From: Michael Br. <mb...@st...> - 2001-02-04 03:25:24
|
i think the following may be interesting... ns5: i found that elm.scrollWidth and elm.scrollHeight in ns5 contain the correct values if elm.style.width/height is set to 'auto', so what i did in Dynlayer.prototype.getContentWidth() is setting the elm.style.width to 'auto', retrive the scrollWidth, and then changing the value of elm.style.width again to the original value. this causes a short flickering, because when set to 'auto', ns5 adjust the size of the layer to the contentSize, but at least i get the correct size of the content. ie5/mac: this browser needs some time to update the scrollWidth/Height-values, so i store the old values of the contentSize and then call a function that loops with a timeout until the values have changed (or a maximum of retries is reached). the 'onload'-event isn't invoked until that moment. this means that everything that needs the size of the content has to wait for the 'onload'-event to be invoked. since the setHTML() method of a DynLayer is the only place where the size of the content can be changed there's no need for accessing the browsers object every time the contentsize is needed, so i introduced two new properties to the DynLayer: contentW and contentH (they are updated every time setHTML() is called) i made a demonstration page available on the web: http://n.ethz.ch/student/mibuerge/dynapi/examples/contentsize.htm the behaviour in any other browsers than mentioned shouldn't have changed. the pieces of code i changed in "dynlayer.js": /* ... */ DynLayer.prototype.toString=function () { return (this.elm)?'DynAPI.getDocument("'+this.dyndoc.id+'").all["'+this.id+'"]':'Dy nLayer.unassigned["'+this.id+'"]'; }; // replaced check for this.created with this.elm /* ... */ DynLayer.prototype.setHTML=function(html,noevt) { this.html=html?html:''; if (this.css==null) return; this.invokeEvent("beforeload"); // saving the actual size of the content if (is.ie5 && is.platform == 'mac') { this.lastContentW = this.contentW || this.getContentWidth(); this.lastContentH = this.contentH || this.getContentHeight(); } this.elm.innerHTML=html; if (is.ns4) { this.doc.open(); this.doc.write(html); this.doc.close(); for (var i in this.doc.images) this.doc.images[i].lyrobj=this; for (i=0;i<this.doc.links.length;i++) this.doc.links[i].lyrobj=this; } else if (is.ns5) { while (this.elm.hasChildNodes()) this.elm.removeChild(this.elm.firstChild); var r=this.elm.ownerDocument.createRange(); r.selectNodeContents(this.elm); r.collapse(true); var df=r.createContextualFragment(html); this.elm.appendChild(df); for (var i in this.doc.images) this.doc.images[i].lyrobj=this.elm; } else { //for (var i in this.elm.all.tags("img")) this.elm.all.tags("img")[i].lyrobj=this; } this.updateContentSizeValues(noevt) }; /* ... */ DynLayer.prototype.getContentWidth=function() { if (this.elm==null) return 0; else if (is.ns4) return this.doc.width; else if (is.ns5) { this.elm.style.width = "auto"; // makes the offsetWidth available var w = this.elm.offsetWidth; this.elm.style.width = this.w; // restore the width return w; } else if (is.ie) return parseInt(this.elm.scrollWidth); else return 0; }; DynLayer.prototype.getContentHeight=function() { if (this.elm==null) return 0; else if (is.ns4) return this.doc.height; else if (is.ns5) { this.elm.style.height = "auto"; var h = this.elm.offsetHeight; this.elm.style.height = this.h; return h; } else if (is.ie) return parseInt(this.elm.scrollHeight); else return 0; }; DynLayer.prototype.updateContentSizeValues = function(noevt) { if (is.ie5 && is.platform == 'mac') { this.chkTimer = setTimeout(this + '.checkForContentSizeUpdate(1,'+!(noevt==false)+')',0); return; } this.contentW = this.getContentWidth(); this.contentH = this.getContentHeight(); if (noevt!=false) this.invokeEvent('load'); } DynLayer.prototype.checkForContentSizeUpdate = function(retry,noevt) { var w = this.getContentWidth(); var h = this.getContentHeight(); // check for changed values if (this.lastContentW != w || this.lastContentH != h) { this.lastContentW = this.lastContentH = null; this.contentW = w; this.contentH = h; if (noevt!=false) this.invokeEvent('load'); } else if (retry < DynLayer.maxRetries) { clearTimeout(this.chkTimer) setTimeout(this +'.check4ContentSizeUpdate(' +(retry+1) +','+!(noevt==false)+')',30); } else if (noevt!=false) this.invokeEvent('load'); } DynLayer.maxRetries = 5; /* ... */ the whole "dynapi.js"-file is included as an attachement. i hope this will lead to some discussion... -- // Michael Buerge |