1 (Page 1 of 1)
window.onload 的问题

随着ajax的流行,页面中的JS代码越来越多。一般我们用JS处理页面时,都是使用window.onload等到页面加载完毕后再来处理,否则有时会出现文档未加载完毕而报的错误了。

但window.onload有一个不好的地方,它会等到整个页面(包括图片,flash等)全部加载完毕后,才会执行。一个页面中如果有很多图片,中间会有较长的延迟才会去执行我们的代码。

具体效果:http://www.ajaxeye.com/labs/domready.htm(注意页面中的两个小方块颜色,一开始默认都是红色,注意颜色的改变)

上面页面中,会在DOM树加载完毕后window.onload时分别改变两个小方块的颜色为绿色。

解决方法可以参见英文原文:
http://dean.edwards.name/weblog/2005/09/busted/
http://dean.edwards.name/weblog/2006/06/again/

解决方法就是想办法监听DOM树加载完毕的事件,等DOM树载完毕后执行我们的代码

  • Firefox、Opera9下,可以监听DOMContentLoaded事件来处理
  • IE下,可以给script标签加defer来处理

偶这个是从mootools,prototype中抠出来的IE,Firefox下测试通过

  1. Event.addDOMReadyEvent = function($callback) {   
  2.     var timer, fired = false;   
  3.        
  4.     function fireDOMReadyEvent() {   
  5.         if (fired) {   
  6.             return;   
  7.         }   
  8.         if (timer) {   
  9.             window.clearInterval(timer);   
  10.         }   
  11.         fired = true;   
  12.         $callback();   
  13.     }   
  14.        
  15.     // firefox, opera, safari ...    
  16.     if (document.addEventListener) {   
  17.         if (window.webkit) {   
  18.             timer = window.setInterval(function() {   
  19.                 if (/loaded|complete/.test(document.readyState)) {   
  20.                     fireDOMReadyEvent();   
  21.                 }   
  22.             }, 10);   
  23.                
  24.             Event.addEvent(window, 'load', fireDOMReadyEvent);   
  25.         } else {   
  26.             // firefox, opera9 使用 DOMContentLoaded   
  27.             document.addEventListener("DOMContentLoaded", fireDOMReadyEvent, false);   
  28.         }   
  29.     } else {   
  30.         // Internet Explorer中使用 defer 属性   
  31.         var src = (window.location.protocol == 'https') ? '://0' : 'javascript:void(0)';   
  32.         document.write('<SCRIPT id=__tbOnDOMReady src="' + src + '" defer><\/script>');   
  33.         $('__tbOnDOMReady').onreadystatechange = function() {   
  34.             if (this.readyState == 'complete') {   
  35.                 this.onreadystatechange = null;   
  36.                 fireDOMReadyEvent();   
  37.             }   
  38.         };   
  39.     }   
  40. }  
innerText在firefox下的区别

IE/OPERA下元素有innerText这个方法用来剔除dom下的html标签,快速的取得文本内容。
Firefox下没有这个属性,可以用DOM Level3的textContent来代替。

  1. <DIV id=target><SPAN>hello </SPAN>world</DIV>   
  2. <SCRIPT type=text/javascript>   
  3.     var dom = document.getElementById("target");   
  4.     if (dom.innerText) {   
  5.         alert("innerText: " + dom.innerText);   
  6.     } else {   
  7.         alert("textContent: " + dom.textContent);   
  8.     }   
  9. </SCRIPT>  
html dom设置自定义需用setAttribute引起的问题

有文章说html dom中设置自定义属性时,需要使用setAttribute来设置.
但在某些情况下,不能全使用setAttribute来设置值
比如:

// 设置自定义属性
element.setAttribute("attribute.name", "attribute.value");
// 取得自定义属性
var value = element.setAttribute("attribute.name", "attribute.value");
alert(value);

在setAttribute属性值为字符串时,IE6,Firefox2,opera9下都工作正常.
而setAttribute当属性值为对象时,用上面的方法,只有IE下能工作正常.
比如:

// 设置自定义属性
element.setAttribute("attribute.name", object);
// 取得自定义属性
var obj = element.getAttribute("attribute.name");
// IE下返回的类型是object,而Firefox,opera下返回的类型却是string
alert(typeof obj);

解决的办法可以在设置自定义属性时,像设置内置属性一样操作

// 设置自定义属性
element.attribute = object;
// 取得自定义属性
var obj = element.getAttribute("attribute");
// 这样IE,Firefox,opera下都工作正常了
alert(typeof obj);

 

