View Full Version : unhiding 4 divs after check if an image has loaded
I am trying to unhide div1,2,3,4 after image with id=largeImage has loaded.
It is not working. Who can help me out? What am I doing wrong?
The JS
function unhideAllDivs () {
if (!document.getElementById) {return;}
document.getElementById('div1').style.visibility = "visible";
document.getElementById('div2').style.visibility = "visible";
document.getElementById('div3').style.visibility = "visible";
document.getElementById('div4').style.visibility = "visible";
}
The CSS
<style type="text/css">
#div1,#div2,#div3,#div4 {visibility:hidden;}
</style>
The HTML
<img id="largeImage" src="largeIamge.jpg width="732" heigth="460" onload="unhideAllDivs();">
<div id="div1"><img src="1.jpg width="100" heigth="100"></div>
<div id="div2"><img src="2.jpg width="100" heigth="100"></div>
<div id="div3"><img src="3.jpg width="100" heigth="100"></div>
<div id="div4"><img src="4.jpg width="100" heigth="100"></div>
Willy Duitt
07-04-2005, 03:42 AM
Once cached the onload event will not fire again...
Therefore, at best your script will work only the first time...
Harry Armadillo
07-04-2005, 04:53 AM
onload should fire whether cached or not -- it'll just be really soon if the image is cached. And FWIW, when creating image elements dynamically I've found that I need to assign the onload/orerror handlers before assigning a src -- sometimes with cached images the event is done and gone before the next js statement executes.
Anyway, _com's problem lies in a laziness with closing quotes. In the unhide function, div2 is missing its closing quote. In the img tags, every one of the src's is missing its closing quote. Fix that, and things ought work.
Willy Duitt
07-04-2005, 05:11 AM
Harry;
You're wrong... Once the image is cached the onload event will not fire again unless you fool the browsers by appending a querry and the GMT time or any other incrementing number so the browser believes it's another image...
Think about it... Once cached... It's not loading anymore...
Oh... But you're probably right that the missing quote is preventing the O/P's script from running... I was going to suggest that the image was not loading but... That seemed too obvious...
.....Willy
Harry Armadillo
07-04-2005, 05:43 AM
Have you actually tested this concept? If so why, when I load this page fragment, do I get 5 alerts counting up to 5, despite the fact that my firewall indicates there were no outgoing requests (due to the image already being in cache)?<img src='http://www.codingforums.com/images/icons/icon5.gif' onload="window.count=window.count+1||1;alert(window.count);">
<img src='http://www.codingforums.com/images/icons/icon5.gif' onload="window.count=window.count+1||1;alert(window.count);">
<img src='http://www.codingforums.com/images/icons/icon5.gif' onload="window.count=window.count+1||1;alert(window.count);">
<img src='http://www.codingforums.com/images/icons/icon5.gif' onload="window.count=window.count+1||1;alert(window.count);">
<img src='http://www.codingforums.com/images/icons/icon5.gif' onload="window.count=window.count+1||1;alert(window.count);">Loaded into cache is an entirely different thing than loaded into a specific DOM node.
Sorry for the typos should be - that does cause a lot of assumptions of all of you regarding what I might have done wrong here but rest assured in my testpage all syntax was correct though.
The problem I had was a different one.
Some remarks:
I am using HTMl 4.01 strict doctype so I needed to remove the inline event handler from the image - to make it validate in W3C.
So I removed the inline event handler (see HTML)
The JS
function unhideAllDivs () {
if (!document.getElementById) {return;}
document.getElementById('div1').style.visibility = "visible";
document.getElementById('div2').style.visibility = "visible";
document.getElementById('div3').style.visibility = "visible";
document.getElementById('div4').style.visibility = "visible";
}
The HTML - here I put the javascript directly after the <img id="largeImage">
And this works actually just perfect. The <img id="largeImage"> gets loaded first and then the divs are unhidden. And it will validate for W3C.
<img id="largeImage" src="largeImage.jpg width="732" height="460" alt="">
<script type="text/javascript">
document.getElementById('largeImage').onload=function(){
unhideAllDivs ();
}
</script>
<div id="div1" style="visibility:hidden;"><img src="1.jpg" width="100" heigth="100" alt=""></div>
<div id="div2" style="visibility:hidden;"><img src="2.jpg" width="100" heigth="100" alt=""></div>
<div id="div3" style="visibility:hidden;"><img src="3.jpg" width="100" heigth="100" alt=""></div>
<div id="div4" style="visibility:hidden;"><img src="4.jpg" width="100" heigth="100" alt=""></div>
Then (see previous reply) I had another problem.
The unhide javascript stopped working in IE WIN because I moved my code to the real page again where other javascripts are needed too.
I use this dom events library script, needed to make another tooltip script work.
Anyway I tested without these scripts and all worked fine.
With the scripts included eg IEWIN did not execute the unhide the divs javascript in the HTML.
<script type=" text/javascript" src="/js/dom_evt.js"></script>
<script type=" text/javascript" src="/js/tooltip.js"></script>
</head>
I had encountered this problem before.
And using the addEvent(window,'load', function); could help ensure the script getting loaded ...
How can I rewrite this script by using this addEvent? Any ideas
<script type="text/javascript">
function unhideAllDivs () {
if (!document.getElementById) {return;}
document.getElementById('div1').style.visibility = "visible";
document.getElementById('div2').style.visibility = "visible";
document.getElementById('div3').style.visibility = "visible";
document.getElementById('div4').style.visibility = "visible";
}
</script>
<script type="text/javascript">
document.getElementById('largeImage').onload=function(){
unhideAllDivs();
}
</script>
Willy Duitt
07-04-2005, 07:02 PM
Have you actually tested this concept?
Harry;
Not so much tested the concept as opposed to having problems with this in the past... Run the below script, click on an image to open the popup... Close the popup and click on the same image and note the popup will not open again... This is the anomaly I was referring too (in IE anyways)...
<BASE HREF="http://www.xs4all.be/~chadier/webgallery_1/">
<script type="text/javascript">
<!--//
function display(image,name){
var theImage = new Image();
theImage.src = image;
theImage.onerror = function(){
alert('This image has failed to load!');
}
theImage.onload = function(){
var width = theImage.width; if(width <100) { width = 100 };
var height = theImage.height; if(height<100) { height = 100 };
var left = Math.round((screen.width - width) / 2);
var top = Math.round((screen.height - height) / 2);
var features = 'top='+top+',left='+left+',width='+width+',height='+height;
var openWindow = window.open('','display',features);
with(openWindow.document){
writeln('<html><head><title>'+name+'</title></head>');
writeln('<body onload="self.focus()" onblur="self.close()"');
writeln('style="background-image:url('+image+');');
writeln('background-repeat:no-repeat;width:'+width+';height:'+height+'">');
writeln('<div style="position:absolute;bottom:3px;text-align:center">');
writeln('<span style="font-size:12px;width:100%">');
writeln('<a href="javascript:self.close()">Close</a>');
writeln('</span></div></body></html>');
close();
}
}
return false;
}
//-->
</script>
</head>
<body>
<a href="images/17.jpg" name="Classic Table"
onclick="return display(this.href,this.name)">
<img src="thumbnails/17.jpg" width="55" height="70"></a>
<a href="images/18.jpg" name="Wrought Iron Table"
onclick="return display(this.href,this.name)">
<img src="thumbnails/18.jpg" width="55" height="70"></a>
<a href="images/19.jpg" Name="Wrought Iron Sculpture"
onclick="return display(this.href,this.name)">
<img src="thumbnails/19.jpg" width="55" height="70"></a>
_com;
You really should have provided all this latest info from the beginning... Your problem is you are already using multiple onload events... And you already have a script block that creates/attaches an onload event... Try duplicating that or adding your unHide divisions function call within the existing script block... Oh, and please use ...CODE HERE... tags when posting code...
....Willy
_com;
You really should have provided all this latest info from the beginning... Your problem is you are already using multiple onload events... And you already have a script block that creates/attaches an onload event... Try duplicating that or adding your unHide divisions function call within the existing script block... Oh, and please use ...CODE HERE... tags when posting code...
....Willy
I did not provide it because I always first try to make my script work.
The problem I saw with the multiple load events was after.
I will use the for posting any code in the future.
So you suggest to do: Try duplicating that or adding your unHide divisions function call within the existing script block.Can you give an example? Because you obviously know how as I do not have a clue ...
Willy Duitt
07-04-2005, 09:37 PM
Try placing your unHide division function call immediately prior to your closing brace here:
window.attachEvent('onunload', function()
{
// loop through every item in the document collection
// var start = new Date();
for(var i=0,m=document.all.length;i<m;i++) {
// set any event handlers that have been assigned a callback function to null. eg..
document.all[i]['onmouseover'] = null;
document.all[i]['onmouseout'] = null;
document.all[i]['onmousemove'] = null;
document.all[i]['ondragstart'] = null;
document.all[i]['onfocus'] = null;
document.all[i]['onblur'] = null;
}
// var end = new Date();
// var time = end.getTime() - start.getTime();
// alert(i + " DOM nodes cleaned.\nClean up took " + time + "ms.");
if (typeof req == "object") {req = null;}
});
// INSERT HERE
}
EDIT: Ooops... that's the unload event handler...
If you return to your previous post and wrap those codes in [code] tags... I will take another look... As it is, I can barely read that and the bold does not help any...
I find out myself somehow.
close the post if need for ...
Willy Duitt
07-05-2005, 12:17 AM
I find out myself somehow.
close the post if need for ...
The proper thing to do would be to share your solution so others can learn from it... That's what these forums are for... Not just to answer your question...
.....Willy
BTW: I see that not have you NOT wrapped your previous post in code tags as I asked you too... Instead, you returned and removed most of that script without the respect to place what you left within [code] tags... :(
Harry Armadillo
07-05-2005, 05:03 AM
_com, are you sure you want to abondon the thread? We can be a little rough with the criticism (and occasionally seem rude), but we do produce a lot of solutions and functioning code here at Codingforums.
Not so much tested the concept as opposed to having problems with this in the past... :) You've got the same problem there that I mentioned having earlier -- assigning the image's src before the event handlers. If the image is cached, it could be loaded into the new node before you've attached the onload code. No onload event will be apparent, because when the node loaded there was no onload handler.
Just move the line assigning the src to after the onerror and onload lines. :)
Willy Duitt
07-05-2005, 08:53 AM
Harry;
Yes, I have read that where you posted that before... :thumbsup:
My example is somewhat dated but I felt it adequately demonstrated what I was referring too...
As for _com... I do not think he so much abondoned the thread as he found a solution elsewhere and moved on... I for one was hoping he would share the solution... Guess not...
Thanks for your help and insight;
.....Willy
Harry Armadillo
07-05-2005, 10:13 AM
If he'd posted elsewhere (solution or not), you'd have found it and posted a link to the other thread. ;)
I only got the briefest glimpse of the addition code before it was removed. Some of the DOM prototyping looked interesting -- shame it's gone.
Hope there is anyone who can help me out so that
this unhide function will work ...
As I mentioned before I have some other javascripts they work perfect but the problem is that I put the last javascript after the <img> in the HTML and hence the onload event does not work properly. Maybe someone can have a look at a testpage.
/* This library contains commonly used scripts for DOM Manipulation */
// DOM library, courtesy Author: Tom Wright <tomwright.me.uk>
//Copyright (c): 2003-2004 Tom Wright, all rights reserved
// --------------------------
// -- Debugging routines ----
// --------------------------
function debug(obj) {
var str,
holder = document.getElementsByTagName("body").item(0),
container = document.createElement("pre"),
styles = {"textAlign":"left",
"background":"#fff",
"border":"1px solid #333",
"padding":"2%",
"width":"80%",
"overflow":"auto",
"margin":"1em auto"};
for (i in obj) { str += i + ":" + obj[i] + "\n\r"; }
if (holder == null) { alert(str); }
else {
container.appendChild(document.createTextNode(str));
defineCSS(container, styles);
holder.appendChild(container);
}
}
function
report_errors(e) {
debug(e);
}
// --------------------------
// ------- DIY Legacy -------
// --------------------------
var undefined;
if (typeof Function.prototype.call == undefined) {
Function.prototype.call = function(obj, param) {
obj.base = this;
obj.base(param);
}
}
// ----------------------------
// -- Prototype enhancements --
// ----------------------------
Function.prototype.Iterate = function(collection) {
if (typeof TreeWalker != "undefined" && collection instanceof TreeWalker) {
while((elem = collection.nextNode()) != null) {
this(elem);
}
}
else {
// note use the collection index rather than item() method
// since IE will pass a standard array if getSet has been
// used to build the collection
for (var i = 0, elem; elem = collection[i]; i++ ) {
this(elem, i);
}
}
}
Array.prototype.search = function(str) {
var re;
for (var i = 0, m = this.length; i < m; i++) {
re = new RegExp('^' + str + '$', 'i');
if (re.test(this[i])) {
return true;
}
}
return false;
}
// ---------------------------
// -- Standard DOM Routines --
// ---------------------------
if (typeof Node == "undefined") {
// set some node constants for IE.
var Node = {};
Node.ELEMENT_NODE =1;
Node.ATTRIBUTE_NODE =2;
Node.TEXT_NODE =3;
Node.CDATA_SECTION_NODE =4;
Node.ENTITY_REFERENCE_NODE =5;
Node.ENTITY_NODE =6;
Node.PROCESSING_INSTRUCTION_NODE =7;
Node.COMMENT_NODE =8;
Node.DOCUMENT_NODE =9;
Node.DOCUMENT_TYPE_NODE =10;
Node.DOCUMENT_FRAGMENT_NODE =11;
Node.NOTATION_NODE =12;
}
// replacement func for referencing an element in the DOM tree
function ref(id) {
if (document.getElementById) {
var elem = document.getElementById(id);
return (elem) ? elem : undefined;
}
return undefined;
}
// replacement func for creating an element
function create(t, nodeType) {
if (nodeType == undefined) {
return document.createElement(t);
}
else {
switch(nodeType) {
case Node.TEXT_NODE:
return document.createTextNode(t)
break;
default:
return document.createElement(t);
break;
}
}
}
// get a reference to an HTMLCollection or HTMLElement within a collection
// eg
// * col('table') will return a collection of all table elements
// * col('table', 1) will return the second table in table's collection
// * col('input', 0, 'form_id') will return the first input field in the form with ID form_id
// * col('input', 0, col('form', 0)) will return then first input field in the first form
function col(tag, idx, parent) {
var c;
if (document.getElementsByTagName) {
if (parent != undefined) {
c = (typeof parent == "string") ?
ref(parent).getElementsByTagName(tag) : parent.getElementsByTagName(tag);
}
else {
c = document.getElementsByTagName(tag);
}
}
return (c.length == 0) ? undefined : ((idx != undefined && idx != -1) ? c[idx] : c);
}
// compressed method for navigating through the dom tree, similar to get but based
// on properties (ie prototyping).
// get('form')(0).get('input')(0) would get the first input in first form
//
// this method depends on assignToDOM to work in IE and is setup by calling __initDOMCrawler
var get = function(tag) {
var self = (this.nodeName != undefined) ?
this : // this instanceof Node
document; // this instanceof Window
return function(idx) {
if (tag instanceof Array) {
return getSet(tag, self);
}
else {
return (idx == undefined) ?
self.getElementsByTagName(tag) :
self.getElementsByTagName(tag).item(idx);
}
}
}
function getSet(tags, root) {
if (document.createTreeWalker) {
// Keep out IE unless we build an IE TreeWalker object!!
root = (root == undefined) ? document : root;
var set = document.createTreeWalker(root,
NodeFilter.SHOW_ELEMENT,
{
acceptNode : function(n) {
return (tags.search(n.tagName)) ?
NodeFilter.FILTER_ACCEPT :
NodeFilter.FILTER_SKIP;
}
},
false);
}
else {
var set = [];
try {
for(var i = 0, m = tags.length; i < m; i++) {
// cannot call get on document so check for root parameter
// and if it does not exist call get globally
if (root == document || root == undefined) {
(function(elem){set[set.length]=elem;}).Iterate(get(tags[i])());
}
else {
(function(elem){set[set.length]=elem;}).Iterate(root.get(tags[i])());
}
}
} catch(e) {alert("Error thrown in getSet()");report_errors(e);}
}
return set;
}
function assignToDOM(fn, fn_name, obj) {
var elem;
if (obj.childNodes && obj.childNodes.length > 0) {
elem = obj.firstChild;
do {
if (elem.nodeType == Node.ELEMENT_NODE) {
elem[fn_name] = fn;
assignToDOM(fn, fn_name, elem);
}
} while (elem = elem.nextSibling);
}
}
function __initDOMCrawler() {
if (typeof HTMLElement != "undefined") { HTMLElement.prototype.get = get; }
else { assignToDOM(get, 'get', get('body')(0)); }
}
// assign a group of styles to a DOM node where the styles are
// stores as an object {property_1:value_1, .. , property_n:value_n}
function defineCSS(obj, styles) {
if (styles instanceof Object) {
for (var prop in styles) {
obj.style[prop] = styles[prop];
}
}
}
// calculate the computed style for a element
function getStyle(elem, ieStyle, cssStyle) {
if (elem.currentStyle) {
return elem.currentStyle[ieStyle];
}
else if (window.getComputedStyle) {
var comp = window.getComputedStyle(elem, "");
return comp.getPropertyValue(cssStyle);
}
return "";
}
// recursively iterate through the DOM tree building
// output in global variable <str >
var str = "", TAB = " ";
function walkDOM(obj, tabs) {
var elem;
if (tabs == undefined) { tabs = ""; }
if (obj.childNodes && obj.childNodes.length > 0) {
elem = obj.firstChild;
do {
str += (tabs + elem.nodeName + ":" + elem.nodeType + "\n\r");
walkDOM(elem, tabs + TAB);
} while (elem = elem.nextSibling);
}
}
// -----------------------------
// -- Standard DHTML Routines --
// -----------------------------
function getInsideWidth(){if(window.innerWidth){return window.innerWidth;}else if(document.documentElement.clientWidth&&document.documentElement.clientWidth!=0){return document.documentElement.clientWidth;}else if(document.body&&document.body.clientWidth){return document.body.clientWidth;}else{return 0;}}
function getInsideHeight(){if(window.innerHeight){return window.innerHeight;}else if(document.documentElement.clientHeight&&document.documentElement.clientWidth!=0){return document.documentElement.clientHeight;}else if(document.body&&document.body.clientWidth){return document.body.clientHeight;}else{return 0;}}
function getPosObj(elem){var coords={x:0,y:0};do{coords.x+=elem.offsetLeft;coords.y += elem.offsetTop;elem=elem.offsetParent;}while(elem.offsetParent);coords.x=parseInt(coords.x);coords.y =parseInt(coords.y);return coords;}
function getPosEvtScr(e){var coords={x:0,y:0};if(e.pageX){coords.x=e.pageX;coords.y=e.pageY;}else if(e.clientX){var b=get('body')(0);coords.x=e.clientX+b.scrollLeft-b.clientLeft;coords.y=e.clientY+b.scrollTop-b.clientTop;if(b.parentElement&&b.parentElement.clientLeft){p=b.parentElement;coords.x+=p.scrollLeft-p.clientLeft;coords.y+=p.scrollTop-p.clientTop;}}coords.x=parseInt(coords.x);coords.y=parseInt(coords.y);return coords;}
function getPosEvtObj(e,elem){var coords={x:0,y:0},pScr=getPosEvtScr(e),pElem=getPosObj(elem);coords.x=parseInt(pScr.x-pElem.x);coords.y=parseInt(pScr.y-pElem.y);return coords;}
function getObjSize(elem){var size={w:0,h:0};size.h=parseInt(elem.offsetHeight);size.w=parseInt(elem.offsetWidth);return size;}
// ----------------------------
// ------ Event Handling ------
// ----------------------------
/**
* @abstract
*/
function EventListener(elem) {
this.elem = elem;
this.evt = "";
this.invoke = function(evt) {
this.evt = (evt) ? evt :
((window.event) ? window.event : null);
}
this.cancelDefault = function() {
if (this.evt) {
if (this.evt.preventDefault) {
this.evt.preventDefault();
}
this.evt.returnValue = false;
}
}
this.register = function(handler,fn) {
if (handler instanceof Array) {
for(var i=0;i<handler.length; i++) {
addEvent(this.elem,handler[i],fn);
}
}
else { addEvent(this.elem,handler,fn); }
}
this.unregister = function(handler, fn) {
if (handler instanceof Array) {
for (var i = 0; i < handler.length; i++) {
removeEvent(this.elem, handler[i], fn);
}
}
else { removeEvent(this.elem, handler, fn); }
}
}
function getTarget(evt){if(!evt)var evt=window.event;if(evt){var elem=(evt.target)?evt.target:((evt.srcElement)?evt.srcElement:null);while(elem.nodeType==Node.TEXT_C ONTENT){elem=elem.parentNode;}return elem;}}
function cancelPropogation(evt)
{
if (!evt) var evt = window.event;
evt.cancelBubble = true; /* ie */
if (evt.stopPropagation) {
evt.stopPropagation();
}
}
function cancelDefault(evt){if(evt){if(evt.preventDefault){evt.preventDefault();}evt.returnValue=false;}}
function addLoadEvent(func){if(document.getElementById&&document.createTextNode){var oldonload=window.onload;if(typeof window.onload!='function'){window.onload=func;}else{window.onload=function(){oldonload();func();}}}}
function addEvent(obj,evType,fn,useC){if(obj.addEventListener){obj.addEventListener(evType,fn,useC);return true;}else if(obj.attachEvent){var r=obj.attachEvent("on"+evType,fn);return r;}else{alert("Browser does not support event attachment");}}
function removeEvent(obj,evType,fn,useC){if(obj.removeEventListener){obj.removeEventListener(evType,fn,useC); return true;}else if(obj.detachEvent){var r=obj.detachEvent("on"+evType,fn);return r;}else{alert("Browser does not support event detachment");}}
addLoadEvent(function() { __initDOMCrawler(); });
//avoid memory leaks in IE
if(typeof window.attachEvent != 'undefined')
{
window.attachEvent('onunload', function()
{
// loop through every item in the document collection
// var start = new Date();
for(var i=0,m=document.all.length;i<m;i++) {
// set any event handlers that have been assigned a callback function to null. eg..
document.all[i]['onmouseover'] = null;
document.all[i]['onmouseout'] = null;
document.all[i]['onmousemove'] = null;
document.all[i]['ondragstart'] = null;
document.all[i]['onfocus'] = null;
document.all[i]['onblur'] = null;
}
// var end = new Date();
// var time = end.getTime() - start.getTime();
// alert(i + " DOM nodes cleaned.\nClean up took " + time + "ms.");
if (typeof req == "object") {req = null;}
});
}
PS if wanna use this code let the author know.
This in the head
<script type="text/javascript">
function unhideSmallDivs() {
if (!document.getElementById) {return;}
document.getElementById('div1').style.visibility = "visible";
document.getElementById('div2').style.visibility = "visible";
document.getElementById('div3').style.visibility = "visible";
document.getElementById('div4').style.visibility = "visible";
}
</script>
In the body
<div id="wrapperlargeImage" style="z-index:1;">
<img id="largeImage" src="largeImage" width="732" height="460" alt="">
</div>
<script type="text/javascript">
// put directly after the referenced image tag
// ugly but it works now in IE WIN too
// credits go to brothercake
// <http://www.codingforums.com/showthread.php?t=56369>
// but somehow document.getElementsByTagName is used here to check the // DOM ??
function domReady(){this.n=typeof this.n=='undefined'?0:this.n+1;
if(typeof document.getElementsByTagName!='undefined'&&(document.getElementsByTagName('body')[0]!=null||document.body!=null))
{
document.getElementById('largeImage').onload=unhideSmallDivs;
}
else if(this.n<60){setTimeout('domReady()',250);}};domReady();
</script>
Harry Armadillo
07-06-2005, 08:33 AM
Some interest stuff in that DOM manipulation code (and some that strikes me as silly), but I didn't see anything that would interfere with the image-onload function.
I'm glad to see that Brothercake's DOM routines got it going, though I think it possible that the 250ms timeout for trying again could lead to occasional loss of the onload (where the event occurs in the interval before the handler is attached).
If you have a 'live' test page, I'd still like to play with it to see what was (and wasn't) happening. If not, cool that it's working for you now.
The most recent version of the DOM manipulation script:
/**
* dom_evt.js
* Library of experimental and implemented functions and objects for
* DOM manipulation. Some of this code is *very* experimental and has
* only been tested across a small number of browsers.
* Use freely but at your own risk! ;))
*
* @author Tom Wright <tomwright.me.uk>
* @last update 01/04/05 00:27
*
* EventManager object based on EventManager.js by Keith Gaughan
* Visit http://talideon.com/weblog/2005/03/js-memory-leaks.cfm
* for licensing and latest updates.
*/
// --------------------------
// -- Debugging routines ----
// --------------------------
function debug(obj) {
var str,
holder = document.getElementsByTagName("body").item(0),
container = document.createElement("pre"),
styles = {"textAlign":"left",
"background":"#fff",
"border":"1px solid #333",
"padding":"2%",
"width":"80%",
"overflow":"auto",
"margin":"1em auto"};
for (i in obj) { str += i + ":" + obj[i] + "\n\r"; }
if (holder === null) { alert(str); }
else {
container.appendChild(document.createTextNode(str));
defineCSS(container, styles);
holder.appendChild(container);
}
}
function report_errors(e) {
debug(e);
}
// --------------------------
// ------- DIY Legacy -------
// --------------------------
/* Strictly illegal reserved word - but temp soln for IE */
//var undefined; // for IE5.0x
if (typeof Function.prototype.call === String(undefined)) {
Function.prototype.call = function(obj, param) {
obj.base = this;
obj.base(param);
};
}
if (typeof Array.prototype.push === String(undefined)) {
Array.prototype.push = function(elem) {
this[this.length] = elem;
};
}
// ----------------------------
// -- Prototype enhancements --
// ----------------------------
Function.prototype.Iterate = function(collection) {
var elem;
if (typeof TreeWalker !== String(undefined) && collection instanceof TreeWalker) {
while((elem = collection.nextNode()) !== null) {
this(elem);
}
}
else {
// note use the collection index rather than item() method
// since IE will pass a standard array if getSet has been
// used to build the collection
for (var i = 0; (elem = collection[i]); i+=1 ) {
this(elem, i);
}
}
};
Array.prototype.search = function(str) {
var re;
for (var i = 0, m = this.length; i < m; i+=1) {
re = new RegExp('^' + str + '$', 'i');
if (re.test(this[i])) {
return true;
}
}
return false;
};
// ---------------------------
// -- Standard DOM Routines --
// ---------------------------
if (typeof Node === String(undefined)) {
// set some node constants for IE.
var Node = {};
Node.ELEMENT_NODE =1;
Node.ATTRIBUTE_NODE =2;
Node.TEXT_NODE =3;
Node.CDATA_SECTION_NODE =4;
Node.ENTITY_REFERENCE_NODE =5;
Node.ENTITY_NODE =6;
Node.PROCESSING_INSTRUCTION_NODE =7;
Node.COMMENT_NODE =8;
Node.DOCUMENT_NODE =9;
Node.DOCUMENT_TYPE_NODE =10;
Node.DOCUMENT_FRAGMENT_NODE =11;
Node.NOTATION_NODE =12;
}
// replacement func for referencing an element in the DOM tree
function ref(id) {
if (document.getElementById) {
var elem = document.getElementById(id);
return (elem) ? elem : undefined;
}
return undefined;
}
// replacement func for creating an element
// this is far from complete!!!
function create(t, nodeType) {
if (nodeType === undefined) {
return document.createElement(t);
}
else {
switch(nodeType) {
case Node.TEXT_NODE:
return document.createTextNode(t);
default:
return document.createElement(t);
}
}
// failure
return null;
}
// get a reference to an HTMLCollection or HTMLElement within a collection
// eg
// * col('table') will return a collection of all table elements
// * col('table', 1) will return the second table in table's collection
// * col('input', 0, 'form_id') will return the first input field in the form with ID form_id
// * col('input', 0, col('form', 0)) will return then first input field in the first form
function col(tag, idx, parent) {
var c;
if (document.getElementsByTagName) {
if (parent !== undefined) {
c = (typeof parent == "string") ?
ref(parent).getElementsByTagName(tag) : parent.getElementsByTagName(tag);
}
else {
c = document.getElementsByTagName(tag);
}
}
return (c.length === 0) ? undefined : ((idx !== undefined && idx != -1) ? c[idx] : c);
}
// compressed method for navigating through the dom tree, similar to get but based
// on properties (ie prototyping).
// get('form')(0).get('input')(0) would get the first input in first form
//
// this method depends on assignToDOM to work in IE and is setup by calling __initDOMCrawler
var get = function(tag) {
var self = (this.nodeName !== undefined) ?
this : // this instanceof Node
document; // this instanceof Window
return function(idx) {
if (tag instanceof Array) {
return getSet(tag, self);
}
else {
return (idx === undefined) ?
self.getElementsByTagName(tag) :
self.getElementsByTagName(tag).item(idx);
}
};
};
function getSet(tags, root) {
var set = null;
if (document.createTreeWalker) {
// Keep out IE unless we build an IE TreeWalker object!!
root = (root === undefined) ? document : root;
set = document.createTreeWalker(root,
NodeFilter.SHOW_ELEMENT,
{
acceptNode : function(n) {
return (tags.search(n.tagName)) ?
NodeFilter.FILTER_ACCEPT :
NodeFilter.FILTER_SKIP;
}
},
false);
}
else {
set = [];
try {
for(var i = 0, m = tags.length; i < m; i+=1) {
// cannot call get on document so check for root parameter
// and if it does not exist call get globally
if (root == document || root === undefined) {
(function(elem){set[set.length]=elem;}).Iterate(get(tags[i])());
}
else {
(function(elem){set[set.length]=elem;}).Iterate(root.get(tags[i])());
}
}
} catch(e) {alert("Error thrown in getSet()");report_errors(e);}
}
return set;
}
function assignToDOM(fn, fn_name, obj) {
var elem;
if (obj.childNodes && obj.childNodes.length > 0) {
elem = obj.firstChild;
do {
if (elem.nodeType == Node.ELEMENT_NODE) {
elem[fn_name] = fn;
assignToDOM(fn, fn_name, elem);
}
} while (( elem = elem.nextSibling ));
}
}
function __initDOMCrawler() {
if (typeof HTMLElement !== String(undefined)) { HTMLElement.prototype.get = get; }
else { assignToDOM(get, 'get', get('body')(0)); }
}
// assign a group of styles to a DOM node where the styles are
// stores as an object {property_1:value_1, .. , property_n:value_n}
function defineCSS(obj, styles) {
if (styles instanceof Object) {
for (var prop in styles) {
obj.style[prop] = styles[prop];
}
}
}
// calculate the computed style for a element
function getStyle(elem, ieStyle, cssStyle) {
if (elem.currentStyle) {
return elem.currentStyle[ieStyle];
}
else if (window.getComputedStyle) {
var comp = window.getComputedStyle(elem, "");
return comp.getPropertyValue(cssStyle);
}
return "";
}
// recursively iterate through the DOM tree building
// output in global variable <str>
var str = "", TAB = " ";
function walkDOM(obj, tabs) {
var elem;
if (tabs === undefined) { tabs = ""; }
if (obj.childNodes && obj.childNodes.length > 0) {
elem = obj.firstChild;
do {
str += (tabs + elem.nodeName + ":" + elem.nodeType + "\n\r");
walkDOM(elem, tabs + TAB);
} while (( elem = elem.nextSibling ));
}
}
// -----------------------------
// -- Standard DHTML Routines --
// -----------------------------
function getInsideWidth(){if(window.innerWidth){return window.innerWidth;}else if(document.documentElement.clientWidth&&document.documentElement.clientWidth!==0){return document.documentElement.clientWidth;}else if(document.body&&document.body.clientWidth){return document.body.clientWidth;}else{return 0;}}
function getInsideHeight(){if(window.innerHeight){return window.innerHeight;}else if(document.documentElement.clientHeight&&document.documentElement.clientWidth!==0){return document.documentElement.clientHeight;}else if(document.body&&document.body.clientWidth){return document.body.clientHeight;}else{return 0;}}
//function getPosObj(elem){var coords={x:0,y:0};if(elem.offsetParent){while(elem.offsetParent){coords.x+=elem.offsetLeft;coords.y += elem.offsetTop;elem=elem.offsetParent;}}coords.x=parseInt(coords.x);coords.y=parseInt(coords.y);retu rn coords;}
function getPosObj(elem){var coords={x:0,y:0};do{coords.x+=elem.offsetLeft;coords.y += elem.offsetTop;elem=elem.offsetParent;}while(elem.offsetParent);coords.x=parseInt(coords.x);coords.y =parseInt(coords.y);return coords;}
function getPosEvtScr(e){var coords={x:0,y:0};if(e.pageX){coords.x=e.pageX;coords.y=e.pageY;}else if(e.clientX){var b=get('body')(0);coords.x=e.clientX+b.scrollLeft-b.clientLeft;coords.y=e.clientY+b.scrollTop-b.clientTop;if(b.parentElement&&b.parentElement.clientLeft){p=b.parentElement;coords.x+=p.scrollLeft-p.clientLeft;coords.y+=p.scrollTop-p.clientTop;}}coords.x=parseInt(coords.x);coords.y=parseInt(coords.y);return coords;}
function getPosEvtObj(e,elem){var coords={x:0,y:0},pScr=getPosEvtScr(e),pElem=getPosObj(elem);coords.x=parseInt(pScr.x-pElem.x);coords.y=parseInt(pScr.y-pElem.y);return coords;}
function getObjSize(elem){var size={w:0,h:0};size.h=parseInt(elem.offsetHeight);size.w=parseInt(elem.offsetWidth);return size;}
// ------------------------------
// ------ Event Management ------
// ------------------------------
/**
* @updated 31/03/05 23:45
*
* Temporary resolution to memory leakage issues in IE particular and possibly Firefox
* Implemented new EventManager class.
* This is based on Keith Gaughan's class @ http://talideon.com/weblog/2005/03/js-memory-leaks.cfm
* Extended the code to ensure capture is not ignored with restricted default false value
* ::TODO:: replace the with block - performance ?
*/
var EventManager =
{
_registry: null,
Initialise: function() {
if (this._registry === null) {
this._registry = [];
EventManager.Add(window, 'unload', this.CleanUp);
}
},
Add: function(obj, type, fn, capture) {
this.Initialise();
// Not needed since addEventListener will default the capture
// parameter value to false if it is undefined
capture = Boolean(capture);
// If a string was passed assume working with an ID value
if (typeof obj == "string") {
obj = ref(obj);
}
if (obj === undefined || fn === undefined) {
return false;
}
// W3C DOM Event Listeners
if (obj.addEventListener) {
obj.addEventListener(type, fn, capture);
this._registry.push({obj:obj, type:type, fn:fn, capture:capture});
return true;
}
// IE Proprietary DOM Event Listeners
else if (obj.attachEvent && obj.attachEvent("on" + type, fn)) {
this._registry.push({obj:obj, type:type, fn:fn});
return true;
}
return false;
},
CleanUp: function() {
for (var i = EventManager._registry.length - 1; i >= 0; i-=1) {
with (EventManager._registry[i]) {
if (obj.removeEventListener) {
obj.removeEventListener(type, fn, Boolean(capture));
}
else if (obj.detachEvent) {
obj.detachEvent("on" + type, fn);
}
}
}
// kill the registry itself to remove last remaining references
EventManager._registry = null;
}
};
// ----------------------------
// ------ Event Listener ------
// ----------------------------
/**
* Acts as a wrapper for some of the common event handling methods
*
* @udpate 31/03/05 23:54
* Use the EventManager object to handle memory leakages
*/
/**
* @abstract
*/
function EventListener(elem) {
this.elem = elem;
this.evt = "";
this.invoke = function(evt) {
this.evt = (evt) ? evt :
((window.event) ? window.event : null);
};
this.cancelDefault = function() {
if (this.evt) {
if (this.evt.preventDefault) {
this.evt.preventDefault();
}
this.evt.returnValue = false;
}
};
this.register = function(handler,fn) {
if (handler instanceof Array) {
for(var i=0;i<handler.length; i+=1) {
EventManager.Add(this.elem,handler[i],fn);
}
}
else { EventManager.Add(this.elem,handler,fn); }
};
// ::TODO:: map a remove method to the EventManager object
// this.unregister = function(handler, fn) {
// if (handler instanceof Array) {
// for (var i = 0; i < handler.length; i+=1) {
// removeEvent(this.elem, handler[i], fn);
// }
// }
// else { removeEvent(this.elem, handler, fn); }
// };
}
// Just some other event handling routines in global space
function getTarget(evt){if(!evt)evt=window.event;if(evt){var elem=(evt.target)?evt.target:((evt.srcElement)?evt.srcElement:null);while(elem.nodeType==Node.TEXT_C ONTENT){elem=elem.parentNode;}return elem;}}
function cancelPropogation(evt)
{
if (!evt) evt = window.event;
evt.cancelBubble = true; /* ie */
if (evt.stopPropagation) {
evt.stopPropagation();
}
}
function cancelDefault(evt){if(evt){if(evt.preventDefault){evt.preventDefault();}evt.returnValue=false;}}
function addLoadEvent(func){if(document.getElementById&&document.createTextNode){var oldonload=window.onload;if(typeof window.onload!='function'){window.onload=func;}else{window.onload=function(){oldonload();func();}}}}
function addEvent(obj,evType,fn,useC){if(obj.addEventListener){obj.addEventListener(evType,fn,useC);return true;}else if(obj.attachEvent){var r=obj.attachEvent("on"+evType,fn);return r;}else{alert("Browser does not support event attachment");return null}}
function removeEvent(obj,evType,fn,useC){if(obj.removeEventListener){obj.removeEventListener(evType,fn,useC); return true;}else if(obj.detachEvent){var r=obj.detachEvent("on"+evType,fn);return r;}else{alert("Browser does not support event detachment");return null}}
EventManager.Add(window, 'load', function() { __initDOMCrawler(); });
// Defunct - Implementing EventManager instead
// clean up routine for WinIE to avoid memory leaks
// this can take around 0.6s for 500+ DOM nodes!
//if(typeof window.attachEvent != 'undefined')
//{
// window.attachEvent('onunload', function()
// {
// // loop through every item in the document collection
// // var start = new Date();
// for(var i=0,m=document.all.length;i<m;i++) {
// document.all[i]['onmouseover'] = null;
// document.all[i]['onmouseout'] = null;
// document.all[i]['onmousemove'] = null;
// document.all[i]['onfocus'] = null;
// document.all[i]['onblur'] = null;
// document.all[i]['onclick'] = null;
// }
// // var end = new Date();
// // var time = end.getTime() - start.getTime();
// // alert(i + " DOM nodes cleaned.\nClean up took " + time + "ms.");
// if (typeof req == "object") {req = null;}
// });
//}
I still think what I did is too complex and you mentioned possible errors may occur with using this brothercake DOM script
A testpage removed ... saves bandwidth
It works but maybe it can be simplified.
Note the navigation is hidden and onmouseover it appears
when creating image elements dynamically I've found that I need to assign the onload/orerror handlers before assigning a src -- sometimes with cached images the event is done and gone before the next js statement executes.
any code example to illustrate this:
Harry Armadillo
07-08-2005, 07:22 AM
Willy's pop-up viewer code is a good example of it, especially if you substitute local images (to simulate cached images that aren't even verified by eTag or modified date). Have the src assignment before or after the onload/onerror.
tinyurl seems to be blocked somewhere between me and world at large, so I couldn't check your example. :(
it works just fine here, extra DOM parse check script not needed
vBulletin® v3.8.2, Copyright ©2000-2012, Jelsoft Enterprises Ltd.