JS学习10(DOM扩展)

选择符API

这个API存在的主要目的就是让JS原生支持CSS查询。

querySelector()

这个方法接收一个CSS选择符,返回与该模式匹配的第一个元素或null。

var body = document.querySelector("body");

querySelectorAll()

这个方法同样接收一个CSS选择符,以静态NodeList的形式返回所有匹配的元素。

var strongs = document.querySelectorAll("p strong");
strong = strongs[i];
strong = strongs.item(i);

matchesSelector()

接收一个CSS选择符,并返回调用元素与该选择符是否匹配。

if (document.body.matchesSelector("body.page1")){
    //true
}

元素遍历

由于空白text类型节点的问题,childNodes里面会包含空的文本节点。这导致遍历元素很不方便。于是有了这几个属性,它们都只返回真正的元素:

  • childElementCount
  • firstElementChild
  • lastElementChild
  • previousElementSibling
  • nextElementSibling

这样一来遍历元素就不用判断节点类型了:

var i, 
    len,
    child = element.firstElementChild;
while(child != element.lastElementChild){
    processChild(child);     
    child = child.nextElementSibling;
}

HTML5

与类相关的扩充

getElementsByClassName()
接收一个或多个类名,返回动态NodeList。

var selected = document.getElementById("myDiv").getElementsByClassName("username current");

classList
这个是便于大家添加,删除类名的,之前使用className属性获得的是一个字符串,每次要改变都得找出要改的那个,删除或改变,再拼出新的字符串。有了这个属性就方便多了。
classList是新的类型DOMTokenList的实例。提供了4个方法:

  • add(value)
  • contains(value)
  • remove(value)
  • toggle(value) 如果存在就删除,不存在就添加
div.classList.add("current");
div.classList.toggle("user");
div.classList.remove("user");
if (div.classList.contains("bd")) {

}

焦点管理

添加了document.activeElement属性,这个属性始终引用DOM中当前获得焦点的元素。默认情况下,当文档刚刚加载完成时,这里面保存的是body元素,加载过程中是null。
添加了document.hasFocus()方法,用于确定元素是否获得焦点。

var button = document.getElementById("myButton");
button.focus();
alert(document.activeElement === button);   //true
alert(document.hasFocus());  //true

HTMLDocument的变化

readyState属性
指示文档是否加载完成,有两个可能的值:loading和complete。

if (document.readyState == "complete"){    
}

兼容模式
区分渲染页面的模式是标准的还是混杂的。属性为document.compatMode。标准模式时值为CSS1Compat,混杂模式时为BackCompat。

if (document.compatMode == "CSS1Compat"){
    alert("Standards mode");
} else {
    alert("Quirks mode");
}

head属性
像body一样可以直接访问了document.head。

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

字符集属性

HTML5新增了几个与文档字符集有关的属性
charset表示文档中实际使用的字符集,默认为UTF-16,可以通过

<meta charset="UTF-8">

来设置,或者响应头部,或者在JS中直接设置这个属性。

alert(document.charset);
alert(document.defaultCharset);

另一个属性是defaultCharset,代表根据默认浏览器设置,字符集应该是什么。

自定义数据属性

使用data-加自定义名,可以定义自己的节点特性,在JS里使用dataset访问,这个属性的值是一个DOMStringMap的一个实例,也就是一个键值对的映射。访问时不用带data-前缀。

var div = document.getElementById("myDiv");
var appId = div.dataset.appId;
var myName = div.dataset.myname;
div.dataset.appId = 23456;
div.dataset.myname = "Michael";
alert(div.dataset.myname);
alert(div.dataset.appId);
//就算原来没有写在DOM里的也可以设置,会同步到DOM里
div.dataset.haha = "hahaha";
alert(div.dataset.haha);

插入标记

使用插入标记,可以直接插入HTML字符串来构建DOM树。
innerHTML
在读模式下,返回与调用元素所有子节点对应的HTML标记的字符串。
在写模式下则会根据指定的值创建新的DOM树,然后替换调用元素所有子节点。

alert(document.body.innerHTML);
var div = document.getElementById("myDiv");
div.innerHTML = "<p>balalala</p><button>balalala</button>";

虽然绝大部分浏览器不支持在innerHTML中添加script节点,但是IE8是支持的,虽然有些特殊,要插入在有作用域的元素后。而且通过onclick等事件插入可执行的代码也是可能的。所以为了安全,在使用innerHTML时一定要注意安全。
style元素是被支持的。在IE8中有些特殊,要插入在有作用域的元素后。

//style元素是被支持的。在IE8中有些特殊,要插入在有作用域的元素后。
//失败
div.innerHTML = "<style type=\"text/css\">body {background-color: red; }</style>";
//成功
div.innerHTML = "_<style type=\"text/css\">body {background-color: red; }</style>";
//成功
div.innerHTML = "<input type=\"hidden\"><style type=\"text/css\">body {background-color: red; }</style>";

outerHTML
这个就是不止替换子元素,调用元素本身也被替换。
insertAdjacentHTML()
这个方法是在指定位置插入HTML文本,可以指定的位置有4个:

  • before begin:在当前元素之前插入一个同辈元素
  • after begin:插入在当前元素的所有子元素之前,作为当前元素的子元素
  • beforeend:插入在当前元素的所有子元素之后,作为当前元素的子元素
  • afterend:在当前元素之后插入一个同辈元素
element.insertAdjacentHTML("afterend", "<p>Hello world!</p>");

内存与性能问题
在使用这个几个方法替换节点时,节点如果有一个事件处理程序或者引用了其他对象作为属性,这些东西可能还在内存中。所以最好先手动删除这些。
不过在插入新元素时,这个方法不管在编写上还是执行上都比我们使用DOM操作要高效的多,在执行这个方法时会创建一个HTML解析器,这个通常时浏览器级别的C++代码。
但是创建和销毁HTML解析器是要开销的,所以尽量减少调用次数,将字符串一次拼好在调用。

scrollIntoView()

div.scrollIntoView();
这个就是让屏幕滚动到这个元素所在的位置让大家能看见。传入true则尽量元素顶部与屏幕平齐,传入false则尽量多显示元素。
把当前元素设置为焦点也可以达到这个效果。

专有拓展

这些都是各个浏览器自己实现的,有的很普遍,有的很不普适。

文档模式

决定了可以使用什么功能,IE5,IE7,IE9等。
可以强制浏览器以什么方式渲染,通过HTTP头部的 X-UA-Compatible或meta标签。

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

其中IEVersion可以是Edge、EmulateIE9、EmulateIE8、EmulateIE7、9、8、7、5。
JS里也可以获取,IE中才有貌似。

var mode = document.documentMode;

children属性

只返回元素子节点,没有乱七八糟的文本节点

var childCount = element.children.length;

contains()方法

一个节点是不是另一个的后代

alert(document.documentElement.contains(document.body)); //true

插入文本

innerText

<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>

对content使用innerText读:

This is a paragraph with a list following it.
Item 1
Item 2
Item 3

写的话就覆盖所有子节点,且会进行HTML编码去掉HTML标签避免生成多个节点。这个可以用来过滤用户输入哦。
有的浏览器不支持这个,但是支持textContent。

function getInnerText(element){
    return (typeof element.textContent == "string") ?
        element.textContent : element.innerText;
}
function setInnerText(element, text){
    if (typeof element.textContent == "string"){
        element.textContent = text;
    } else {
        element.innerText = text;
    }
}

outerText
读时与innerText一样,写时覆盖调用节点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值