HTML5
HTML5规范围绕如何使用新增标记定义了大量JavaScriptAPI。其中一些API与DOM重叠,定义了浏览器应该支持的DOM扩展。
与类相关的扩充
HTML5 新增了很多API,致力于简化CSS类的用法。
- getElementsByClassName()方法
通过document对象及所有HTML元素调用该方法,接受一个参数:一个包含类名的字符串,返回带有指定累的所有元素的NodeList。
// 取得所有类中包含"username"和"current"的元素
var allCurrentUsernames = document.getElementsByClassName("username current");
//取得ID为"myDiv"的元素中带有类名"selected"的所有元素
var selected = document.getElementById("myDiv").getElementByClassName("selected");
因返回的对象是NodeList,所以存在于getElementByTagName()以及其他返回NodeList的DOM方法都具有相同的性能问题。
- classList属性
在操作类名时,需要通过className属性添加、删除和替换类名。因此className中是一个字符串,及时修改字符串一部分,也必须每次都设置整个字符串:
<div class = "bd user disabled">...</div>
该元素共三个类名,要删除其中一个,需要把类名拆开,删除不想要的类名,再把其他类名拼成一个新字符串。
//删除"user"类
//首先,取得类名字符串并拆分成数组
var classNames = div.className.split(/\s+/);
//找到要删的类名
var pos = -1,
i,
len;
for (i = 0, len = classNames.length; i < len; i++){
if (className[i] == "user"){
pos = i
break;
}
}
//删除类名
classNames.splice(i,1);
//把剩下的类名拼成字符串并重新设置
div.className = classNames.join("");
HTML5新增了种操作类名的方式,为所元素添加了classList属性。
classList属性是新集合类型DOMTokenList的实例。
DOMTokenList有length属性,取得每个元素使用item()方法和’[]’
add(value) | 将给定字符串值添加到列表中 |
---|---|
contains(value) | 表示列表中是否存在给定的值(布尔值) |
remove(value) | 从列表中定字符串 |
toggle(value) | 如果列表中存在给定的值,删除它;如果列表中不用存在给定的值,添加它 |
//删除“disabled”类
div.classList.remove (disabled);
//添加“current”类
div.classList.add("current");
//切换“user”类
div.classList.toggle("current");
// 确定元素中是否包含既定的类名
if (div .classList.contains("bd") && !div.classList.contains("disabled")){
//执行操作
}
//类名迭代
for (var i = 0, len = div.classList.length; i < len ; i++){
doSomething(div.classList[i]);
}
支持classList属性的浏览器有Firefox3.6+和Chrome
- 焦点管理
HTML5添加了辅助管理DOM焦点的功能:document.activeElement属性,始终引用DOM中当前获得了焦点的元素。
元素获得焦点的方式有页面加载、用户输入(通常是通过TAB键)和在代码中调用focus()方法:
var button = document.getElementById("myBotton");
//赋予焦点
button.focus();
alert{document.activeElement === button}
<script type="text/javascript">
function setFocus()
{
//获得焦点
document.getElementById('check1').focus()
}
function loseFocus()
{
//移除焦点
document.getElementById('check1').blur()
}
</script>
<form>
<input type="checkbox" id="check1" />
<br />
<input type="button" onclick="setFocus()" value="Set focus" />
<input type="button" onclick="loseFocus()" value="Lose focus" />
</form>
document.hasFocus()方法
用于确定文档是否获得了焦点
var button = document.getElementById("myButton");
button.focus();
alert(document.hasFocus); //true
通过检测文档是否获得了焦点,可以知道用户是不是正在和页面交互。
通过确定用户是否获得焦点,可以提高Web应用的无障碍性,确切的知道哪个元素获得焦点。
- HTMLDocument的变化
HTML5扩展了HTMLDocument:
readyState属性 | loading(正在加载文档);complete(已经加载完成) |
---|---|
compatMode属性(兼容模式) | 告知开发人员浏览器采用何种渲染模式.标准模式下等于“CSS1Compat”;混合模式下等于”BackCompat” |
head属性 | 对document.body引用文档的<body> 元素的补充 |
5. 字符集属性
HTML5新增了与文档字符集有关的属性:
charset属性 | 表示文档中实际使用的字符集,或指定新字符集。默认值为“UTF-16”;通过<meta> 元素响应头部或直接设置charset属性修改值 |
---|---|
defaultCharset | 表示根据浏览器及操作系统的设置,当前文档默认的字符集是什么。如果文档未使用默认的字符集charset和defaultCharset可能会不同 |
6. 自定义数据属性
HTML5规定可以为元素添加非标准的属性。但要添加data-,目的是为元素提共与渲染无关的信息。
<div id = "myDiv" data-appId = "12345" data-myname = "Nicholas"></div>
通过元素的dataset属性来访问自定义属性的值,dataset属性的值是DOMStringMap的一个实例,也就是一个键值对。每个data-name形式的属性都会有一个对应的属性,只不过属性名没哟data-前缀(比如,自定义属性是data-myname,在映射中对应的属性是myname):
//本例中使用的方法就用于演示
var div = document.getElementById("myDiv");
//取得自定义属性的值
var appId = div.dataset.appId ;
var myName = div.dataset.myname;
//设置值
div.dataset.appId = 23456;
div.dataset.myname = "Michael";
//有没有"myname"值?
if (div.dataset.myname){
`alert("Hello," + div.dataset.myname);
}
给元素添加一些不可见的数据以便处理,就需要用到自定义数据属性,在跟踪连或混搭应用中,通过自定义数据属性能方便的知道点击页面来自哪个部分。
支持浏览器:Firefox6+和Chrome
- 插入标记
innerHTML属性:返回与调用元素的所有子节点对应的HTML标记。
innerHTML会根据指定的只创建新的DOM树。然后用这个DOM树完全替换调用元素原先的子节点:
<div id = content>
<p>This is a <strong>paragraph</strong>with a list following it.</p>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
innerHTML属性返回的字符串:
<p>This is a <strong>paragraph</strong>with a list following it.</p>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
IE和Opera会将所有标签转化为大写形式,而Safari、Chrome、Firefox则会按照原先文档中的格式返回HTML,包括空格和缩进。
在写模式下,innerHTML的值会被解析为DOM子树,替换调用元素原来的所有子节点:
div.innerHTML = "Hello & welcome, <b>\"reader\"!</b>";
//得到结果
//设置了innerHTML之后,可以像访问文档中的其他节点一样访问新厂家呢的节点。
<div id = "content">Hello & welcome, <b>&quto;reader"!</b></div>
outerHTML属性:返回调用它的元素及所有子节点的HTML标签。
outerHTML会根据指定的HTML字符串创建新的DOM子树,然后用这个DOM子树完全替换调用元素。
<div id = content>
<p>This is a <strong>paragraph</strong>with a list following it.</p>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
调用<div>
元素上调用outerHTML,返回与使用innerHTML属性时存在差异性质。
div.outerHTML = "<p>this is a paragraph.</p>";
这行代码完成的操作与下面这些DOM脚本代码一样:
var p = document.createElement("p");
p.appendChild(document.createTextNode("this is a paragraph."));
div.parentNode.replaceChild(p, div);
新创建的<p>
元素回取代DOM树中的<div>
元素。
insertAdjacentHTML()方法
插入标记的最后一个新增方式是insertAdjacentHTML()方法。这个方法最早也是在IE中出现的,接受两个参数:插入位置和要插入的HTML文本。
第一个参数必须是下列值之一:
deforebegin | 在当前元素之前插入一个紧邻的同辈元素 |
---|---|
afterbegin | 在当前元素之下插入一个新的子元素或在第一个子元素之前再插入新的子元素 |
beforeend | 在当前元素之下插入一个新的子元素或在最后一个子元素之后再插入新的子元素 |
afterend | 在当前元素之后插入一个紧邻的同辈元素 |
//作为前一个同辈元素插入
element.insertAdjacentHTML("beforebegin", "<p>Hello world</p>");
//作为第一个子元素插入
element.insertAdjacentHTML("afterbegin", "<p>Hello world</p>");
//作为最后一个子元素插入
element.insertAdjacentHTML("beforeend", "<p>Hello world</p>");
//作为后一个同辈元素插入
element.insertAdjacentHTML("afterend", "<p>Hello world</p>");
内存和性能问题
替换子节点可能会导致浏览器的内存占用问题,在删除带有事件处理程序或引用了其他JavaScript对象子树是,就有可能导致内存占用问题。
假设某个元素有一个事件处理程序(或者引用了一个JavaScript对象作为属性),在使用前述某个属性将该元素从文档树中删除后,元素与事件处理程序(或JavaScript对象)之间的绑定关系在内存中并没有一并删除,会导致页面占用的内存数量就会明显增加。
因此在使用innerHTML、outerHTML属性和insertAdjacentHTML()方法时,最好手工删除要被替换的元素的所有事件处理程序和JavaScript对象属性。
在设置innerHTML或outerHTML时,就会创建一个HTML解析器。创建和销毁HTML解析器也会带来性能损失,所以innerHTML或outerHTML设置的次数控制在合理的范围内。
for (var i = 0, len = values.length; i < len; i++){
//要避免这种频繁操作
ul.innerHTML += "<li>" + values[i] + "</li>";
}
var itemHTML = "";
//单独构建字符串,再一次性将结果字符串赋值给innerHTML
for (var i = 0, len = values.length; i < len; i++){
itemHTML += "<li>" + values[i] + "</li>";
}
ul.innerHTML= itemHTML ;
- scrollIntoView()方法
HTML5通过规定scrollIntoView()方法,控制滚动页面。
scrollIntoView(“布尔值”)
true:调用元素出现在视口中,调用元素的顶部与视口顶部平齐;
false:调用元素出现在视口中,调用元素的底部与视口底部平齐;
<a onClick="onc()">dasdasd</a>
<div style="width:400px; height:400px; border: 1px solid #f00;"></div>
<div id="nn" style="border:1px solid #666">
<div style="height:900px;">sadasdasd</div>
</div>
<script type="text/javascript">
//作为一个事件的函数来被调用
function onc () {
var dd = document.getElementById("nn").scrollIntoView(true);
//这个意思其实就是将这个元素到顶部来浏览器窗口的顶部来显示
}
</script>