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一样,写时覆盖调用节点。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,580评论 18 139
  • Class 学过Java的小伙伴会发现, 这个class和Java里的class基本语法并没有什么区别... 下面...
    刘翾阅读 962评论 2 2
  • 月底的时候,由于店里员工越来越多,原先的宿舍已经无法容纳更多的人了,于是我们被迫换宿舍。 听到这个消息的时候,我正...
    素墨wz阅读 233评论 0 0