第二十课:js中如何操作元素的属性系统
本章的内容有点复杂,我将用简单的方式来介绍重要的东西,不重要的东西,这里就不讲了,讲了也毛用。
通常我们把对象的非函数成员叫做属性。对元素节点来说,其属性大题分为两大类,固有属性和自定义属性。固有属性拥有默认值,并且无法删除。自定义属性是用户随意添加的键值对。浏览器提供一组API来供人们操作自定义属性,即:setAttribute,getAttribute,removeAttribute,我们统称这组API为DOM属性系统。
DOM属性系统对属性名会进行小写处理,属性值会统一转字符串,举个例子:
div.setAttribute("xxx","1");
div.setAttribute("XxX","2");
div.setAttribute("XXx",3);
div.getAttribute("xxx");
div.getAttribute("XxX");
标准浏览器以及IE8以及以上浏览器会返回"3",因为属性名name先进行小写处理,所以第三个setAttribute会覆盖前面的属性设置,值被赋值为"3"。而取值时,也会把属性名name先进行小写处理,因此以上两个getAttribute都会返回"3"(会转换成字符串)。
但是IE6-7就很变态,第二个和第三个setAttribute不会覆盖第一个的设置,但是在取值时,也就是getAttribute时,第一个返回"1",第二个也返回"1"。本人又在IE7下去测试了一下:
var div = document.createElement("div");
div.setAttribute("xXx","1");
div.setAttribute("XXX",2);
console.log(div.getAttribute("xXx")); //"2"
console.log(div.getAttribute("XXX")); //"2"
简直是超级表态,对于超级变态的东西,没必要深究了,忽略IE6-7。记住上面的规则就OK了。
IE6-IE7在处理固有属性时,有时需要进行名字映射,比如:class变成className,for变成htmlFor。
元素内部撑起整个属性系统的attributes类数组属性
IE6-IE7中,attributes会包含上百个特性节点。不管你是用setAttribute定义的属性,还是以el.name = key定义的属性,还是没有定义的属性。在IE8和其他浏览器中,你只看到了寥寥可数的几个特性节点,这些被称为显式属性。
显式属性是被显式设置的属性,分两种情况:一种是写在标签内的HTML属性,一种是通过setAttribute动态设置的属性。这些属性不分固有的还是自定义的,只要设置了,都会出现在attributes中。在IE6-7中,我们可以通过特性节点的specified属性判定它是否被显式设置了。在IE8以及其他浏览器可以通过hasAttribute来判定属性是否被显式设置了。
因此有以下方法判定元素的属性是否是显示设置的属性:
var isSpecified = !!"1"[0] ? function(el, attr){ return el.hasAttribute(attr) } : function(el, attr){ var val = el.attributes[attr]; return !!val && val.specified }
在IE6-7下"1"[0]返回false,而IE8和其他浏览器返回true。
HTML5对属性也进行了分类,dataset对象装载着所有以data-开头的自定义属性。classList装载着元素的所有类名。formData装载着所有要提供到后台的数据,以表单元素name值与value值构成的不透明对象(不能通过for in进行循环遍历)。表单元素的form属性总是指向其外围的表单对象form。
如何区分固有属性与自定义属性
IE下,元素节点的attributes对象有一种名为expando的的布尔属性,可以判定它是否为自定义属性。
function isCustomAttribute(attr, elem){ //true就代表attr是elem的自定义属性
var attrs= elem.attributes;
return attrs[attr] && attrs[attr].expando == true;
}
但是标准浏览器没有名为expando的布尔属性。
兼容性的写法如下:
function isCustomAttribute(attr,elem){
elem = elem || document.createElement("div"); //有些属性只有特殊元素才会有,这时才需要传入这个元素。一般的属性,直接用div元素
return elem.getAttribute(attr) === null && elem[attr] === undefined;
}
只有自定义属性,在div元素下,会返回true。如果是固有属性,在div元素下,不会全部满足条件,返回false。如果是其他特殊的属性,比如:checked,这时需要传入元素节点type为radio的input(此input没有设置checked属性,最好是一个新创建的input元素,因为如果你传入一个已经通过setAttribute(checked,null),设置的input,那么测试就会有兼容性问题了),这时也不会全部满足条件,返回false。如果是name属性,直接用div来测试,这时return也会是false,因为name是固有属性。如果你把chaojidan这个名字传进去,那么以上就会return true,表明chaojidan不是固有属性。
这里需要明白的一点就是,elem参数一般不需要,如果你设置了一个div1的chaojidan = "chaojidan",然后调用isCustomAttribute(chaojidan,div1),那么就测试不出来了。因为你已经在div1上设置了属性值chaojidan了,那么你getAttribute(chaojidan)时,就会返回"chaojidao"了。你只需要调用isCustomAttribute(chaojidan)就行了,这时返回的就是true。这个方法的第二个参数,是针对div没有的属性值来设置的。
综上所述:
进行属性判定时,必须确保元素没有设置此属性,最好是新创建的元素。
如何判定浏览器是否区分固有属性和自定义属性
jQuery中通过以下方法来判断:
el.setAttribute("className","t");
el.className !== "t";
如果区分固有属性和自定义属性,以上会返回true。因为如果区分的话,el.setAttribute("className","t")设置的是自定义属性className,这时通过el.className会取到元素节点的class属性,而el的class属性没有设置值是undefined,因此返回true。但是在IE6-7下,是不区分固有属性和自定义属性,因此以上el.className会取到"t",返回false。
这里再介绍一些知识点:
大家在看源码的时候,可能会看到getAttribute(name,4)这种用法,但是getAttribute只接受一个参数的。其实接受第二个参数是IE的专有方法。
在IE下,getAttribute的第二个参数有4个预设值:0是默认情况。1属性名区分大小写。2取出源代码中的原字符串值(IE6-7对动态创建的节点无效,IE6-8对布尔属性无效)。4用户href属性,取得完整路径。这里无须知道IE几下支持,只要知道有这么一个东西就行了,看源码时,至少可以看得懂。
操作class的一些工具方法:
var getClass = function(elem){
return elem.className.replace(/\s+/," ").split(" "); //replace方法,会把类名中多余的空字符串清除掉,然后通过split方法,把类名组装成数组返回。
}
var hasClass = function(elem,cls){
return -1 < (" "+elem.className+" ").indexOf(" "+cls+" "); //空格隔开,才能确保cls是独立的字符串。
}
var addClass = function(elem,cls){
if(!hasClass(elem,cls)) elem.className + = " " + cls;
}
var removeClass = function(elem,cls){
if(hasClass(elem,cls)){
var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');
//此正则前半部分\\s,因为是new RegExp,所以\需要转义,其实\\s就是\s,只不过s前面的\需要转义。|是或的意思,^是开始标识。后半部分$是结束标识
elem.className = elem.className.replace(reg," "); //之所有用此正则,因为cls可能在最前面(匹配^+cls),最后面(cls+$),最中间(\s+cls+\s)
}
}
var clearClass = function(elem,cls){
elem.className = "";
}
在HTML5中,元素添加了一个classList属性对象,这个属性对象有add,toggle,remove,contains方法来操作class属性。
数组some和every方法的区别:
array1.some(callbackfn,thisArg)接受两个参数,
callbackfn
必需。 一个接受最多三个参数的函数。 some 方法会为 array1 中的每个元素调用 callbackfn 函数,直到 callbackfn 返回 true(array1.some返回true),或直到到达数组的结尾(array1.some返回false)。
thisArg
可选。 可在 callbackfn 函数中为其引用 this 关键字的对象。 如果省略 thisArg,则 undefined 将用作 this 值。
some 方法会按升序索引顺序对每个数组元素调用 callbackfn 函数,直到 callbackfn 函数返回 true。 如果找到导致 callbackfn 返回 true 的元素,则 some 方法会立即返回 true。 如果回调不对任何元素返回 true,则 some 方法会返回 false。
不为数组中缺少的元素调用该回调函数。([1,2,"",3,4]),数组的第三项不会执行回调方法
除了数组对象之外,some 方法可由具有 length 属性且具有已按数字编制索引的属性名的任何对象使用。(arguments,jQuery对象等)
function callbackfn(value, index, array1),可使用最多三个参数来声明回调函数。
every方法跟some方法很相似,除了返回值的条件不一样:
every 方法会按升序顺序对每个数组元素调用一次 callbackfn 函数,直到 callbackfn 函数返回 false。 如果找到导致 callbackfn 返回 false 的元素,则 every 方法会立即返回 false。 否则,every 方法返回 true。
综上所述:some方法,只要数组中有一个让回调方法返回true,就返回true。every方法,数组中的每一个都让回调方法返回true,才返回true。
加油!
第二十课:js中如何操作元素的属性系统的更多相关文章
- 在js中获取页面元素的属性值时,弱类型导致的诡异事件踩坑记录,
前几天写一个js的时候遇到一个非常诡异的事情,这个问题是这样的,我要获取一个页面的DOM元素的val值,判断这个值是否比某个变量大,这个需求原先数字最大也就是10,现在要改了,可能会更多,这个时候我发 ...
- NeHe OpenGL教程 第二十课:蒙板
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- JQuery中操作元素的属性_对象属性
我们主要是通过attr去获取元素的属性: 看body内容: <body> <p> 账号:<input type="text" id="una ...
- Kali Linux Web 渗透测试视频教—第二十课-利用kali linux光盘或者usb启动盘破解windows密码
Kali Linux Web 渗透测试视频教—第二十课-利用kali linux光盘或者usb启动盘破解windows密码 文/玄魂 目录 Kali Linux Web 渗透测试视频教—第二十课-利用 ...
- Kali Linux Web 渗透测试— 第二十课-metasploit.meterpreter
Kali Linux Web 渗透测试— 第二十课-metasploit.meterpreter 原文链接:http://www.xuanhun521.com/Blog/7fc11b7a-b6cb-4 ...
- js中常用追加元素的几种方法
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- js中如何操作json数据
一.要想熟练的操作json数据,就先要了解json数据的结构,json有两种结构:对象和数组. 1.对象 一个对象以“{”开始,“}”结束.每个“名称”后跟一个“:”:“‘名称/值’ 对”之间使用“, ...
- JS中对数组元素进行增删改移
在js中对数组元素进行增删改移,简单总结了一下方法: 方法 说明 实例 push( ); 在原来数组中的元素最后面添加元素 arr.push("再见58"); unshift( ) ...
- 从零开始学习jQuery (四) 使用jQuery操作元素的属性与样式
本系列文章导航 从零开始学习jQuery (四) 使用jQuery操作元素的属性与样式 一.摘要 本篇文章讲解如何使用jQuery获取和操作元素的属性和CSS样式. 其中DOM属性和元素属性的区分值得 ...
随机推荐
- jsp EL 表达式
EL表达式 EL 全名为Expression Language EL 语法很简单,它最大的特点就是使用上很方便.接下来介绍EL主要的语法结构: ${sessionScope.user.sex} 所有E ...
- STL的erase()陷阱-迭代器失效总结
下面材料整理自Internet&著作. STL中的容器按存储方式分为两类,一类是按以数组形式存储的容器(如:vector .deque):另一类是以不连续的节点形式存储的容器(如:list.s ...
- Storm之spout,bolt编写
Storm,核心代码使用clojure书写,实用程序使用python开发,使用java开发拓扑. Nimbus节点接收到请求,对提交的拓扑进行分片,分成一个个的task,并将task和supervis ...
- 基于Retrotfit2.1+Material Design+ijkplayer开发的一个APP(新闻,gif 动图,视频播放)
此项目主要目的还是为了练习框架的使用,仅供学习用途. 数据来源 新闻 直接用的聚合数据提供的接口:https://www.juhe.cn/docs/api/id/235gif动图 通过jsoup爬的某 ...
- 使用EntityFramework6完成增删查改和事务
使用EntityFramework6完成增删查改和事务 上一节我们已经学习了如何使用EF连接数据库,并简单演示了一下如何使用EF6对数据库进行操作,这一节我来详细讲解一下. 使用EF对数据库进行操作, ...
- TYVJ1288 飘飘乎居士取能量块 -SilverN
描述 9月21日,今天是pink的生日,飘飘乎居士当然要去别人的领土大闹一番啦! 为了收集更多的能量到pink家大闹,飘飘乎居士准备从后花园中取出自己多年积攒的p个能量块.后花园一共被划分n个地 ...
- codeforces 721B B. Passwords(贪心)
题目链接: B. Passwords time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- 关于jQuery的一些实用代码
(1)修改默认编码:(将默认的utf-8,修改为GB2312) $.ajaxSetup({ ajaxSettings:{contentType:"application/x-www-from ...
- javascript中的时间处理
var myDate = new Date(); myDate.getYear(); //获取当前年份(2位) myDate.getFullYear(); //获取完整的年份(4位,1970-???? ...
- 阻塞与非阻塞IO step by step
谈到IO,阻塞.非阻塞,异步.同步是绕不开的话题.说实话,我也没搞清楚,网上查了许多资料,大家众说纷纭,一种比较靠谱的说法是:”在处理 IO 的时候,阻塞和非阻塞都是同步 IO,使用使用了特殊的API ...