随着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树载完毕后执行我们的代码
偶这个是从mootools,prototype中抠出来的IE,Firefox下测试通过
Event.addDOMReadyEvent = function($callback) {
var timer, fired = false;
function fireDOMReadyEvent() {
if (fired) {
return;
}
if (timer) {
window.clearInterval(timer);
}
fired = true;
$callback();
}
// firefox, opera, safari ...
if (document.addEventListener) {
if (window.webkit) {
timer = window.setInterval(function() {
if (/loaded|complete/.test(document.readyState)) {
fireDOMReadyEvent();
}
}, 10);
Event.addEvent(window, 'load', fireDOMReadyEvent);
} else {
// firefox, opera9 使用 DOMContentLoaded
document.addEventListener("DOMContentLoaded", fireDOMReadyEvent, false);
}
} else {
// Internet Explorer中使用 defer 属性
var src = (window.location.protocol == 'https') ? '://0' : 'javascript:void(0)';
document.write('<SCRIPT id=__tbOnDOMReady src="' + src + '" defer><\/script>');
$('__tbOnDOMReady').onreadystatechange = function() {
if (this.readyState == 'complete') {
this.onreadystatechange = null;
fireDOMReadyEvent();
}
};
}
}
IE/OPERA下元素有innerText这个方法用来剔除dom下的html标签,快速的取得文本内容。
Firefox下没有这个属性,可以用DOM Level3的textContent来代替。
<DIV id=target><SPAN>hello </SPAN>world</DIV>
<SCRIPT type=text/javascript>
var dom = document.getElementById("target");
if (dom.innerText) {
alert("innerText: " + dom.innerText);
} else {
alert("textContent: " + dom.textContent);
}
</SCRIPT>
有文章说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);
之前的留言回复使用tiny_mec做所见即所得编辑器,速度感觉太慢了,于是自己想写个简单的UBB编辑器玩玩,碰到一些问题记这里:
IE和Firefox下取消事件冒泡
function showEmot() { var evt = || event; if(evt.preventDefault) { // Firefox evt.preventDefault(); evt.stopPropagation(); } else { // IE evt.cancelBubble=true; evt.returnValue = false; } }
textarea下将一段内容替换鼠标所选文字或插入到当前光标位置
function append($val) { // sEditorId textarea的ID var eObj = document.getElementById(sEditorId); // ie if (eObj.createTextRange) { eObj.focus(); document.selection.createRange().duplicate().text = $val; } else { // firefox var iStart = eObj.selectionStart; var iEnd = eObj.selectionEnd; eObj.value = eObj.value.substr(0, iStart) + $val + eObj.value.substr(iEnd, eObj.value.length); eObj.focus(); } }
字符串形式的xml数据(和html合在一起),在IE和FF下都可以用一般的dom标签定位到过去取值。
但在FF中有一个BUG,假如值有时,取出来的值会是:[CDATA[数据]]。
<XMP id=target> <root><node><![CDATA[数据]]></node></root> </XMP>
function getXmlFromString($str) {
// 简单用这种方法判断一下是否是IE
if (document.all) {
var xmlDom = new ActiveXObject("Microsoft.XMLDOM");
xmlDom.loadXML($str);
return xmlDom;
} else {
return new DOMParser().parseFromString($str, "text/xml");
}
} // 此时就可以用像处理xml一样的方法取值了 var doc = getXmlFromString(document.getElementById("target").innerHTML); alert(doc.childNodes[0].childNodes[0].childNodes[0].nodeValue);
这里说的跨浏览器主要指的是IE及Firefox
首先推荐使用或阅读Prototype.js,其中解决了很多IE及firefox下的兼容问题。
然后就是“Javascript的IE和Firefox兼容性汇编”这篇文章。
这里主要记录是一些本人碰到,而上面又没有涉及的问题
if (typeof(domFrame.onreadystatechange) != "undefined") {
// ie
domFrame.onreadystatechange = notify;
} else {
// firefox
domFrame.onload = notify;
}
function notify() {
alert('iframe内容装载完成');
}
像上面那个例子,假如在B页面中写onload事件回调方法,在方法中取clientHeight,clientWidth返回值将不正确。
解决方法可以在A页面中来取值或设置
// A页面
// 将返回B页面的clentWidth, clientHeight
domFrame.contentWindow.document.body.clientWidth;
domFrame.contentWindow.document.body.clientHeight;
function getCurrentStyle(obj, prop) {
if (obj.currentStyle) {
return obj.currentStyle[prop];
} else if (window.getComputedStyle) {
prop = prop.replace(/([A-Z])/g, "-$1");
prop = prop.toLowerCase();
return window.getComputedStyle(obj, "").getPropertyValue();
}
return null;
}