HTML5规范围绕着如何利用新增标记定义了大量Javascript API;个中一些API与DOM重叠,定义了浏览器该当支持的DOM扩展;

从HTML4开始,在Web开拓领域,有一个非常大的运用,便是滥用class属性,一方面可以通过它为元素添加样式,另一方面还可以用它表示元素的语义;于是,开拓职员会用大量的Javascript代码来操作CSS类,比如动态修正类或者搜索文档中具有给定类或给定的一组类的元素,等等这些操作;为了让开发职员适应并增加对class属性的新的认识,HTML5新增了很多API,致力于简化CSS类的用法;

getElementsByClassName(names)方法:

htmljavascript参数第46节 HTML5扩大Javascript零点法式员 CSS
(图片来自网络侵删)

该方法是基于元素class属性值中的类名来选取成组的文档元素,可以通过document工具或Element元素调用这个方法;该方法最早涌如今第三方Javascript类库中,是通过既有的DOM功能实现的,而现在,原生的实现具有极大的性能上风;

该方法吸收一个names参数,即一个包含一个或多个类名的字符串,多个类名利用空格隔开,返回带有指定类的所有元素的HTMLCollection;

var elts = document.getElementsByClassName("myclass");console.log(elts); // HTMLCollectionconsole.log(elts[0]); // 第一个元素

传入多个类名时,类名的先后顺序不主要;如:

// 取得所有类中同时包括username和current的元素,类名的先后顺序无所谓var allCurrentUsernames = document.getElementsByClassName("username current");console.log(allCurrentUsernames);var selected = document.getElementById("mydiv").getElementsByClassName("selected");console.log(selected);

它返回的HTMLCollection凑集,可以借用Array的方法,如:

var elts = document.getElementsByClassName("selected");var eltDivs = Array.prototype.filter.call(elts, function(ele){ return ele.nodeName === 'DIV';});console.log(eltDivs); // 返回拥有selected类名的所有div元素

利用这个方法可以更方便地为带有某些类的元素添加事宜处理程序,从面不必再局限于利用ID或标署名;

<style>.zr{background-color: rosybrown;}@keyframes rotate{ 0%{transform: rotate(0deg);} 50%{transform: rotate(45deg);} 100%{transform: rotate(0deg);}}.animating{ animation: rotate 2s ease-in-out;}</style><p class="zr">this is ok</p><!-- 添加多少个class为zr的元素 --><script>var elts = document.getElementsByClassName("zr");for(var i=0,len=elts.length; i<len; i++){ elts[i].addEventListener("click",function(e){ this.classList.add("animating"); },false); elts[i].addEventListener("animationend",function(e){ this.classList.remove("animating"); console.log("end"); });}</script>

如此,我们就可以为某些须要实行动画的元素添加一个名为zr的class类即可;当然,此处是一个动画效果,也可以是其他的某些操作;

getElementsByClassName()方法与querySelector()和querySelectorAll()方法很类似,但用法及返回类型不同;

var elts = document.getElementsByClassName("myclass outer");console.log(elts); // HTMLCollectionvar elts = document.querySelectorAll(".myclass,.outer");console.log(elts); // NodeList

getElementsByClassName()参数只能是类名,且多个类名用空格隔开,多个类名是并的关系,而且不分顺序,即只有所有class都匹配的元素才会被返回,其返回类型是HTMLCollection,是动态的凑集;

querySelector()参数是CSS选择器,并且可以利用繁芜的CSS选择器,只假如合法的CSS选择器都可以,但多个选择器必须利用逗号分隔,它们是或的关系,其返回类型是NodeList,并且这个NodeList是静态的;

目前,获取元素凑集共有四个方法,要把稳它们的不同点;

var elts = document.getElementsByClassName("myclass outer");console.log(elts); // HTMLCollectionvar elts = document.getElementsByTagName("div");console.log(elts); // HTMLCollectionvar elts = document.getElementsByName("myname");console.log(elts); // NodeListvar elts = document.querySelectorAll(".myclass,.outer,.current");console.log(elts); // NodeList

其余,须要把稳的是,getElementsByClassName()方法返回的是动态HTMLCollection,以是利用这个方法与利用getElementsByTagName()以及其他返回动态凑集的DOM方法都具有同样的性能问题;

元素滚动:

