第二十一课:js属性操作的兼容性问题
上一课主要讲了属性的概念,用法,固有属性和自定义属性的区别,class属性操作的方法等,这一课主要讲一些有关属性操作的兼容性问题。
IE6-IE8在一些表示URL的属性会返回补全的改过编码的路径,比如:href,action,background,cite,data,src,url等。我们只需要用getAttribute(href,2),就能很好的兼容各种浏览器了。标准浏览器不支持第二个参数,因此忽略第二个参数。而IE支持第二个参数,2代表只取出原字符串的值。
IE6-7下,对于form元素,调用getAttribute取属性值,会取到它的子元素input(ID值或name值等于属性值的input)。举个例子:
<form action="#">
<input id="action" >
<input name="length">
</form>
var el = document.getElementsByTagName("form")[0];
el.getAttribute("action"); //会取到<input id="action" >,IE6-7下
el.getAttribute("length"); //<input name="length">,IE6-7下
对于布尔属性,比如checked,IE6-IE8都无法取得用户预设值(<input type="radio" checked="chaojidan">),无论是通过elem.getAttribute("checked"),加上第二个参数2,还是elem.checked,都得不到"chaojidan"。
注释节点的nodeType等于8。
tabindex的取值问题
tabindex 属性规定元素的 tab 键控制次序(当 tab 键用于导航时)。<element tabindex="number"
>,number 规定元素的 tab 键控制次序(1 是第一个)。tabindex默认情况下只对表单元素与链接有效,对于这些元素,如果你没有显式设置tabindex,标准浏览器下,它会返回0,而对于div这样的默认不支持tabindex属性的,会返回-1.但IE6-8下都返回0.
在chrome中,如果你把固有属性从原型中删掉(delete操作符),会导致下次赋值时出错。
IE7不能修改表单元素的type属性。
这里讲一下判定一个元素的属性是否是布尔属性的方法:
function isBoolAttr(node,prop){
var isBool = typeof node[prop] ==="boolean" && typeof defaultProp(node,prop) ==="boolean";
//如果元素的属性值是boolean类型,就证明它有机会是布尔属性。(还要排除用户强制执行node[prop]=true(false)的情况,这时不是元素默认的情况,而是用户强制赋值)
return isBool;
}
function defaultProp(node,prop){
return document.createElement(node.tagName)[prop]; //创建一个新的node元素,然后判断这个新节点的prop属性是否是boolean类型。
}
IE6-IE8下有一个href属性的bug,书上的例子没看懂,直接去http://gabriel.nagmay.com/2008/11/javascript-href-bug-in-ie/看了一下,我的理解是:
<a href="http://www.google.com">google.com</a> // fine - changing href will not change text
<a href="http://www.google.com">http://www.google.com</a> // bad - changing href will change the inner html text
address = "@pcc.edu addresses"
$(this).attr("href","http://www.pcc.edu/resources/web/forms/email/?to="+address);
以上代码的意思就是,当a链接的href属性值和a链接的text值相同时,当你改变href的属性值时,会把text值一起替换掉。
解决办法:
(1)text跟href的值不一样,就行了。(这里需要参考下面的讲解,其实如果text里面没有标签元素,同时以www.开头,或者包含@字符,都会引起上面的问题,这里所说的解决办法,只是针对以上例子的特殊情况,比如:google.com不等于http://www.google.com)
(2)在替换href时,我们用相对地址就行了。$(this).attr("href","/resources/web/forms/email/?to="+address);(这里只能解决text跟href相同的情况,不能解决a链接的text里面没有标签元素,同时以www.开头,或者包含@字符的情况)
(3)var linkHtml = $(this).html();先把text的值取出来,$(this).attr("href","http://www.pcc.edu/resources/web/forms/email/?to="+address).html(linkHtml);替换了href后,再恢复成原来的text的值。(这里也有问题,如果<a> 元素里面可能不是一段文本,而是一个 <img>,并且这个 <img> 上绑定了事件,那么,再将 innerHTML 写回去时,就会生成新的节点,原来绑定的事件也就失效了。)
司徒正美的书上有另外一个href属性的bug,在IE6-8下,链接地址:http://oldj.net/article/ie-bug-at-href-innerhtml/,我的理解是:
<a id="a-test" href="http://www.taobao.com">链接@BABY</a>
setTimeout(function () {
var a = document.getElementById("a-test");
a.href = "http://rate.taobao.com/";
}, 3000);
页面打开时,链接的内容为“链接@BABY”,一切正常,但当 js 函数执行,修改了 <a> 元素的 href 属性时,它的 innerHTML 值也变成了同样的值(http://rate.taobao.com/)。除了直接给 a.href 赋值外,使用 a.setAttribute 方法也是一样的效果。
解决办法:
var a = document.getElementById("a-test"), s;
s = a.innerHTML; // 先记下 innerHTML
a.href = "http://rate.taobao.com/";
a.innerHTML = s; // 再将 innerHTML 的值写回去
上面那种先记下 innerHTML 的值,修改 href 之后再将它写回去的做法是有隐患的。比如,<a> 元素里面可能不是一段文本,而是一个 <img>,并且这个 <img> 上绑定了事件,那么,再将 innerHTML 写回去时,就会生成新的节点,原来绑定的事件也就失效了。
一个更好的方法,只需在要写入的 href 的值前面加一个半角空格即可,而现代浏览器会安全地忽略掉 href 值前后的多余的空白字符。即:
a.href = " " + "http://rate.taobao.com/";
或者:
a.href = " http://rate.taobao.com/"; // 注意前面的空格
在 href 前面加一个空格的方式副作用太多,最后决定使用先加一个 <b></b> 节点然后再删除的方法。
var b,
inner_html = anchor.innerHTML;
if (inner_html && inner_html.indexOf("<") == -1) { //如果a链接有值,并且它的innerHTML没有标签(子元素节点),就创建一个子节点
b = doc.createElement("b");
b.style.display = "none";
anchor.appendChild(b);
}
anchor.href = href;
if (b) {
anchor.removeChild(b);
}
上面代码的意思是:如果a标签的值里面包含其他元素节点,那么改变它的href属性值时,不会改变a标签的值。
进一步测试发现,如果a标签没有子元素, <a> 链接的内容(值)以“www.”开头,也会有这个问题。
总结以上所有讨论,得到chaojidan的结论:
在a标签没有子元素的情况下,凡是形如电子邮件(包含“@”字符)或网址(以“www.”开头)的字符串,在 IE6/7/8 中都有这种行为。同时,如果a链接的href属性值和a链接的text值相同,也会出现这样的行为。
以上属于超级变态,了解就行。
value的操作
select元素,它的value值就是其被选中的option孩子的value值。不过,select有两种形态。一种type为select-one,一种是select-multiple。option元素,它的value值可以使value属性的值,也可以是其中间文本的值。当用户没有显式设置value属性时,就可以使用其文本的值。取文本可以使用text,或者innerHTML这两种方法,但是option元素的text属性会做trim操作,支持所有浏览器。但只有旧版本的IE,在innerHTML会做trim操作,标准浏览器不会。如何判定option设置了value属性,IE6-7可以使用specified,标准浏览器使用hasAttribute来判定,具体操作请看上一课.
button,它的取值在IE6-7下是取它的text,IE8以及以上IE浏览器才会取value属性的值。标准浏览器,button标签只有当其为提交按钮,(type = submit)时,点击按钮,才会提交其value属性的值。
在safari5下,如果设置了select为disable,那么它的所有孩子都是disable的。
checkbox的value属性值默认为on,只有chrome是空字符串。
在旧版本IE下,form表reset后,select中的option不会改变为默认的selected值。举个例子:默认情况下,select的第一个option有selected属性,就代表第一个option显示在select中。当你做了操作后,把第二个option变成了selected,这时select中显示的是第二个option。这时你点击reset按钮,恢复默认值。在IE旧版本下,select中的option不会把selected值赋给第一个option,恢复默认。而不做任何改变,还是在第二个option中。但是其他浏览器就会恢复默认值,显示在第一个option中。
加油!
第二十一课:js属性操作的兼容性问题的更多相关文章
- NeHe OpenGL教程 第二十一课:线的游戏
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- [妙味JS基础]第一课:属性操作、图片切换、短信发送模拟
知识点总结 HTML的属性操作:读.写 元素.属性名 => “读” 元素.属性名=新的值 => “写” 例如: oBtn.value => “读” oBtn.value='按钮' = ...
- JS属性操作
一.属性读操作:元素.属性名 ( 获取.找到属性值 ) 属性写操作:元素.属性名 = 新的值 ( 替换.修改属性值 ) 二.没有属性名的,也可进行读.写操作: 读操作:元素.innerHTML ...
- 快学Scala 第二十一课 (初始化trait的抽象字段)
初始化trait的抽象字段: trait Logged { println("Logged constructor") def log(msg: String){ println( ...
- Python学习第二十一课——Mysql 对数据库的基本操作
数据库操作(DDL) 在数据库下创建表(create_table) 创建表代码块: CREATE TABLE employee( id TINYINT PRIMARY KEY auto_increme ...
- 潭州课堂25班:Ph201805201 django 项目 第二十一课 文章主页 新闻列表页面功能 (课堂笔记)
新闻列表页功能 1.分析 业务处理流程: 判断前端传的标签分类id是否为空,是否为整数.是否超过范围 判断前端传的当前文章页数是否为空,是否为整数.是否超过范围 请求方法:GET url定义:/new ...
- python第二十一课——str中的常用函数(重要)
演示str中常用的一些函数: 1.join():将容器对象以某种特定的格式(字符串)进行拼接组合,最后以字符串的形式返回 lt=['i','love','you','very','much'] str ...
- Spring入门第二十一课
切面优先级 先看代码: package logan.study.aop.impl; public interface ArithmeticCalculator { int add(int i, int ...
- JAVA学习第二十一课(多线程(一)) - (初步了解)
放假在家,歇了好几天了,也没学习,今天学习一下多线程.找找感觉.后天就要回学校了.sad... PS:包 没有什么技术含量,会用就可以,日后开发就必需要会用啦,所以打算先放一放,先来多线程 一.多线程 ...
随机推荐
- linux安装hadoop 1.2.1
我的服务器里面会装很多东西,所以我在跟目录下面建立了个doc文档文件夹 1.创建存放软件的doc文件夹 mkdir doc 2.进去doc文件夹进行下载hadoop-1.2.1资源包或者到我的百度云下 ...
- hadooop 配置多网卡 提供跨网段服务
http://hortonworks.com/blog/multihoming-on-hadoop-yarn-clusters/ https://hadoop.apache.org/docs/r2.6 ...
- NP完全问题 NP-Completeness
原创翻译加学习笔记,方便国人学习算法知识! 原文链接http://www.geeksforgeeks.org/np-completeness-set-1/ 我们已经找到很多很高效的算法来解决很难得问题 ...
- ref out 方法参数
ref out 相似 ref和out两个关键字的作用大致相同,但是有一些微妙但是重要的区别. 两者的行为相似到连编译器都认为这两者不能被重载:public void SampleMethod(out ...
- java 20 -2 递归之找特定目录下的特定格式文件
/* 需求:把C:\Users\Administrator\Desktop\记录目录下所有以.java结尾的文件的绝对路径输出到控制台 分析: A:封装该目录 B:获取该目录下的所有文件或文件夹的Fi ...
- xshell5.0实现中键复制
1. 右建点击黑色屏幕 2. 在打开选项 3. 勾选 ""
- AE二次开发技巧之撤销、重做
原文地址:http://www.cnblogs.com/wylaok/articles/2363208.html 可以把AE自带的重做.撤销按钮或工具添加到axToolBarControl上,再把ax ...
- 应用python编写简单新浪微博应用(一)
转载至:http://blog.sina.com.cn/s/blog_6c39196501016o7n.html 首先,你要有一个新浪微博账号. 申请页面:http://weibo.com 其次,你要 ...
- 使用CSS3制作72个webapp图标
前言 移动网络带宽的快慢直接影响webapp应用体验效果的优差,其中加载图片是很耗流量的,所以对这一方面的性能优化是很需要的.一般对于那些小而多的图片(图标)都会采用sprite合并成一张图片来减少h ...
- Javascript的变量与delete操作符
原文:http://charlee.li/javascript-variables-and-delete-operator.html 刚刚看到一篇好文(原文链接), 对Javascript中的dele ...