本章的内容有点复杂,我将用简单的方式来介绍重要的东西,不重要的东西,这里就不讲了,讲了也毛用。

通常我们把对象的非函数成员叫做属性。对元素节点来说,其属性大题分为两大类,固有属性和自定义属性。固有属性拥有默认值,并且无法删除。自定义属性是用户随意添加的键值对。浏览器提供一组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中如何操作元素的属性系统的更多相关文章

  1. 在js中获取页面元素的属性值时,弱类型导致的诡异事件踩坑记录,

    前几天写一个js的时候遇到一个非常诡异的事情,这个问题是这样的,我要获取一个页面的DOM元素的val值,判断这个值是否比某个变量大,这个需求原先数字最大也就是10,现在要改了,可能会更多,这个时候我发 ...

  2. NeHe OpenGL教程 第二十课:蒙板

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  3. JQuery中操作元素的属性_对象属性

    我们主要是通过attr去获取元素的属性: 看body内容: <body> <p> 账号:<input type="text" id="una ...

  4. Kali Linux Web 渗透测试视频教—第二十课-利用kali linux光盘或者usb启动盘破解windows密码

    Kali Linux Web 渗透测试视频教—第二十课-利用kali linux光盘或者usb启动盘破解windows密码 文/玄魂 目录 Kali Linux Web 渗透测试视频教—第二十课-利用 ...

  5. Kali Linux Web 渗透测试— 第二十课-metasploit.meterpreter

    Kali Linux Web 渗透测试— 第二十课-metasploit.meterpreter 原文链接:http://www.xuanhun521.com/Blog/7fc11b7a-b6cb-4 ...

  6. js中常用追加元素的几种方法

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. js中如何操作json数据

    一.要想熟练的操作json数据,就先要了解json数据的结构,json有两种结构:对象和数组. 1.对象 一个对象以“{”开始,“}”结束.每个“名称”后跟一个“:”:“‘名称/值’ 对”之间使用“, ...

  8. JS中对数组元素进行增删改移

    在js中对数组元素进行增删改移,简单总结了一下方法: 方法 说明 实例 push( ); 在原来数组中的元素最后面添加元素 arr.push("再见58"); unshift( ) ...

  9. 从零开始学习jQuery (四) 使用jQuery操作元素的属性与样式

    本系列文章导航 从零开始学习jQuery (四) 使用jQuery操作元素的属性与样式 一.摘要 本篇文章讲解如何使用jQuery获取和操作元素的属性和CSS样式. 其中DOM属性和元素属性的区分值得 ...

随机推荐

  1. confluence wiki搭建使用

    1.准备工作 服务器环境:centos6.6x64 IP:172.16.0.203 1)软件包,地址下载 http://pan.baidu.com/s/1ntlBCQP  ,把几个 软件包放在服务器上 ...

  2. openwrt简单ipk生成及Makefile解释

    前言 类似的文章其实网上比较多了,我写这个的目的: 1,网上文章良莠不齐,有些自己都没实际动手操作,随便复制粘贴,实际操作不可行. 2,基本只讲了操作,我当时最关心的Makefile文件的解释没有. ...

  3. MySQL中EXPLAIN的解释

    EXPLAIN是查看MySQL优化器如何决定执行查询的主要方法,这个功能具有局限性,以为它并总是会说出真相,但是却可以获得最好信息. 学会解释EXPLAIN,你就会了解MySQL优化器是如何工作,你才 ...

  4. nopcommerce之权限模块

    这篇文章简单介绍一下nopcommerce的权限模块,nopcommerce里面的权限设计相对比较简单,主要针对后台的action和前台的是否显示(比如产品.品牌等),虽然简单但是应付一般的项目应该没 ...

  5. UVA-10652 (凸包)

    题意: 给n个矩形,问包含这些矩形的尽量小的凸多边形的面积是多少; 思路: 由于给的矩形的形式是给出了中心的坐标,长和宽以及旋转的角度,所以先转换成四个点的坐标,然后求一遍凸包就好了,第一次写凸包,代 ...

  6. Android网络之数据解析----使用Google Gson解析Json数据

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  7. AC日记——codevs 1688 求逆序对

    1688 求逆序对  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Description 给定一个序列a1,a2,…, ...

  8. java 16 -4 LinkedList的特有功能

    了解 LinkedList的特有功能: A:添加功能 public void addFirst(Object e) public void addLast(Object e) B:获取功能 publi ...

  9. linux上的常见命令掌握

    http://coolshell.cn/articles/8883.html 这篇文章来源于Quroa的一个问答<What are some time-saving tips that ever ...

  10. C#综合揭秘——细说多线程(下)

    引言 本文主要从线程的基础用法,CLR线程池当中工作者线程与I/O线程的开发,并行操作PLINQ等多个方面介绍多线程的开发.其中委托的BeginInvoke方法以及回调函数最为常用.而 I/O线程可能 ...