js DOM属性

来源:互联网 发布:木琴软件 编辑:程序博客网 时间:2024/05/27 01:15



<!--这些url xxx yyy都是自定义属性  在浏览器的element找不到相应的内容-->  <div url="http://www.baidu.com" xxx="aaa" Yyy="bbb" xxx="ccc"></div>

  • property是DOM中的属性,是JavaScript里的对象;
  • attribute是HTML标签上的特性,它的值只能够是字符串;

基于JavaScript分析property 和 attribute

html中有这样一段代码:

<input id="in_1" value="1" sth="whatever">

简单的在html页面上创建一个input输入栏(注意在这个标签中添加了一个DOM中不存在的属性“sth”),此时在JS执行如下语句

var in1 = document.getElementById('in_1');

执行语句

console.log(in1);           

从console的打印结果,可以看到in1含有一个名为“attributes”的属性,它的类型是NamedNodeMap,同时还有“id”和“value”两个基本的属性,但没有“sth”这个自定义的属性。

attributes: NamedNodeMapvalue: "1"id: "in_1"

有些console可能不会打印in1上的属性,那么可以执行以下命令打印要观察的属性:

console.log(in1.id);        // 'in_1'console.log(in1.value);     // 1console.log(in1.sth);       // undefined

可以发现,标签中的三个属性,只有“id”和“value”会在in1上创建,而“sth”不会被创建。这是由于,每一个DOM对象都会有它默认的基本属性,而在创建的时候,它只会创建这些基本属性,我们在TAG标签中自定义的属性是不会直接放到DOM中的。

我们做一个额外的测试,创建另一个input标签,并执行类似的操作:

html:

<input id="in_2">

JS:

var in2 = document.getElementById('in_2');console.log(in2);

从打印信息中可以看到:

id: "in_2"value: null

尽管我们没有在TAG中定义“value”,但由于它是DOM默认的基本属性,在DOM初始化的时候它照样会被创建。由此我们可以得出结论:

  • DOM有其默认的基本属性,而这些属性就是所谓的“property”,无论如何,它们都会在初始化的时候再DOM对象上创建。
  • 如果在TAG对这些属性进行赋值,那么这些值就会作为初始值赋给DOM的同名property。