Element.scrollIntoView(alignToTop | scrollIntoViewOptions)方法:

DOM对滚动页面没有做出规定;各浏览器分别实现了相应的方法,用于以不同办法掌握滚动,终极HTML5选择了scrollIntoView()作为标准方法;

该方法是作为Element类型的扩展存在的,因此可以在所有元素上利用,通过滚动浏览器窗口或某个容器元素,使调用该方法的元素涌如今视口中;

该方法吸收一个布尔值参数alignToTop或Object型(scrollIntoViewOptions)参数,如果为true或者省略,那么窗口会尽可能滚动到自身顶部与元素顶部平齐,如果为false,调用元素会尽可能全部涌如今视口中,不过顶部不一定对齐;

var mybtn = document.getElementById("mybtn");mybtn.onclick = function(){ var img = document.getElementById("myimg"); img.scrollIntoView(false);}

Object型参数scrollIntoViewOptions:一个包含下列属性的工具:

behavior:可选,定义动画过渡效果,"auto"或 "smooth" 之一,默认为 "auto";block:可选,定义垂直方向的对齐,"start", "center", "end", "nearest"之一,默认为 "start";inline:可选,定义水平方向的对齐,"start", "center", "end", "nearest"之一,默认为 "nearest";

img.scrollIntoView({behavior:"smooth",block:"nearest",inline:"center"});

但是IE与Edge对scrollIntoViewOptions这个参数并不友好,比如不支持behavior:”smooth”等;

