跨浏览器通信
建立跨浏览器通信有两个前提条件
- 两个窗口都包含来自同一个域的页面;
- 其中一个窗口包含对另一个窗口的引用。
第一个条件是JavaScript同源策略的结果,保护用户的隐私,第二个条件是为了使一个窗口知道另一个窗口的存在。实现通信主要是涉及到window对象的name和opener属性,以及open()方法。
window.name属性的作用是为HTML链接的target属性作引导的,同时它也可以引导弹出窗口。它的默认值为空,但可以设置的。
window.name = "endlesscode";
点击带有此target的链接,比如<a href=”somepage.html” target=”endlesscode”>,该链接就会在window.name为”endlesscode”的窗口打开。另外,也可以在window.open()方法中使用name,例如:
window.open("somepage.html", "endlesscode", [arguments]);
这样浏览器就会查找名字叫做”endlesscode”的窗口。如果它找到一个,somepage.html就会在这个窗口打开。如果没有找到,就找开一个新窗口,并将name命名为”endlesscode”。其实像wp的预览、优酷的视频观看页面以及卓越的书目录页面都是使用这种方式在同一个页面打开的。
window.opener属性是弹出窗口指回主窗口的引用,如果新页面被载入到弹出窗口中(如果用户点击了一个链接),opener属性仍旧可用。如果新页面是载入到主窗口中,则可以通过在弹出窗口中
opener.ST_newWindow = window;
来在主窗口中保存弹出窗口的引用。
弹出窗口拦截软件
主流的浏览器一般都会有弹出窗口拦截的功能,可以拦截页面上的弹出窗口,但实际上浏览器厂商并没有简单地禁用了window.open()方法,因为弹出窗口还是有合理的使用方法。相反,它们只拦截未被(用户)请求的弹出框。而对于“未被请求的弹出窗口”,浏览器厂商一般的定义似乎是:在用户点击之后打开的窗口是被请求的,而其他的则不是被请求的。因此,下面的代码是可以绕过弹出窗口过滤器的:
var popup;
document.onclick = function() {
popup = window.open("somepage.html", "name", [arguments]);
}
这样,用户点击文档的任何位置,弹出窗口都会跳出来,因为点击动作是用户请求的。
href与replace()
location.href和location.replace()有同样的功能是,使浏览器载入新的页面,但并非完全一样。如果你改变了页面的location.href,就好像用户点击了某个链接,于是浏览器加载一个新页面。这个新页面就会成为窗口历史中的一项新条目。而如果使用replace(),新页面就会直接覆盖窗口历史当前页面的条目。
在IE中创建并添加option元素
在Explorer中createElement(option)是可以的,但是不直接支持appendChild(option),想要在IE为select添加一个option的话,需要调用:
/* 方法一 使用select.options.add */
var newOpt = document.createElement("option");
newOpt.text = "text";
newOpt.value = "value";
select.options.add(newOpt);
/* 方法二 使用createTextNode建立option标签内的文字内容 */
var newOpt = document.createElement("option");
var oText = document.createTextNode("text");
newOpt.appendChild(oText);
newOpt.setAttribute("value", "value");
select.appendChild(newOpt);
更改样式表
成功进行样式表编辑的第一个必要条件就是支持document.styleSheets节点序列,document.styleSheets包含了link和style标签里面的样式表,以数组的形式组织,并按照在源代码中的出现顺序被一一编号。

访问样式表中的所有规则,Mozilla使用w3c规范定义的cssRules[]节点序列,而Explorer必须使用微软专有的rules[]节点序列,幸运的是,这两个属性除了名字不同外几乎是一样的。
currentSheet = document.styleSheets[0];
if (currentSheet.cssRules)
sheetRules = currentSheet.cssRules;
else if (currentSheet.rules)
sheetRules = currentSheet.rules;
else return;
每一条规则都有一个selectorText属性,以字符串的形式保存着规则的选择符:
/* 接上面 */
for (var i=0;i<sheetRules.length;i++)
alert(sheetRules[i].selectorText);
每条规则都有一个style属性,它用起来像单个HTML元素的style属性:
/* 接上面 */ /* 第一条规则的color被设置为#cccccc */ var currentRule = sheetRules[0]; currentRule.style.color = "#cccccc";
在读取样式表完整文本上还没有跨浏览器的方法,cssText属性可以访问css文本内容,但浏览器们没有在这个属性的作用域上完全达成一致:
document.styleSheets[0].cssText; //Windows & Mac 支持 document.styleSheets[0].cssRules[0].cssText; //Mac下的Explorer和Mozilla document.styleSheets[0].cssRules[0].style.cssText; //所有浏览器都支持
添加和删除某个规则,w3c使用insertRule/deleteRule,而Explorer使用微软专用的addRule/removeRule。Safari和Opera完全不支持添加和删除的行为。
/* w3c */
var x = document.styleSheets[0];
x.insertRule('PRE { font:0.9em verdana }', 2); // (ruleContent, ruleIndex)
x.deleteRule(2); //(ruleIndex)
/* IE */
var x = document.styleSheets[0];
x.addRule('PRE', 'font:0.9em verdana', 2); // (selector, declaration, index)
x.removeRule(2); //(index)
其它
- readystatechange事件在Explorer中,是可以应用在所有的元素中,但其他浏览器只支持将它用在XMLHttpRequest对象上。
- load事件是在页面完全加载后(包括图片等文件),才会触发的。而无论什么原因引起页面释放时,会触发unload事件,包括点击一个链接、提交表单、关闭浏览器窗口等等。
- 取消事件传播:
var evt = [the event object];
if (evt.stopPropagation) // w3c
evt.stopPropagation();
evt.cancelBubble = true; // ie
- appendChild、insertBefore、replaceChild三个dom的方法如果要插入的元素已经存在,则移除从当前的结构中移除要插入的元素,其他的元素维持不变。
- childNodes[]包含所有的子节点,children[]包括类型为元素节点的子节点而不包含文本类型的子节点。但children不是w3c dom规范的一部分。
- Explorer并非不允许设置input.type,而是动态创建的input在添加到文档中之前,只允许读/写一次,即:
/* 不可行 */
newField.type = "checkbox";
/* 可行 */
newField.setAttribute("type", "checkbox");