现在回到第一个input(“#in_1”),我们就会问,“sth”去哪里了?别急,我们把attributes这个属性打印出来看看

console.log(in1.attributes);

上面有几个属性:

0: id1: value2: sthlength: 3__proto__: NamedNodeMap

原来“sth”被放到了attributes这个对象里面,这个对象按顺序记录了我们在TAG中定义的属性和属性的数量。此时,如果再将第二个input标签的attributes打印出来,就会发现只有一个“id”属性,“length”为1。

从这里就可以看出,attributes是属于property的一个子集,它保存了HTML标签上定义属性。如果再进一步探索attitudes中的每一个属性,会发现它们并不是简单的对象,它是一个Attr类型的对象,拥有NodeType、NodeName等属性。关于这一点,稍后再研究。注意,打印attribute属性不会直接得到对象的值,而是获取一个包含属性名和值的字符串,如:

那么,如果我们更改property和attribute的值会出现什么效果呢?执行如下语句:

in1.value = 'new value of prop';console.log(in1.value);             // 'new value of prop'console.log(in1.attributes.value);  // 'value="1"'

此时,页面中的输入栏的值变成了“new value of prop”,而propety中的value也变成了新的值,但attributes却仍然是“1”。从这里可以推断,property和attribute的同名属性的值并不是双向绑定的。

如果反过来,设置attitudes中的值,效果会怎样呢?

in1.attributes.value.value = 'new value of attr';console.log(in1.value);             // 'new value of attr'console.log(in1.attributes.value);  // 'new value of attr'

此时,页面中的输入栏得到更新,property中的value也发生了变化。此外,执行下面语句也会得到一样的结果

in1.attributes.value.nodeValue = 'new value of attr';

由此,可得出结论:

  • property能够从attribute中得到同步
  • attribute不会同步property上的值
  • attribute和property之间的数据绑定是单向的,attribute->property;
  • 更改property和attribute上的任意值,都会将更新反映到HTML页面中;






固有属性property

<!DOCTYPE html><html>  <head>    <meta charset="utf-8">    <meta name="viewport" content="width=device-width, initial-scale=1">    <title>Property</title>    <script src="domReady.js"></script>    <script>      myReady(function(){        var a = document.getElementById('txt');        console.log(a.type);        console.log(a.id);        console.log(a.a);        console.log(a.title);      });    </script>  </head>  <body>    <input type="text" id="txt" a="b" />  </body></html>


自定义属性attribute

<!DOCTYPE html><html>  <head>    <meta charset="utf-8">    <meta name="viewport" content="width=device-width, initial-scale=1">    <title>attribute</title>    <script src="domReady.js"></script>    <script>      myReady(function(){        var div = document.querySelector('div');        console.log(div.attributes);//会将两种属性都打印出来      });    </script>  </head>  <body>  <!--这些url xxx yyy都是自定义属性  在浏览器的element找不到相应的内容-->    <div url="http://www.baidu.com" xxx="aaa" Yyy="bbb" xxx="ccc"></div>  </body></html>



tips:attributes返回指定节点属性集合  getNamedItem返回节点列表中指定属性名的值。(ie8以下不支持);



<!DOCTYPE html><html>  <head>    <meta charset="utf-8">    <meta name="viewport" content="width=device-width, initial-scale=1">    <title>Attributes</title>    <script src="domReady.js"></script>    <script>      myReady(function(){        var div = document.querySelector('div');        // console.log(div.xxx);无法直接打印xxx        console.log(div.attributes.getNamedItem('xxx').nodeValue);        // console.log(div.nodeName);        // console.log(div.attributes.getNamedItem('nodeName').nodeValue);        //console.log(div.attributes.getNamedItem('id').nodeValue);        // console.log(div.attributes['id'].nodeValue);        div.attributes.removeNamedItem('yyy');        //div.attributes.setNamedItem('data-title', 'ddd');报错        var attr = document.createAttribute('data-title');        attr.value = 'ddd';        div.attributes.setNamedItem(attr);      });    </script>  </head>  <body>    <div id="div0" url="http://www.baidu.com" xxx="aaa" yyy="bbb"></div>  </body></html>

总结

这三种应用于显示的出来的属性


对于显示不出来的

getAttribute

有些属性通过.和getattribute获得的值不同  getattribute既能获得固有属性也能获得自定义属性

<!DOCTYPE html><html>  <head>    <meta charset="utf-8">    <meta name="viewport" content="width=device-width, initial-scale=1">    <title>getAttribute</title>    <script src="domReady.js"></script>    <script>      myReady(function(){        //var div = document.querySelector('div');        var div = document.getElementById('div0');        div.innerHTML = "属性操作方法";        // console.log(div.innerHTML);        // console.log(div.url);        // console.log(div.getAttribute('url'));        // console.log(div.getAttribute('yyy'));        // console.log(div.getAttribute('style'));        // console.log(div.style); style和onclick通过.和getattribute返回的值是不同的 一般使用.方法  只有在取得自定义属性的值的时候才使用getattribute        console.log(div.getAttribute('onclick'));        console.log(div.onclick);      });    </script>  </head>  <body>    <div id="div0" style="color:red" onclick="alert(0)" url="http://www.baidu.com" xxx="aaa" Yyy="bbb"></div>  </body></html>



setattribute  在ie7及之前的版本都无效

<!DOCTYPE html><html>  <head>    <meta charset="utf-8">    <meta name="viewport" content="width=device-width, initial-scale=1">    <title>setAttribute</title>    <script src="domReady.js"></script>    <script>      myReady(function(){        var div = document.getElementById('div0');        div.setAttribute('xxx', 'a');        div.setAttribute('data-event', 'click');        div.setAttribute('style', 'color:blue');        div.setAttribute('onclick', 'alert(1)');      });    </script>  </head>  <body>    <div id="div0" style="color:red" onclick="alert(0)" url="http://www.baidu.com" xxx="aaa" Yyy="bbb">点击我</div>  </body></html>



removeattribute

<!DOCTYPE html><html>  <head>    <meta charset="utf-8">    <meta name="viewport" content="width=device-width, initial-scale=1">    <title>removeAttribute</title>    <script src="domReady.js"></script>    <script>      myReady(function(){        var div = document.getElementById('div0');        div.removeAttribute('style');        alert(document.body.innerHTML);      });    </script>  </head>  <body>    <div id="div0" style="color:red" onclick="alert(0)" url="http://www.baidu.com" xxx="aaa" Yyy="bbb">点击我</div>  </body></html>



对比getNamedItem和getAttribute方法的区别

getNamedItem()返回指定的节点,getAttribute() 方法返回指定属性名的属性值。还有点区别是前面是XML Dom方法,后者是HTML Dom方法。最大的差异是,它俩的使用方法和返回值是不一样的

以这个代码进行测试:

<!DOCTYPE html>

<html>

<head>

    <meta charset="UTF-8">

    <title>Document</title>

</head>

<body>

    <div id="btn" data="1">111</div>

</body>

<script type="text/javascript">

    var btn=document.getElementById("btn");

    console.log(btn.getAttribute("data"));

    console.log(btn.attributes.getNamedItem("data"));

</script>

</html>

它俩的打印结果是:

http://img.mukewang.com/climg/5a3391090001f33e02870115.jpg



布尔属性


checked

<!DOCTYPE html><html>  <head>    <meta charset="utf-8">    <meta name="viewport" content="width=device-width, initial-scale=1">    <title>布尔属性</title>    <script src="domReady.js"></script>    <script>      myReady(function(){        var inputs = document.querySelectorAll("input");        inputs[0].checked = 1;//设置为true或者"非空字符串"或者{}都相当于true  null为false    在ie6 7无法实现        inputs[0].removeAttribute('checked');//固有属性 无法remove      });    </script>  </head>  <body>    你去过的城市:<br/>    <input type="checkbox">北京    <input type="checkbox" checked="checked">香港    <input type="checkbox" checked>纽约  </body></html>


selected

  <script>    myReady(function(){      var city = document.getElementById('city');      var options = city.options;      options[2].selected = true;    });  </script></head><body>  你去过的城市:<br/>  <select name="city" id="city">    <option value="北京">北京</option>    <option value="香港" selected="selected">香港</option>    <option value="纽约">纽约</option>  </select></body>


readonly

<script>    myReady(function(){      var nationality = document.getElementById('nationality');      nationality.readOnly = false;//注意O大写    });  </script></head><body>  国籍:<input id="nationality" type="text" value="中国" readonly="readonly" /></body>


disabled

 <script>    myReady(function(){      var nationality = document.getElementById('nationality');      nationality.disabled = false;    });  </script></head><body>  国籍:<input id="nationality" type="text" value="中国" disabled="disabled" /></body>


multiple

  <script>    myReady(function(){      var city = document.getElementById('city');      city.multiple = false;    });  </script></head><body>  你去过的城市:<br/>  <select name="city" id="city" multiple="multiple">    <option value="北京">北京</option>    <option value="香港" selected="selected">香港</option>    <option value="纽约">纽约</option>  </select>

hidden和display:none效果一样

 <script>    myReady(function(){      var div = document.getElementById('div');      div.hidden = false;    });  </script></head><body>  <div id="div" hidden="hidden">html5 新增属性hidden</div></body>




字符串属性

title为鼠标划过显示的字



translate未被支持


<body><!--dir文字输出方向-->  <p style="text-align:center" id="title" class="large"><bdo dir="RTL">芙蓉楼送辛渐</bdo></p>  <p style="text-align:center" id="author"><bdo dir="RTL">王昌龄</bdo></p>  <p style="text-align:center" id="sentence"><bdo dir="RTL">寒雨连江夜入吴,</bdo></p>  <p style="text-align:center" id="sentence"><bdo dir="RTL">平明送客楚山孤。</bdo></p>  <p style="text-align:center" title="洛阳亲友如相问,"><bdo dir="RTL">洛阳亲友如相问,</bdo></p>  <p style="text-align:center" title="一片冰心在玉壶。"><bdo dir="RTL">一片冰心在玉壶。</bdo></p>  <a href="http://www.diyifanwen.com/sicijianshang/tangshisanbaishou/">更多</a>  <img src="x.jpg" alt="欧美小孩">  <!--accesskey 可以用组合键聚焦-->  <input type="text" name="txt1" value="tab1" accesskey="a" />  <input type="text" name="txt2" value="tab2" accesskey="s" /></body>




data属性 用于存储页面私有数据


<!DOCTYPE html><html lang="zh">  <head>    <meta charset="utf-8">    <meta name="viewport" content="width=device-width, initial-scale=1">    <title>data attributes</title>    <script src="domReady.js"></script>    <script>      myReady(function(){        var btn = document.getElementById('btn');        console.log(btn.dataset.toggle);        console.log(btn.dataset.xxxYyy);      });    </script>  </head>  <body>    <button id="btn" type="button" data-xxx-yyy="abc" data-toggle="modal">Small modal</button>  </body></html>

做移动端放心使用!!!


class!!!!!!重要


<!DOCTYPE html><html lang="zh">  <head>    <meta charset="utf-8">    <meta name="viewport" content="width=device-width, initial-scale=1">    <title>class attributes</title>    <script src="domReady.js"></script>    <script>      var CC = {        getClass: function(ele) {          return ele.className.replace(/\s+/, " ").split(" "); //  \s表示空格 +表示可以匹配一个以上的空格            //把标签中class属性的俩个class名中的若干个空格用一个空格代替 然后依照空格分割        },        hasClass: function(ele, cls) {          return -1 < (" " + ele.className + " ").indexOf(" " + cls + " ");//避免因为空格的问题找不到        },        addClass: function(ele, cls) {          if (!this.hasClass(ele, cls))            ele.className += " " + cls;        },        removeClass: function(ele, cls) {          if (this.hasClass(ele, cls)) {            var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)', "gi");//可以以空格或者直接开头 可以以空格或者直接结尾 gi表示整个字符串查找并且忽略大小写            ele.className = ele.className.replace(reg, " ");//将匹配到的classname用空格替代          }        },        toggleClass: function(ele, cls) {          if (this.hasClass(ele, cls)) {            this.removeClass(ele, cls);          } else {            this.addClass(ele, cls);          }        }      };      myReady(function() {        var body = document.body;          console.log(typeof (body.className));//返回字符串          console.log(CC.getClass(body));        console.log(CC.hasClass(body, 'bbb'));        CC.addClass(body, 'ccc');        CC.removeClass(body, 'aaa');        CC.toggleClass(body, 'bbb');      });    </script>  </head>  <body class="aaa bbb aaa">      TEST  </body></html>





classList

较新的浏览器支持 ie11才支持

<!DOCTYPE html><html lang="zh">  <head>    <meta charset="utf-8">    <meta name="viewport" content="width=device-width, initial-scale=1">    <title>classList</title>    <script src="domReady.js"></script>    <script>      var CL = {        addClass: function(ele, cls) {          ele.classList.add(cls);        },        removeClass: function(ele, cls) {          ele.classList.remove(cls);        },        hasClass: function(ele, cls) {          return ele.classList.contains(cls);        },        toggleClass: function(ele, cls) {          return ele.classList.toggle(cls);        }      };      myReady(function() {        var body = document.body;        console.log(CL.hasClass(body, 'bbb'));        CL.addClass(body, 'ccc');        CL.removeClass(body, 'aaa');        CL.toggleClass(body, 'bbb');        setTimeout(function(){            alert(document.body.classList.toString());        },2000);      });    </script>  </head>  <body class="aaa bbb aaa">      TEST  </body></html>


原创粉丝点击