最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 红宝书之第十五章:DOM扩展

    正文概述 掘金(梁少杰)   2021-01-03   459

    Selectors API

    querySelector()

    querySelector()方法接收 CSS 选择符参数,返回匹配该模式的第一个后代元素,如果没有匹配项则返回 null。下面是一些例子:

    // 取得<body>元素
    let body = document.querySelector("body"); 
    // 取得 ID 为"myDiv"的元素
    let myDiv = document.querySelector("#myDiv");
    // 取得类名为"selected"的第一个元素
    let selected = document.querySelector(".selected"); 
    // 取得类名为"button"的图片
    let img = document.body.querySelector("img.button");
    

    在 Document 上使用 querySelector()方法时,会从文档元素开始搜索;在 Element 上使用querySelector()方法时,则只会从当前元素的后代中查询。

    querySelectorAll()

    querySelectorAll()方法跟 querySelector()一样,也接收一个用于查询的参数,但它会返回所有匹配的节点,而不止一个。这个方法返回的是一个 NodeList 的静态实例。

    再强调一次,querySelectorAll()返回的 NodeList 实例一个属性和方法都不缺,但它是一个静态的“快照”,而非“实时”的查询。这样的底层实现避免了使用 NodeList 对象可能造成的性能问题。

    用法

    // 取得 ID 为"myDiv"的<div>元素中的所有<em>元素
    let ems = document.getElementById("myDiv").querySelectorAll("em"); 
    // 取得所有类名中包含"selected"的元素
    let selecteds = document.querySelectorAll(".selected"); 
    // 取得所有是<p>元素子元素的<strong>元素
    let strongs = document.querySelectorAll("p strong");
    

    返回的 NodeList 对象可以通过 for-of 循环、item()方法或中括号语法取得个别元素。

    matches()

    matches()方法(在规范草案中称为 matchesSelector())接收一个 CSS 选择符参数,如果元素匹配则该选择符返回 true,否则返回 false。

    使用场景:

    使用这个方法可以方便地检测某个元素会不会被 querySelector()或 querySelectorAll()方法返回。

    所有主流浏览器都支持 matches()。Edge、Chrome、Firefox、Safari 和 Opera 完全支持,IE9~11及一些移动浏览器支持带前缀的方法。

    元素遍历

    IE9 之前的版本不会把元素间的空格当成空白节点,而其他浏览器则会。这样就导致了 childNodes和 firstChild 等属性上的差异。为了弥补这个差异,同时不影响 DOM 规范,W3C 通过新的 Element Traversal 规范定义了一组新属性。

    Element Traversal API 为 DOM 元素添加了 5 个属性:

    • childElementCount,返回子元素数量(不包含文本节点和注释);
    • firstElementChild,指向第一个 Element 类型的子元素(Element 版 firstChild);
    • lastElementChild,指向最后一个 Element 类型的子元素(Element 版 lastChild);
    • previousElementSibling ,指向前一个 Element 类型的同胞元素( Element 版previousSibling);
    • nextElementSibling,指向后一个 Element 类型的同胞元素(Element 版 nextSibling)。

    在支持的浏览器中,所有 DOM 元素都会有这些属性,为遍历 DOM 元素提供便利。这样开发者就不用担心空白文本节点的问题了。

    举个例子,过去要以跨浏览器方式遍历特定元素的所有子元素,代码大致是这样写的:

    let parentElement = document.getElementById('parent'); 
    let currentChildNode = parentElement.firstChild; 
    // 没有子元素,firstChild 返回 null,跳过循环
    while (currentChildNode) { 
     if (currentChildNode.nodeType === 1) { 
     // 如果有元素节点,则做相应处理
     processChild(currentChildNode); 
     } 
     if (currentChildNode === parentElement.lastChild) { 
     break; 
     } 
     currentChildNode = currentChildNode.nextSibling; 
    }
    

    使用 Element Traversal 属性之后,以上代码可以简化如下:

    let parentElement = document.getElementById('parent'); 
    let currentChildElement = parentElement.firstElementChild;
    // 没有子元素,firstElementChild 返回 null,跳过循环
    while (currentChildElement) { 
     // 这就是元素节点,做相应处理
     processChild(currentChildElement); 
     if (currentChildElement === parentElement.lastElementChild) { 
     break; 
     } 
     currentChildElement = currentChildElement.nextElementSibling; 
    }
    

    IE9 及以上版本,以及所有现代浏览器都支持 Element Traversal 属性。

    HTML5

    CSS 类扩展

    getElementsByClassName()

    getElementsByClassName()是 HTML5 新增的最受欢迎的一个方法,暴露在 document 对象和所有 HTML 元素上。这个方法脱胎于基于原有 DOM 特性实现该功能的 JavaScript 库,提供了性能高好的原生实现。

    getElementsByClassName()方法接收一个参数,即包含一个或多个类名的字符串,返回类名中包含相应类的元素的 NodeList。如果提供了多个类名,则顺序无关紧要。

    下面是几个示例:

    // 取得所有类名中包含"username"和"current"元素
    // 这两个类名的顺序无关紧要
    let allCurrentUsernames = document.getElementsByClassName("username current"); 
    // 取得 ID 为"myDiv"的元素子树中所有包含"selected"类的元素
    let selected = document.getElementById("myDiv").getElementsByClassName("selected");
    

    IE9 及以上版本,以及所有现代浏览器都支持 getElementsByClassName()方法。

    classList 属性

    className 是一个字符串,所以每次操作之后都需要重新设置这个值才能生效,即使只改动了部分字符串也一样.

    以下面的 HTML代码为例:

    <div class="bd user disabled">...</div>
    

    这个

    元素有 3 个类名。要想删除其中一个,就得先把 className 拆开,删除不想要的那个,再把包含剩余类的字符串设置回去。比如:
    // 要删除"user"类
    let targetClass = "user"; 
    // 把类名拆成数组
    let classNames = div.className.split(/\s+/); 
    // 找到要删除类名的索引
    let idx = classNames.indexOf(targetClass); 
    // 如果有则删除
    if (idx > -1) { 
     classNames.splice(i,1); 
    } 
    // 重新设置类名
    div.className = classNames.join(" ");
    

    这就是从

    元素的类名中删除"user"类要写的代码。替换类名和检测类名也要涉及同样的算法。添加类名只涉及字符串拼接,但必须先检查一下以确保不会重复添加相同的类名。很多 JavaScript库为这些操作实现了便利方法。

    HTML5 通过给所有元素增加 classList 属性为这些操作提供了更简单也更安全的实现方式。

    classList 是一个新的集合类型 DOMTokenList 的实例。与其他 DOM 集合类型一样,DOMTokenList也有 length 属性表示自己包含多少项,也可以通过 item()或中括号取得个别的元素。

    此外,DOMTokenList 还增加了以下方法。

    •  add(value),向类名列表中添加指定的字符串值 value。如果这个值已经存在,则什么也不做。
    •  contains(value),返回布尔值,表示给定的 value 是否存在。
    •  remove(value),从类名列表中删除指定的字符串值 value。
    •  toggle(value),如果类名列表中已经存在指定的 value,则删除;如果不存在,则添加。

    这样以来,前面的例子中那么多行代码就可以简化成下面的一行:

    div.classList.remove("user");
    

    这行代码可以在不影响其他类名的情况下完成删除。其他方法同样极大地简化了操作类名的复杂性,如下面的例子所示:

    // 删除"disabled"类
    div.classList.remove("disabled"); 
    // 添加"current"类
    div.classList.add("current");
    // 切换"user"类
    div.classList.toggle("user"); 
    // 检测类名
    if (div.classList.contains("bd") && !div.classList.contains("disabled")){ 
     // 执行操作
    ) 
    // 迭代类名
    for (let class of div.classList){ 
     doStuff(class); 
    }
    

    添加了 classList 属性之后,除非是完全删除或完全重写元素的 class 属性,否则 className属性就用不到了。IE10 及以上版本(部分)和其他主流浏览器(完全)实现了 classList 属性。

    焦点管理

    HTML5 增加了辅助 DOM 焦点管理的功能。首先是 document.activeElement,始终包含当前拥有焦点的 DOM 元素。页面加载时,可以通过用户输入(按 Tab 键或代码中使用 focus()方法)让某个元素自动获得焦点。例如:

    let button = document.getElementById("myButton"); 
    button.focus(); 
    console.log(document.activeElement === button); // true
    

    默认情况下,document.activeElement 在页面刚加载完之后会设置为 document.body。而在页面完全加载之前,document.activeElement 的值为 null。

    其次是 document.hasFocus()方法,该方法返回布尔值,表示文档是否拥有焦点:

    let button = document.getElementById("myButton"); 
    button.focus(); 
    console.log(document.hasFocus()); // true
    

    第一个方法可以用来查询文档,确定哪个元素拥有焦点,第二个方法可以查询文档是否获得了焦点,而这对于保证 Web 应用程序的无障碍使用是非常重要的。无障碍 Web 应用程序的一个重要方面就是焦点管理,而能够确定哪个元素当前拥有焦点(相比于之前的猜测)是一个很大的进步。

    HTMLDocument 扩展

    readyState 属性

    readyState 是 IE4 最早添加到 document 对象上的属性,后来其他浏览器也都依葫芦画瓢地支持这个属性。最终,HTML5 将这个属性写进了标准。document.readyState 属性有两个可能的值:

    •  loading,表示文档正在加载;
    •  complete,表示文档加载完成。

    实际开发中,最好是把 document.readState 当成一个指示器,以判断文档是否加载完毕。在这个属性得到广泛支持以前,通常要依赖 onload 事件处理程序设置一个标记,表示文档加载完了。这个属性的基本用法如下:

    if (document.readyState == "complete"){ 
     // 执行操作
    }
    

    compatMode 属性

    作用:检测页面渲染模式

    标准模式下 document.compatMode 的值是"CSS1Compat",而在混杂模式下,document.compatMode 的值是"BackCompat":

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

    HTML5 最终也把 compatMode 属性的实现标准化了。

    head 属性

    作为对 document.body(指向文档的元素)的补充,HTML5 增加了 document.head 属性,指向文档的元素。可以像下面这样直接取得元素:

    let head = document.head;
    

    字符集属性

    HTML5 增加了几个与文档字符集有关的新属性。其中,characterSet 属性表示文档实际使用的字符集,也可以用来指定新字符集。这个属性的默认值是"UTF-16",但可以通过元素或响应头,以及新增的 characterSeet 属性来修改。下面是一个例子:

    console.log(document.characterSet); // "UTF-16" 
    document.characterSet = "UTF-8";
    

    自定义数据属性

    HTML5 允许给元素指定非标准的属性,但要使用前缀 data-以便告诉浏览器,这些属性既不包含与渲染有关的信息,也不包含元素的语义信息。除了前缀,自定义属性对命名是没有限制的,data-后面跟什么都可以。下面是一个例子:

    <div id="myDiv" data-appId="12345" data-myname="Nicholas"></div>
    

    定义了自定义数据属性后,可以通过元素的 dataset 属性来访问。dataset 属性是一个DOMStringMap 的实例,包含一组键/值对映射。元素的每个 data-name 属性在 dataset 中都可以通过 data-后面的字符串作为键来访问(例如,属性 data-myname、data-myName 可以通过 myname 访问,但要注意 data-my-name、data-My-Name 要通过 myName 来访问)。下面是一个使用自定义数据属性的例子:

    // 本例中使用的方法仅用于示范
    let div = document.getElementById("myDiv"); 
    // 取得自定义数据属性的值
    let appId = div.dataset.appId; 
    let myName = div.dataset.myname; 
    // 设置自定义数据属性的值
    div.dataset.appId = 23456; 
    div.dataset.myname = "Michael"; 
    // 有"myname"吗?
    if (div.dataset.myname){ 
     console.log(`Hello, ${div.dataset.myname}`); 
    }
    

    自定义数据属性非常适合需要给元素附加某些数据的场景,比如链接追踪和在聚合应用程序中标识页面的不同部分。另外,单页应用程序框架也非常多地使用了自定义数据属性。

    插入标记

    innerHTML 属性

    在读取 innerHTML 属性时,会返回元素所有后代的 HTML 字符串,包括元素、注释和文本节点。而在写入 innerHTML 时,则会根据提供的字符串值以新的 DOM 子树替代元素中原来包含的所有节点。比如下面的 HTML 代码:

    <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 则会按照文档源代码的格式返回,包含空格和缩进。因此不要指望不同浏览器的innerHTML 会返回完全一样的值。

    在写入模式下,赋给 innerHTML 属性的值会被解析为 DOM 子树,并替代元素之前的所有节点。因为所赋的值默认为 HTML,所以其中的所有标签都会以浏览器处理 HTML 的方式转换为元素,如果赋值中不包含任何 HTML 标签,则直接生成一个文本节点,如下所示:

    div.innerHTML = "Hello world!";
    

    因为浏览器会解析设置的值,所以给 innerHTML 设置包含 HTML 的字符串时,结果会大不一样。来看下面的例子:

    div.innerHTML = "Hello & welcome, <b>\"reader\"!</b>";
    

    这个操作的结果相当于:

    <div id="content">Hello &amp; welcome, <b>&quot;reader&quot;!</b></div>
    

    注意 设置 innerHTML 会导致浏览器将 HTML 字符串解析为相应的 DOM 树。这意味着设置 innerHTML 属性后马上再读出来会得到不同的字符串。这是因为返回的字符串是将原始字符串对应的 DOM 子树序列化之后的结果。

    旧 IE 中的 innerHTML

    在所有现代浏览器中,通过 innerHTML 插入的

    而在 IE8 及之前的版本中,只要这样插入的

    // 行不通
    div.innerHTML = "<script defer>console.log('hi');<\/script>";
    
    // 以下都可行
    div.innerHTML = "_<script defer>console.log('hi');<\/script>"; 
    div.innerHTML = "<div>&nbsp;</div><script defer>console.log('hi');<\/script>"; 
    div.innerHTML = "<input type=\"hidden\"><script defer>console.log('hi');<\/script>";
    

    作为了解,IE自己玩吧!

    outerHTML 属性

    与innerHTML用法基本一致,只是会替换原来的容器元素;

    insertAdjacentHTML()与 insertAdjacentText()

    关于插入标签的最后两个新增方法是 insertAdjacentHTML()和 insertAdjacentText()。这两个方法最早源自 IE

    它们都接收两个参数:要插入标记的位置和要插入的 HTML 或文本。

    •  "beforebegin",插入当前元素前面,作为前一个同胞节点;
    •  "afterbegin",插入当前元素内部,作为新的子节点或放在第一个子节点前面;
    •  "beforeend",插入当前元素内部,作为新的子节点或放在最后一个子节点后面;
    •  "afterend",插入当前元素后面,作为下一个同胞节点。

    第二个参数会作为 HTML 字符串解析(与 innerHTML 和outerHTML 相同)或者作为纯文本解析(与 innerText 和 outerText 相同)。如果是 HTML,则会在解析出错时抛出错误。

    下面展示了基本用法

    // 作为前一个同胞节点插入
    element.insertAdjacentHTML("beforebegin", "<p>Hello world!</p>"); 
    element.insertAdjacentText("beforebegin", "Hello world!"); 
    // 作为第一个子节点插入
    element.insertAdjacentHTML("afterbegin", "<p>Hello world!</p>"); 
    element.insertAdjacentText("afterbegin", "Hello world!"); 
    // 作为最后一个子节点插入
    element.insertAdjacentHTML("beforeend", "<p>Hello world!</p>"); 
    element.insertAdjacentText("beforeend", "Hello world!"); 
    // 作为下一个同胞节点插入
    element.insertAdjacentHTML("afterend", "<p>Hello world!</p>"); element. 
    insertAdjacentText("afterend", "Hello world!");
    

    内存与性能问题

    使用本节介绍的方法替换子节点可能在浏览器(特别是 IE)中导致内存问题。比如,如果被移除的子树元素中之前有关联的事件处理程序或其他 JavaScript 对象(作为元素的属性),那它们之间的绑定关系会滞留在内存中。如果这种替换操作频繁发生,页面的内存占用就会持续攀升。在使用 innerHTML、outerHTML 和 insertAdjacentHTML()之前,最好手动删除要被替换的元素上关联的事件处理程序和JavaScript 对象。

    使用这些属性当然有其方便之处,特别是 innerHTML。一般来讲,插入大量的新 HTML 使用innerHTML 比使用多次 DOM 操作创建节点再插入来得更便捷。这是因为 HTML 解析器会解析设置给innerHTML(或 outerHTML)的值。解析器在浏览器中是底层代码(通常是 C++代码),比 JavaScript快得多。

    不过,HTML 解析器的构建与解构也不是没有代价,因此最好限制使用 innerHTML 和outerHTML 的次数。

    比如,下面的代码使用 innerHTML 创建了一些列表项:

    for (let value of values){ 
     ul.innerHTML += '<li>${value}</li>'; // 别这样做!
    }
    

    这段代码效率低,因为每次迭代都要设置一次 innerHTML。不仅如此,每次循环还要先读取innerHTML,也就是说循环一次要访问两次 innerHTML。为此,最好通过循环先构建一个独立的字符串,最后再一次性把生成的字符串赋值给 innerHTML,比如:

    let itemsHtml = "";
    for (let value of values){ 
    	itemsHtml += '<li>${value}</li>'; 
    } 
    ul.innerHTML = itemsHtml;
    

    这样修改之后效率就高多了,因为只有对 innerHTML 的一次赋值。当

    跨站点脚本

    尽管 innerHTML 不会执行自己创建的

    如果页面中要使用用户提供的信息,则不建议使用 innerHTML。与使用 innerHTML 获得的方便相比,防止 XSS 攻击更让人头疼。最好对它们进行转义。

    scrollIntoView()

    DOM 规范中没有涉及的一个问题是如何滚动页面中的某个区域。为填充这方面的缺失,不同浏览器实现了不同的控制滚动的方式。在所有这些专有方法中,HTML5 选择了标准化 scrollIntoView()。

    scrollIntoView()方法存在于所有 HTML 元素上,可以滚动浏览器窗口或容器元素以便包含元素进入视口。这个方法的参数如下:

    alignToTop 是一个布尔值。

    • true:窗口滚动后元素的顶部与视口顶部对齐。
    • false:窗口滚动后元素的底部与视口底部对齐。

    scrollIntoViewOptions 是一个选项对象。

    • behavior:定义过渡动画,可取的值为"smooth"和"auto",默认为"auto"。
    • block:定义垂直方向的对齐,可取的值为"start"、"center"、"end"和"nearest",默认为 "start"。
    • inline:定义水平方向的对齐,可取的值为"start"、"center"、"end"和"nearest",默认为 "nearest"。

    不传参数等同于 alignToTop 为 true。

    经常应用菜单栏的滚动操作,聊天消息的回到底部等场景;

    看下面一个例子:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <style>
        ul {
            height: 200px;
            overflow-y: scroll;
            position: relative;
            border:1px solid pink;
        }
    
        li {
            height: 30px;
            line-height: 30px;
        }
    </style>
    
    
    <body>
        <ul>
            <li>111</li>
            <li>112</li>
            <li>113</li>
            <li>114</li>
            <li>151</li>
            <li>114541</li>
            <li>11451</li>
            <li>141411</li>
            <li>11453411</li>
            <li>112811</li>
            <li>1124231</li>
            <li>11446491</li>
            <li>1233</li>
            <li>111231231</li>
            <li>11145645</li>
        </ul>
    </body>
    
    <script>
        (function () {
            var li = document.querySelectorAll("li");
            var ul = document.querySelector("ul");
            var height = parseInt(getComputedStyle(document.querySelector("ul")).height);
            li.forEach(item => {
                item.onclick = function () {
                    this.style = "color:red"
                    // 用自带的方法  但是如果父亲和爷爷都有滚动条的话,都会动
                    this.scrollIntoView({behavior: 'smooth', block: 'center'});
    
                    /* 
                        1. scrollTop 小于0是不动的
                        2. li 的offsetTop 是以dom 中的为准,是不会变的,通过滚动到试图中间只是视觉上变了,所以如果scollTop 等于  的offsetTop 就到最上面了
                        3. top-height/2 所以说当到了中间的时候才会动
                     */
    
                    // let top = this.offsetTop;
                    // console.log('top', top);
                    // ul.scrollTop = top - height / 2;
                }
            })
        })()
    </script>
    
    </html>
    

    专有扩展

    children 属性

    出现的原因:IE9 之前的版本与其他浏览器在处理空白文本节点上的差异导致了 children 属性的出现。

    children 属性是一个 HTMLCollection,只包含元素的 Element 类型的子节点。如果元素的子节点类型全部是元素类型,那 children 和 childNodes 中包含的节点应该是一样的。

    contains()方法

    DOM 编程中经常需要确定一个元素是不是另一个元素的后代。IE 首先引入了 contains()方法,让开发者可以在不遍历 DOM 的情况下获取这个信息。contains()方法应该在要搜索的祖先元素上调用,参数是待确定的目标节点。

    如果目标节点是被搜索节点的后代,contains()返回 true,否则返回 false。

    下面看一个例子:

    console.log(document.documentElement.contains(document.body)); // true
    

    另外,使用 DOM Level 3 的 compareDocumentPosition()方法也可以确定节点间的关系。这个方法会返回表示两个节点关系的位掩码。

    要模仿 contains()方法,就需要用到掩码 16(0x10)。compareDocumentPosition()方法的结果可以通过按位与来确定参考节点是否包含传入的节点,

    let result = document.documentElement.compareDocumentPosition(document.body); 
    console.log(!!(result & 0x10));
    

    以上代码执行后 result 的值为 20(或 0x14,其中 0x4 表示“随后”,加上 0x10“被包含”)。对result 和 0x10 应用按位与会返回非零值,而两个叹号将这个值转换成对应的布尔值。

    IE9 及之后的版本,以及所有现代浏览器都支持 contains()和 compareDocumentPosition()方法。

    插入标记

    HTML5 将 IE 发明的 innerHTML 和 outerHTML 纳入了标准,但还有两个属性没有入选。这两个剩下的属性是 innerText 和 outerText。

    innerText 属性

    innerText 属性对应元素中包含的所有文本内容,无论文本在子树中哪个层级。在用于读取值时,innerText 会按照深度优先的顺序将子树中所有文本节点的值拼接起来。

    来看下面的 HTML 代码:

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

    对这个例子中的

    而言,innerText 属性会返回以下字符串:
    This is a paragraph with a list following it. 
    Item 1 
    Item 2 
    Item 3
    

    注意不同浏览器对待空格的方式不同,因此格式化之后的字符串可能包含也可能不包含原始 HTML代码中的缩进。

    设置 innerText 会移除元素之前所有的后代节点,完全改变 DOM 子树。此外,设置 innerText也会编码出现在字符串中的 HTML 语法字符(小于号、大于号、引号及和号)。下面是一个例子:

    div.innerText = "Hello & welcome, <b>\"reader\"!</b>";
    

    执行之后的结果如下:

    <div id="content">Hello &amp; welcome, &lt;b&gt;&quot;reader&quot;!&lt;/b&gt;</div>
    

    因为设置 innerText 只能在容器元素中生成一个文本节点,所以为了保证一定是文本节点,就必须进行 HTML 编码。innerText 属性可以用于去除 HTML 标签。

    一个很有意思的题目,去除所有的html标签,可以这样写:

    div.innerText = div.innerText;
    

    执行以上代码后,容器元素的内容只会包含原先的文本内容。

    outerText 属性

    outerText 与 innerText 是类似的,只不过作用范围包含调用它的节点。

    outerText 是一个非标准的属性,而且也没有被标准化的前景。因此,不推荐依赖这个属性实现重要的操作。除 Firefox 之外所有主流浏览器都支持 outerText。

    滚动

    如前所述,滚动是 HTML5 之前 DOM 标准没有涉及的领域。虽然 HTML5 把 scrollIntoView()标准化了,但不同浏览器中仍然有其他专有方法。比如,scrollIntoViewIfNeeded()作 为HTMLElement 类型的扩展可以在所有元素上调用。

    考虑到 scrollIntoView()是唯一一个所有浏览器都支持的方法,所以只用它就可以了。


    起源地下载网 » 红宝书之第十五章:DOM扩展

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元