var btn = document.getElementById("btn");btn.onclick = function(){ var img = document.querySelector("img"); // 以下三行是等同的 img.scrollIntoView(); img.scrollIntoView(true); img.scrollIntoView({behavior:"auto",block:"start"}); // 以下两行是等同的,但IE与Edge彷佛不识别end img.scrollIntoView(false); img.scrollIntoView({behavior:"auto",block:"end"});}

其余,CSS3中有个平滑滚动的属性scroll-behavior,如;

<style> html,body{scroll-behavior: smooth;}</style>

只要页面有滚动行为,自动进行平常处理;但IE与Edge不支持;

当页面发生变革时,一样平常会用这个方法来吸引用户的把稳力;实际上,为某个元素设置焦点也会导致浏览器滚动并显示出得到焦点的元素;

var username = document.getElementById("username");username.focus();

Element.scrollIntoViewIfNeeded()方法:

用来将不在浏览器窗口的可见区域内的元素滚动到浏览器窗口的可见区域,如果该元素已经在浏览器窗口的可见区域内,则不会发生滚动,此方法是标准的Element.scrollIntoView()方法的专有变体,不属于任何规范,是一种WebKit专有的方法;

var btn = document.getElementById("btn");btn.onclick = function(){ var elt = document.getElementById("elt"); elt.scrollIntoViewIfNeeded(true);}

目前,除了Chrome和Opera支持,其他都不支持;

运用的场景:

对URL中hash标记的进化;比如:回到顶部(#);

<a href="javascript:void(0)" id="topA" style="position:fixed;right:50px;bottom:50px;display:block; width:50px;height:50px;background-color:purple;">回到顶部</a><script>// 回到顶部var topA = document.getElementById("topA");topA.onclick = function(){ document.body.scrollIntoView({behavior:"smooth",block:"start"});}</script>

滚动到指定位置(#xxx);

如:一个单页导航的运用;

<style>{margin:0; padding: 0;}html,body{ -ms-overflow-style: none; scrollbar-width: none;}::-webkit-scrollbar{ display: none; }ul,li{list-style-type: none;}header{ position: fixed; top:0; left: 0;; width: 100%; height: 2rem; background-color: rgba(0, 0, 0, .5);}nav ul li{padding: 0 2rem; line-height: 2rem; float: left;}nav ul li a{color:#FFF; text-decoration: none;}section{width: 100%; height: 100vh; box-sizing: border-box; padding: 10%; background-size:cover;}section#banner{background: url(images/1.jpg) no-repeat center; background-size:cover;}section#service{background:url(images/2.jpg) no-repeat center; background-size:cover;}section#contact{background: url(images/3.jpg) no-repeat center; background-size:cover;}footer{ width:100%;height: 2rem; background-color: rgba(0, 0, 0, .8); color:rgba(255, 255, 255, .8); position: fixed; left: 0; bottom: 0;}</style><header> <nav> <ul> <li><a href="dom1.html">首页</a></li> <li><a href="#news" data-name="news">新闻</a></li> <li><a href="#service" data-name="service">做事</a></li> <li><a href="#about" data-name="about">关于</a></li> <li><a href="#contact" data-name="contact">联系</a></li> </ul> </nav></header><section id="banner"> <h2>零点程序员</h2> <h3>zeronetwork</h3></section><section id="news"><h2>新闻中央</h2></section><section id="service"><h2>做事领域</h2></section><section id="about"><h2>关于我们</h2></section><section id="contact"><h2>联系我们</h2></section><footer><p>北京零点网络科技有限公司,www.zeronetwork.cn 零点程序员</p></footer><script>window.onload = function(){ scrollPage(); var navs = document.querySelectorAll("nav a"); for(var i=0,len=navs.length; i<len; i++){ (function(){ var item = navs[i]; item.addEventListener("click",function(event){ event.preventDefault(); scrollPage(event.target.dataset.name); },false); })(); }}function scrollPage(id){ console.log(id); var section = id ? document.querySelector("#" + id) : document.body; section.scrollIntoView({behavior:"smooth",block:"start"});}</script>

谈天窗口滚动显示最新的;

<style>{margin: 0px; padding: 0;}html,body{font-size: 14px;}ul,li{list-style-type: none;}li{margin: 1.5vh 0;}#app{ width: 400px; height: 400px; border: 10px solid purple; position: relative; background-color: rosybrown; padding-bottom: 40px;}#message{ width: 100%; height:100%; padding:15px; padding-bottom: 0; box-sizing: border-box; overflow-y: scroll;}#message ul{padding-bottom: 15px;}#message ul li{display: flex;}#message ul li.me{flex-direction: row-reverse;}#message ul li a{display: inline-block;}#message ul li a img{width: 2vw; height: 2vw; border-radius: 50%;}#message ul li p{ background-color: #FFF; border-radius: 3px; padding:0.5vw; margin:0 3vw 0 1vw;}#message ul li.me p{background-color:#09ce44;margin: 0 1vw 0 3vw;}#inputdiv{ position: absolute; left: 0; bottom: 0; width: 100%; height: 40px; background-color:rgba(0, 0, 0, 1); padding: 5px; box-sizing: border-box; display:flex;}#txtInput{flex-grow: 3;}#btn{flex-grow: 1;}</style><div id="app"> <div id="message"> <ul> <li><a href="#"><img src="images/1.jpg" /></a><p>...</p></li> <li class="me"><a href="#"><img src="images/1.jpg" /></a><p>...</p></li> <li class="me"><a href="#"><img src="images/1.jpg" /></a><p>..</p></li> <li><a href="#"><img src="images/1.jpg" /></a><p>...</p></li> <li class="me"><a href="#"><img src="images/1.jpg" /></a><p>...</p></li> </ul> </div> <div id="inputdiv"><input type="text" id="txtInput" name="txtInput" /> <input type="button" value="发送" id="btn" /></div></div><script>window.onload = function(){ var ul = document.querySelector("#message>ul"); if(navigator.userAgent.indexOf("Trident") != -1){ ul.scrollIntoView(false); }else{ ul.scrollIntoView({behavior:"smooth", block:"end"}); } var btn = document.querySelector("#btn"); btn.addEventListener("click",function(e){ var txtInput = document.querySelector("#txtInput"); if(txtInput.value){ var html = "<li class=\"me\"><a href=\"#\"><img src=\"images/1.jpg\" /></a>"; html += "<p>" + txtInput.value + "</p></li>"; document.querySelector("#message ul").insertAdjacentHTML("beforeend", html); txtInput.value = ""; } if(navigator.userAgent.indexOf("Trident") != -1){ ul.scrollIntoView(false); }else{ ul.scrollIntoView({behavior:"smooth", block:"end"}); } },false);}</script>

焦点管理:

HTML5也添加了赞助管理DOM焦点的功能;

document.activeElement属性:

该属性始终会引用DOM中当前得到了焦点的元素;

元素得到焦点的办法有页面加载、用户输入和在代码中调用focus()方法,如:

console.log(document.activeElement);var btn = document.getElementById("myButton");btn.focus();console.log(document.activeElement === btn); // true

默认情形下,文档刚刚加载完成时,document.activeElement中保存的是document.body元素的引用,文档加载期间,其该属性的值为null;

一样平常情形下,都是在一个表单控件上运用焦点管理,比如,在一个input或textarea上选择文本时,activeElement属性就会返回该元素;

在现实中,该属性在控件中利用时,一样平常会与选择控件中的文本操作合营利用,比如,调用该控件的selectionStart()和selectionEnd()方法来获取选择的文本内容;

<input type="text" id="myinput" value="北京零点网络科技有限公司" /><br/><textarea id="mytextarea" rows="5" cols="40">北京零点网络科技有限公司推出零点程序员品牌,专门从事IT培训,主讲是大师哥王唯。
</textarea><p>得到焦点的元素:<b id="outputelement"></b></p><p>选择的文本:<b id="outputtext"></b></p><script>function selectText(e){ var activeEl = document.activeElement; var selection = activeEl.value.substring( activeEl.selectionStart, activeEl.selectionEnd ); var outputelement = document.getElementById("outputelement"); var outputtext = document.getElementById("outputtext"); outputelement.innerHTML = activeEl.id; outputtext.innerHTML = selection;}var myinput = document.getElementById("myinput");var mytextarea = document.getElementById("mytextarea");myinput.addEventListener("mouseup", selectText,false);mytextarea.addEventListener("mouseup", selectText,false);</script>

小示例:

// 获取焦点的控件自动滚到页面中间window.addEventListener("click",function(e){ var elt = document.activeElement; if(elt.tagName == "INPUT" || elt.tagName == "TEXTAREA") elt.scrollIntoView({behavior:"smooth", inline:"center"});},false);

办理由于窗口缩放、键盘弹出后遮挡表单的问题:

<!-- 按tab切换到input,再缩放窗口大小 --><h1 tabindex="1">Web前端开拓</h1><div style="height: 1000px; background-color: purple;" id="mydiv" tabindex="2">div</div><input type="text" /><script>window.addEventListener("resize",function(e){ if(document.activeElement.tagName === 'INPUT' || document.activeElement.tagName === 'TEXTAREA'){ setTimeout(function(){ document.activeElement.scrollIntoView({behavior:"smooth"}); },100); }});</script>

activeElement属性是只读的,如果想让某个元素获取焦点,可以调用该元素的focus()方法,如:

var myinput = document.getElementById("myinput");document.activeElement = myinput; // 失落效myinput.focus();console.log(document.activeElement); // input

document.hasFocus()方法:

该方法用于表明当前文档或者当前文档内的节点是否得到取焦点,该方法可以用来判断当前文档中的活动元素是否得到了焦点,如:

console.log(document.hasFocus());

当查看一个文档时,当前文档中得到焦点的元素一定是当前文档的活动元素,但一个文档中的活动元素不一定得到了焦点,例如,一个在后台窗口中的活动元素一定没有得到焦点;

通过检测文档是否得到了焦点,可以知道用户是不是正在与页面交互;

<input id="btn" type="button" value="打开窗口" /><br/><script>function openWin(){ window.open("about:blank","newwin","width=400,height=300");}var btn = document.getElementById("btn");btn.addEventListener("click", openWin, false);function checkPageFocus(){ if(document.hasFocus()) console.log("该页面得到了焦点"); else console.log("该页面失落去了焦点");}setInterval(checkPageFocus, 1000);</script>

查询文档获知哪个元素得到了焦点,以及确定文档是否得到了焦点,这两个功能最主要的用场是提高Web运用的无障碍性;无障碍Web运用的一个紧张标志便是恰当的焦点管理,而确切地知道哪个元素得到了焦点是一个比较主要的操作;

HTMLDocument的增强:

HTML5扩展了HTMLDocument,增加了新的功能;

document.readyState属性:

该属性描述了document 的加载状态,当该属性值发生变革时,会在 document 工具上触发 readystatechange事宜;

IE4最早为document工具引入了readyState属性,然后,其他浏览器也都陆续实现了这个属性,终极HTML5把这个属性纳入了标准之中。

该属性有三个可能的值:

loading:正在加载文档;interactive:可交互的,文档已被解析,"正在加载"状态结束,但是诸如图像,样式表和框架之类的资源仍在加载;complete:文档和所有资源已完成加载,表示load状态的事宜即将被触发;

console.log(document.readyState); // loading

为什么要利用document.readyState属性?目的便是通过它来实现一个指示文档已经加载完成的指示器;在这个属性没有得到广泛支持前,要实现这样的一个指示器,必须借助onload事宜处理程序,表明文档已经加载完毕;

window.onload = function(){ console.log("文档加载完毕") console.log(document.readyState); // complete}现在可以直策应用document.readyState属性来判断,如:// 不会被实行,由于代码运行到此处,readySate状态为loadingif(document.readyState == "complete"){ console.log("文档已加载完毕"); console.log(document.readyState);}

但并没有实行,由于代码实行到此处,readyState的状态为loading,而后它又不能自己更新,以是要实时的取得readyState的状态;当该属性值发生变革时,会在 document 工具上触发 readystatechange事宜,以是利用该事宜就可以实时监听它的状态;

document.onreadystatechange = function(e) { // if(document.readyState == "loading"){ // console.log("Loading"); // }else if(document.readyState == "interactive"){ // var span = document.createElement("span"); // span.textContent = "资源正在加载"; // document.body.appendChild(span); // console.log("Interactive"); // }else if(document.readyState == "complete"){ // var span = document.querySelector("span"); // document.body.removeChild(span); // console.log("Complete"); // } // 或者 switch(document.readyState){ case "loading": console.log("Loading"); break; case "interactive": // 文档已经结束了“正在加载”状态,DOM元素可以被访问。
// 但是像图像,样式表和框架等资源依然还在加载。
var span = document.createElement("span"); span.textContent = "资源正在加载"; document.body.appendChild(span); console.log("Interactive"); break; case "complete": // 页面所有内容都已被完备加载 var img = document.getElementsByTagName("img")[0]; console.log("图片等资源加载完成:" + img.src); break; }}

一个大略小示例,loading页

<style>{margin: 0; padding: 0;}#loading{ width: 100vw; height: 100vh; background-color: rgba(0, 0, 0, .6); position: absolute; top: 0; left: 0;}@keyframes rotate{ 0%{transform: rotate(0deg);} 100%{transform: rotate(360deg);}}#loading img{ width: 5vw; position: absolute; left: 50%; top:50%; margin-left: -5vw; margin-top:-5vh; animation: rotate 1s linear infinite; / [ˈɪnfɪnət] /}#loading.loading-none{display: none;}</style><div id="loading"><img src="images/loading.png" /></div><script>document.onreadystatechange = function(e) { if(document.readyState == "complete") document.getElementById("loading").className = "loading-none"; else document.getElementById("loading").className = ""}</script>

compatMode兼容模式:

页面的渲染有两种办法,Standards mode标准模式和Quirks mode殽杂模式(也称为怪异模式);

这两种模式紧张影响CSS内容的呈现,某些情形下也会影响JavaScript的实行;以是,在开拓时,确定浏览器处于何种模式很主要;

起初,是从IE6开始区分渲染页面的模式是Standards mode还是Quirks mode;IE为此给document工具添加一个名为compatMode属性,该属性即用于识别浏览器处于什么模式;如果是标准模式,返回CSS1Compat,反之返回BackCompat;后来,其他浏览器也实现了这个属性,终极HTML5也把这个属性纳入标准;

console.log(document.compatMode); // CSS1Compat

目前,存在以下几种情形:

浏览器都是根据是否有DOCTYPE声明判断,有则为标准模式,值为CSS1Compact,无则为殽杂模式,值为BackCompact;因此,一条好习气便是每个html文档都要有doctype声明;

对付有DOCTYPE声明,但浏览器不能精确识别,则利用殽杂模式,值为BackCompact;

如果有xml声明 <?xml version="1.0" encoding="utf-8"?>也是殽杂模式;

其余,如果文档的第一行是标签或文本,也为殽杂模式;

对付IE来说,这两种模式差别很大,但对其他浏览器来说,差别很小,因此,这两种模式的判断和差别紧张是针对IE;

两种模式的详细差别:

在Standards Mode下对付盒模型的阐明所有浏览器都是基本同等的,但在Quirks Mode模式下则有很大差别;

在Standards mode中:

元素真正的宽度 = margin + border-width + padding + width;

在Quirks mode中:

元素真正的宽度 = width,而其内容宽度 = width - (margin – padding - border-width);

在标准模式下,所有尺寸都必须包含单位,否则会被忽略,而在殽杂模式下,可以不带单位,如:style.width = "20",相称于"20px";

当一个div元素中包含的内容只有图片时,在标准模式下的所有浏览器中,在图片底部都有4像素的空缺;但在殽杂模式下,div距图片底部默认没有空缺;

两种模式获取视口的办法是不同的;

console.log(document.body.clientHeight);console.log(document.documentElement.clientHeight);

便是说,在BackCompact模式下,取得document的某些属性,如clientWidth、scrollLeft等,利用的是document.body,而标准模式下,利用的是document.documentElement,如:

var height = document.compatMode == "CSS1Compat" ? document.documentElement.clientHeight : document.body.clientHeight;console.log(height);

documentMode文档模式:

IE8为document工具添加了documentMode属性,即文档模式(document mode),该属性与compatMode属性紧密干系,但该属性不是标准属性,除了IE,其它浏览器都不支持;

console.log(document.documentMode); // 11

页面的文档模式决定了可以利用什么功能,如,文档模式决定了可以利用哪个级别的CSS,可以在Javascript中利用哪些API,以及如何对待文档类型;

在IE8中,有三种不同的呈现模式:

为5,则为殽杂模式(IE5),IE8或更高版本中的新功能无法利用;为7,表示IE7仿真模式,IE8或更高版本中的新功能无法利用;为8,表示IE8标准模式,IE8中的新功能都可以利用,如可以利用Selectors API,更多CSS2级选择器和某些CSS3功能,还有一些HTML5的功能;不过IE9中的新功能无法利用;

从IE8今后,都遵照了这一规律,比如,为9,表示IE9标准模式,支持ES5,CSS3和更多HTML5的功能;

有了这个属性,就能准确的判断IE的各种版本了,如:

var isIE = !!(window.ActiveXObject || "ActiveXObject" in window);var ieMode = document.documentMode;var isIE7 = isIE && ieMode && ieMode == 7;var isIE8 = isIE && ieMode && ieMode == 8;var isIE9 = isIE && ieMode && ieMode == 9;var isIE10 = isIE && ieMode && ieMode == 10;console.log(isIE); // trueconsole.log(isIE10); // 切换到10版本,返回true

X-UA-Compatible:

开拓者还可以主动哀求客户端按照什么文档模式进行渲染,也便是逼迫浏览器以某种模式渲染页面,此时可以利用HTTP头部信息X-UA-Compatible,或通过等价的<meta>标签来设置:

<meta http-equiv="X-UA-Compatible" content="IE=IEVersion">

IEVersion有可能有以下值:

Edge:始终以最新的文档模式来渲染页面;忽略文档类型声明;EmulateIE9(8、7):如果有文档声明,则以IE9(8、7)标准模式渲染页面,否则将文档模式设置为IE5;9、8、7、5:逼迫以IE9(8、7、IE5模式)标准模式渲染页面,忽略文档类型声明;

如:让文档模式像在IE7中一样,可以:

<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">

如果不考虑文档类型声明,而直策应用IE8标准模式,可以:

<meta http-equiv="X-UA-Compatible" content="IE=8">

再如,逼迫以IE5殽杂模式渲染:

<meta http-equiv="X-UA-Compatible" content="IE=5" />

如果在IE8以下的浏览器中设置,是无效的,由于该设置是在IE8才开始有的;

利用最新的文档模式:

<meta http-equiv="X-UA-Compatible" content="IE=edge"/>

IE浏览器将总是利用最新版本的文档模式;

其余,也可以同时设置多个值,中间用逗号隔开;

<meta http-equiv="X-UA-Compatible" content="IE=IEVersion">

把稳,由右向左进行考试测验,即先利用IE8模式,如果失落败,则利用IE模式;

最盛行的设置:

<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>

chrome=1表示可以激活Chrome Frame;

如果安装了Google Chrome Frame(谷歌浏览器內嵌框架)则利用谷歌浏览器内核模式,乃至会利用Chrome的掌握台,否则利用最新的IE模式;

head属性:

在HTML5规范中新增了document.head属性,引用文档的<head>元素,属于HTMLHeadElement类型;

console.log(document.head);console.log(document.head === document.querySelector("head"));

各主流浏览器均支持,但为了兼容低版本的,也可以结合备用办法,如:

var head = document.head || document.getElementsByTagName("head")[0];

如果有多个<head>元素,则返回第一个;

document.head 是个只读属性,为该属性赋值只会静默失落败,如果在严格模式中,则会抛出TypeError非常;

字符集属性:

HTML5新增了几个与文档字符集有关的属性,个中,charset属性表示实际利用的字符集,也可以用来指定新字符集;可以通过<meta>元素、相应头部或直接设置charset属性修正这个值,但实际上是只读的,现在已经被characterSet替代,该属性是只读属性,返回当前文档的字符编码,该字符编码是用于渲染此文档的字符集,如:

console.log(document.charset); // UTF-8

此时,可以修正文档的字符集设置,如:

// IE与老版的Edge返回gb2312,其它默认失落败document.charset = "gbk";console.log(document.charset); // UTF-8console.log(document.characterSet);// 同上,但所有浏览器静默失落败document.characterSet = "gbk";console.log(document.characterSet);

另一个属性是defaultCharset,表示根据默认浏览器及操作系统的设置,当前文档默认的字符集该当是什么,该属性不是标准属性,没什么用途;

console.log(document.defaultCharset); // 只有IE与Safari有值

data-自定义数据属性:

HTML5定义了一种标准的、附加额外数据的方法,即在HTML5文档中,任意以”data-”为前缀的小写的属性名称都是合法的,这样的属性被称为数据集属性,目的是为元素供应与渲染无关的信息,或者供应语义信息;这些属性可以任意添加、随便命名,只要以data-开头即可,如:

<div id="mydiv" data-appId="1234" data-myname="wangwei"></div>

HTMLElement.dataset属性:

在Javascript中也为Element工具上定义了dataset属性,该属性指代一个工具,是元素的data-特性的实时、双向的接口;

dataset属性的值是DOMStringMap接口的一个实例,被用于容纳和展示元素的自定义属(特)性,它便是一个名值对的映射,在这个映命中,每个data-name形式的属性都会有一个对应的属(特)性,只不过属性名没有data-前缀,比如,dataset.x保存的便是data-x属(特)性的值;带连字符的属(特)性对应于驼峰命名属性名,如:data-web-test属(特)性就变成dataset.webTest属性;如:

<div id="mydiv" data-appId="001" data-subtitle="zeronetwork" data-web-description="零点程序员"> // Javascriptvar mydiv = document.getElementById("mydiv");console.log(mydiv.dataset); // DOMStringMapconsole.log(mydiv.dataset.subtitle); // zeronetworkconsole.log(mydiv.dataset.webDescription); // 零点程序员console.log(mydiv.dataset.appid); // 只能小写,不能是appId

设置或删除dataset的一个属性就等同于设置或移除对应元素的data-属(特)性,并且在将键值转换为一个属性的名称时会利用相反的转换;

// 判断有没有该属性if(mydiv.dataset.myname){ console.log(mydiv.dataset.myname);}mydiv.dataset.subtitle = "wangwei"; // 修正mydiv.dataset.imgurl = "images/1.jpg"; // 添加mydiv.dataset.userName = "wangwei"; // 添加,被转换为data-user-namedelete mydiv.dataset.subtitle; // 删除遍历DOMStringMap工具;for(var k in mydiv.dataset){ console.log(k + ":" + mydiv.dataset[k]);}

与getAttribute()和setAttribute()比较:

在效率上,dataset没有上述两个方法高,但是,这个影响可以忽略不计;从操作上来看,虽然利用dataset不能提高代码的性能,但是对付简洁代码,提高代码的可读性和可掩护性是很有帮助的,如:

<div class="user" data-id="123" data-user-name="wangwei" data-sex="男" data-date-of-birth="1998/8/8"></div><div class="user" data-id="124" data-user-name="jingjing" data-sex="女" data-date-of-birth></div><div class="user" data-id="125" data-user-name="juanjuan" data-sex="女" data-date-of-birth="1995/5/5"></div><script>var users = document.querySelectorAll(".user");// 利用getAttribute()和setAttribute()for(var i=0,len=users.length; i<len; i++){ var user = users[i]; var id = user.getAttribute("data-id"); var username = user.getAttribute("data-user-name"); var sex = user.getAttribute("data-sex"); if(!user.getAttribute("data-date-of-birth")) // user.setAttribute("data-date-of-birth","2020-1-1"); var dateofbirth = user.getAttribute("data-date-of-birth"); console.log("ID:" + id + ",username:" + username + ",sex:" + sex + ",dateofbirth:" + dateofbirth);}// 利用datasetfor(var i=0,len=users.length; i<len; i++){ var user = users[i]; var id = user.dataset.id; var username = user.dataset.userName; var sex = user.dataset.sex; if(!user.dataset.dateOfBirth) user.dataset.dateOfBirth = "2020/1/1"; var dateofbirth = user.dataset.dateOfBirth; console.log("ID:" + id + ",username:" + username + ",sex:" + sex + ",dateofbirth:" + dateofbirth);}</script>

其余,dataset属性在IE中,只有IE11支持,以是在低版本的IE中,如果要利用dataset属性,必须做兼容性处理;

if(mydiv.dataset){ console.log(mydiv.dataset.subtitle); console.log(mydiv.dataset.webDescription);}else{ console.log(mydiv.getAttribute("data-subtitle")); console.log(mydiv.getAttribute("data-web-description"));}// 封装一个函数function getDataset(elt){ if(elt.dataset) return elt.dataset; var attrs = elt.attributes, // 元素的属性凑集 dataset = {}, // 包装的一个属性集工具 name, // 要获取的特性名 matchStr; // 匹配结果 for(var i=0, len = attrs.length; i<len; i++){ // 匹配data-自定义属性 matchStr = attrs[i].name.match(/^data-(.+)/); if(matchStr){ // 转成小驼峰 name = matchStr[1].replace(/-([\da-z])/gi, function(all, letter){ return letter.toUpperCase(); }); dataset[name] = attrs[i].value; } } return dataset;}var dataset = getDataset(mydiv);console.log(dataset);

其余data-属性并不是只在Javascript中利用,在CSS中运用的场景大概多,如:

<style>p[data-font-size='2em']{font-size: 2em;}p[data-font-size='3em']{font-size: 3em;}</style><p data-font-size="3em">零点程序员</p><p data-font-size="2em">王唯</p>// 又如<style>#mydiv::after{background-color: rgba(0,0,0,.2); content: attr(data-content);}</style><div id="mydiv" data-content="王唯是年夜大好人">大师哥</div>

dataset运用的场景还是非常多的,一样平常来说,为了给元素添加一些不可见的数据,并要进行后续的处理,就可以用到自定义数据属性;比如,合营CSS开拓一些动画效果,或在跟踪链接等运用中,通过自定义数据属性能方便地知道点击来自页面中的哪个部分;

<a href="https://www.zeronetwork.cn" data-title="零点网络">零点网络</a><script>window.onload = function(){ var aElts = document.querySelectorAll("a"); for(var i=0,len=aElts.length; i<len; i++){ aElts[i].addEventListener("click",function(e){ e.preventDefault(); doDataset(this); },false); } var aDataset = []; function doDataset(elt){ var o = {title:elt.dataset.title, href:elt.href, page:location.pathname}; aDataset.push(o); console.log(aDataset); }}</script>// 小示例<style>.banner{ background:url("images/2.jpg") no-repeat center; background-size:cover;}.fadeInDown{opacity: 0; transform: translateY(20px);}</style><div class="banner"> <h2 class="fadeInDown" data-duration=".8" data-delay="400">零点程序员</h2> <h3 class="fadeInDown" data-duration="1" data-delay="800">大师哥王唯</h3> <p class="fadeInDown" data-duration="1" data-delay="1000"><a href="#">更多</a></p></div><script>window.onload = function(){ var elts = document.getElementsByClassName("fadeInDown"); // for(var i=0,len=elts.length; i<len; i++){ // (function(){ // var elt = elts[i]; // var dataset = elt.dataset; // setTimeout(function(){ // elt.style.opacity = 1; // elt.style.transform = "translateY(-20px)"; // elt.style.transition = "all " + dataset.duration + "s linear"; // }, dataset.delay); // })(); // } Array.prototype.forEach.call(elts, function(v,k){ console.log(v); var dataset = v.dataset; setTimeout(function(){ v.style.opacity = 1; v.style.transform = "translateY(-10px)"; v.style.transition = "all " + dataset.duration + "s linear"; }, dataset.delay); });}</script>

Web前端开拓之Javascript