IE和Firefox下textarea操作方法及取消事件冒泡

之前的留言回复使用tiny_mec做所见即所得编辑器,速度感觉太慢了,于是自己想写个简单的UBB编辑器玩玩,碰到一些问题记这里:

IE和Firefox下取消事件冒泡

  1. function showEmot() {   
  2.     var evt =  || event;   
  3.     if(evt.preventDefault) {   
  4.         // Firefox   
  5.         evt.preventDefault();   
  6.         evt.stopPropagation();   
  7.     } else {   
  8.         // IE   
  9.         evt.cancelBubble=true;   
  10.         evt.returnValue = false;   
  11.     }   
  12. }  

textarea下将一段内容替换鼠标所选文字或插入到当前光标位置

  1. function append() {   
  2.     // sEditorId textarea的ID   
  3.     var eObj = document.getElementById(sEditorId);   
  4.     // ie   
  5.     if (eObj.createTextRange) {   
  6.         eObj.focus();   
  7.         document.selection.createRange().duplicate().text = ;   
  8.     } else {   
  9.         // firefox   
  10.         var iStart = eObj.selectionStart;   
  11.         var iEnd = eObj.selectionEnd;   
  12.         eObj.value = eObj.value.substr(0, iStart) +  + eObj.value.substr(iEnd, eObj.value.length);   
  13.         eObj.focus();   
  14.     }   
  15. }  
firefox中处理字符串形式的xml数据
字符串形式的xml数据(和html合在一起),在IE和FF下都可以用一般的dom标签定位到过去取值。
但在FF中有一个BUG,假如值有时,取出来的值会是:[CDATA[数据]]。
  1. <XMP id=target>     
  2.     <root><node><![CDATA[数据]]></node></root>     
  3. </XMP>    
  1. function getXmlFromString($str) {   
  2.     // 简单用这种方法判断一下是否是IE   
  3.     if (document.all) {   
  4.         var xmlDom = new ActiveXObject("Microsoft.XMLDOM");   
  5.         xmlDom.loadXML($str);   
  6.         return xmlDom;   
  7.     } else {   
  8.         return new DOMParser().parseFromString($str, "text/xml");   
  9.     }   
  10. }   
  11.   
  12. // 此时就可以用像处理xml一样的方法取值了   
  13. var doc = getXmlFromString(document.getElementById("target").innerHTML);   
  14. alert(doc.childNodes[0].childNodes[0].childNodes[0].nodeValue);  
corss browser (last update: 2006-12-29)

这里说的跨浏览器主要指的是IE及Firefox

首先推荐使用或阅读Prototype.js,其中解决了很多IE及firefox下的兼容问题。

然后就是“Javascript的IE和Firefox兼容性汇编”这篇文章。

这里主要记录是一些本人碰到,而上面又没有涉及的问题

  • IE中iframe的onreadystatechange方法,在firefox下没有这个方法,可以用onload来代替。
  1. if (typeof(domFrame.onreadystatechange) != "undefined") {      
  2.     // ie      
  3.     domFrame.onreadystatechange = notify;      
  4. else {      
  5.     // firefox      
  6.     domFrame.onload = notify;      
  7. }      
  8.      
  9. function notify() {      
  10.     alert('iframe内容装载完成');      
  11. }    
  • firefox下在iframe中的页面内嵌在别的页面中,onload后,取不到clientHeight,clientWidth这些值

像上面那个例子,假如在B页面中写onload事件回调方法,在方法中取clientHeight,clientWidth返回值将不正确。
解决方法可以在A页面中来取值或设置

  1. // A页面     
  2. // 将返回B页面的clentWidth, clientHeight     
  3. domFrame.contentWindow.document.body.clientWidth;     
  4. domFrame.contentWindow.document.body.clientHeight;    
  • IE中取元素的颜色值可以使用element.currentStyle.color,firefox下没有currentStyle。可以使用下面方法来代替:
  1. function getCurrentStyle(, ) {   
  2.         if (.currentStyle) {   
  3.             return .currentStyle[];   
  4.         } else if (window.getComputedStyle) {   
  5.              = .replace(/([A-Z])/g, "-$1");   
  6.              = .toLowerCase();   
  7.             return window.getComputedStyle(, "").getPropertyValue();   
  8.         }   
  9.         return null;   
  10.     }  
1 (Page 1 of 1)