资讯专栏INFORMATION COLUMN

高程3总结#第11章DOM扩展

cucumber / 2761人阅读

摘要:操作类名时可以通过属性添加删除和替换类名。如果将可选的参数设置为,则表示尽量将元素显示在视口中部垂直方向。将元素的内容滚动指定的页面高度,具体高度由元素的高度决定。

DOM扩展 选择符API querySelector()方法

querySelector()方法接收一个CSS选择符,返回与该模式匹配的第一个元素,如果没有找到匹配的元素,返回null

//取得body元素
var body=document.querySelector("body");
//取得ID为"myDiv"的元素
var myDiv=document.querySelector("#myDiv");
//取得类为"selected"的第一个元素
var selected=document.querySelector(".selector");
//取得类为"button"的第一个元素
var img=document.body.querySelector("img.button")

如果传入了不被支持的选择符,querySelector()会抛出错误

querySelectorAll()方法

querySelectorAll()方法接收的参数与querySelector()方法一样,都是一个CSS选择符,但返回的是所有匹配元素而不是一个元素。这个方法返回的是一个NodeList的实例

底层实现类似于一组元素的快照,而非不断对文档进行搜索的动态查询。

//取得某
中的所有元素 var em =document.getElementById("myDiv").querySelectorAll("em") //取得类为"selected"的所有元素 var selected=document.querySelectorAll(".selected"); //取得所有

元素中的所有元素 var strongs=document.querySelectorAll("p strong") //要取得返回的NodeList中的每一个元素,可以使用item()方法,也可以使用方括号语法 var i,len,strong; for(i=0,len=strong.length;i

matchesSelector()方法

这个方法接收一个参数,即CSS选择符,如果调用元素与该选择符匹配,返回true,否则返回false

function matchesSelector(element, selector){
  if (element.matchesSelector){
    return element.matchesSelector(selector);
  } else if (element.msMatchesSelector){
    return element.msMatchesSelector(selector);
  } else if (element.mozMatchesSelector){
    return element.mozMatchesSelector(selector);
  } else if (element.webkitMatchesSelector){
    return element.webkitMatchesSelector(selector);
  } else {
    throw new Error("Not supported.");
  }
}
if (matchesSelector(document.body, "body.page1")){
  //执行操作
}

元素遍历

DOM新增的5个属性

childElementCount,返回子元素的个数,不包括文本节点和注释

firstElementCount,指向第一个子元素,firstChild的元素版

lastElementCount,指向最后一个子元素,lastChild的元素版

previousElementSibling,指向前一个同辈元素,previousSibling的元素版

nextElementSibling,指向后一个同辈元素,nextSibling的元素版

var i,
    len,
    child = element.firstChild;
while(child != element.lastChild){
  if (child.nodeType == 1){ //检查是不是元素
    processChild(child);
  }
  child = child.nextSibling;
}
//使用新增的元素代码会更简洁
var i,
    len,
    child = element.firstElementChild;
while(child != element.lastElementChild){
  processChild(child); //已知其是元素
  child = child.nextElementSibling;
}

HTML5 与类相关的补充

getElementsByClassName()方法接收一个参数,即一个包含一或多个类名的字符串,返回带有制定类的所有元素的NodeList,传入多个类名时,类名的先后顺序不重要。

getElementsByClassName()始终会返回与类名匹配的所有元素,在元素上调用方法就会返回后代元素中匹配的元素。

操作类名时可以通过className属性添加、删除和替换类名。因为className中是一个字符串,所以即使只修改字符串的一部分,也必须每次都设置整个字符串的值

...
//删除"user"类
//首先,取得类名字符串并拆分成数组
var classNames = div.className.split(/s+/);
//找到要删的类名
var pos = -1,
    i,
    len;
for (i=0, len=classNames.length; i < len; i++){
  if (classNames[i] == "user"){
    pos = i;
    break;
  }
}
//删除类名
classNames.splice(i,1);
//把剩下的类名拼成字符串并重新设置
div.className = classNames.join(" ");

HTML5为所有元素添加classList属性,简化上述操作

add(value),将给定的字符串添加到列表中,如果值已经存在,就不添加了

contain(value),表示列表中是否存在给定的值,如果存在则返回true,否则返回false

remove(value),从列表中删除给定的字符串

toggle(value),如果列表中已经存在给定的值,删除。如果列表中没有给定的值,添加。

//删除"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 (var i=0, len=div.classList.length; i < len; i++){
doSomething(div.classList[i]);
}

焦点管理

document.activeElement属性会引用DOM中当前获得了焦点的元素,元素获得焦点的方式有页面加载、用户输入和在代码中调用focus()方法

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

默认情况下,文档刚刚加载完成时,document.activeElement中保存的是document.body元素的引用。文档加载期间,document.activeElement的值为null

新增document.hasFocus()方法,用于确定文档时候获得了焦点

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

HTMLDocument的变化

Document的readyState属性有两个可能的值

loading,正在加载的文档

complete,已经加载完的文档

使用document.readyState的最恰当方式,就是通过它来实现一个指示文档已经加载完成的指示器

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

document添加了一个名为compatMode的属性,这个属性就是为了告诉开发人员浏览器采用了哪种渲染模式。标准模式下,document.compatMode的值等于"CSS1Compat",而在混杂模式下,document.compatMode的值等于"BackCompat"

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

作为对document.body引用文档的元素的补充,HTML5新增了document.head属性,引用文档的元素,可以结合使用这个属性和另一种后备方法

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

字符集属性 自定义数据属性

可以为元素添加非标准的属性,但要添加前缀data-

可以通过元素的dataset属性类访问自定义属性的值

//本例中使用的方法仅用于演示
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);
}

插入标记

innerHTML

在读模式下,innerHTML属性返回与调用元素的所有子节点对应的HMTL标记。在写模式下,innerHTML会根据指定的值创建新的DOM树,然后用这个DOM树完全替换调用元素原先的所有子节点。

This is a paragraph with a list following it.

  • Item 1
  • Item 2
  • Item 3
//上面元素innerHTML属性会返回下面的字符串

This is a paragraph with a list following it.

  • Item 1
  • Item 2
  • Item 3
div.innerHTML="Hello & welcome,"reader"!"
//操作之后得到下面的HTML代码
Hello & welcome, "reader"!

只要使用innerHTML从外部插入HTML,都应该首先以可靠的方式处理HTML,IE8提供了window.toStationHTML()方法,这个方法接收一个参数,即一个HTML字符串,返回一个经过无害处理后的版本,从源HTML中删除所有脚本节点和事件处理程序属性

outerHTML

在读模式下,outerHTML返回调用它的元素及所有子节点的HTML标签。在写模式下,outerHTML会根据指定的HTML字符串创建新的DOM子树,然后用这个DOM子树完全替换调用元素

This is a paragraph with a list following it.

  • Item 1
  • Item 2
  • Item 3

如果调用outerHTML会返回和上面相同的代码,包括

本身

//设置outerHTML属性
div.outerHTML="

This is a paragraph.

"

insertAdjacentHTML

接收两个参数,插入位置和要插入的HTML文办,第一个参数必须是下列值之一

beforebegin,在当前元素之前插入一个紧邻的同辈元素

afterbegin,在当前元素之前插入一个新的子元素或在第一个子元素之前再插入新的子元素

beforeend,在当前元素之下插入一个新的子元素或在最后一个子元素之后再插入新的子元素

afterend,在当前元素之后插入一个紧邻的同辈元素

//作为前一个同辈元素插入
element.insertAdjacentHTML("beforebegin", "

Hello world!

"); //作为第一个子元素插入 element.insertAdjacentHTML("afterbegin", "

Hello world!

"); //作为最后一个子元素插入 element.insertAdjacentHTML("beforeend", "

Hello world!

"); //作为后一个同辈元素插入 element.insertAdjacentHTML("afterend", "

Hello world!

");
scrollIntoView()方法

scrollIntoView()可以在所有HTML元素上调用,通过滚动浏览器窗口或某个容器元素,调用元素就可以出现在视口中,如果给这个方法传入true作为参数,或者不传入任何参数,那么窗口滚动之后会让调用元素的顶部与视口顶部尽可能平齐,如果传入false作为参数,调用元素会尽可能全部出现在视口中

//让元素可见
document.forms[0]/scrollIntoView();

专有扩展 文档模式

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

IE5,以混杂模式渲染页面,IE8以及更高的版本功能无法使用

IE7,以IE7标准模式渲染页面,IE8以及更高额版本功能无法使用

IE8,以IE8标准模式渲染页面,IE8的新功能可以使用,IE9新功能无法使用

IE9,以IE9标准模式渲染页面,IE9新功能都可以使用

如果想让文档模式像IE7中一样,使用以下代码

如果不考虑文档类型声明,直接使用IE7标准模式

children属性

元素只包含元素子节点时,两个属性的值相同

var childCount=element.children.length;
var firstChild=element.children[0]

contains()方法

调用contain()方法的应该是祖先节点,也就是搜索开始的节点,这个方法接收一个参数,即要检测的后代节点。如果被检测的节点是后代节点,该方法返回true,否则返回false

alert(document.documentElement.contain(document.body))//true

使用浏览器及能力检测,写出通用的contain函数

function contains(refNode, otherNode){
  if (typeof refNode.contains == "function" &&
      (!client.engine.webkit || client.engine.webkit >= 522)){
    return refNode.contains(otherNode);
  } else if (typeof refNode.compareDocumentPosition == "function"){
    return !!(refNode.compareDocumentPosition(otherNode) & 16);
  } else {
    var node = otherNode.parentNode;
    do {
      if (node === refNode){
        return true;
      } else {
        node = node.parentNode;
      }
    } while (node !== null);
    return false;
  }
}

插入文本

innerText

通过这个属性可以操作元素中包含的所有文本内容,包括子文档树中的文本,在通过innerText读取值时,它会按照由浅入深的顺序,将子文档树中的所有文本拼接起来,在通过innerText写入值时,结果会删除元素的所有子节点,插入包含相应文本值的文本节点

This is a paragraph with a list following it.

  • Item 1
  • Item 2
  • Item 3
//对于上面的
元素而言,其innerText属性会返回下列字符串 This is a paragraph with a list following it. Item 1 Item 2 Item 3

设置这个属性

div.innerText="Hello world";
//执行完之后结果是下方代码
Hello world!

编写代码检测属性

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

outerText不只是替换它元素的自己诶单,而是会替换整个元素,包括子节点

滚动

对HTMLElement类型拓展的几个方法

scrollIntoViewIfNeeded(alignCenter) :只在当前元素在视口中不可见的情况下,才滚动浏览器窗口或容器元素,最终让它可见。如果当前元素在视口中可见,这个方法什么也不做。如果将可选的 alignCenter 参数设置为 true ,则表示尽量将元素显示在视口中部(垂直方向)。Safari 和 Chrome 实现了这个方法。

scrollByLines(lineCount) :将元素的内容滚动指定的行高, lineCount 值可以是正值,也可以是负值。Safari 和 Chrome 实现了这个方法。

scrollByPages(pageCount) :将元素的内容滚动指定的页面高度,具体高度由元素的高度决定。Safari 和 Chrome 实现了这个方法。

//将页面主体滚动 5 行
document.body.scrollByLines(5);
//在当前元素不可见的时候,让它进入浏览器的视口
document.images[0].scrollIntoViewIfNeeded();
//将页面主体往回滚动 1 页
document.body.scrollByPages(-1);

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/97830.html

相关文章

  • 高程3总结#1JavaScript简介

    摘要:简介简史诞生于年,当时主要负责表单的输入验证。实现一个完整的由三部分组成核心文档对象模型浏览器对象模型就是对实现该标准规定的各个方面内容的语言的描述。把整个页面映射为一个多层节点结构。由万维网联盟规划。主要目标是映射文档的结构。 JavaScript简介 JavaScript简史 JavaScript诞生于1995年,当时主要负责表单的输入验证。 如果没有表单验证的功能,填入信息之...

    betacat 评论0 收藏0
  • 高程3总结#12DOM2和DOM3

    摘要:如果不需要伪元素信息,第二个参数可以输操作样式表类型表示的是样式表,包括通过元素包含的样式表和在元素中定义的样式表表示样式表是否被禁用的布尔值。包括元素的高度可见的水平滚动条的高度上边框高度和下边框高度。显示处理指令节点。 DOM2和DOM3 DOM变化 针对XML命名空间的变化 有了XML命名空间,不同XML文档的元素就可以混合在一起,共同构成格式良好的文档,而不必担心发生命名冲突...

    Acceml 评论0 收藏0
  • 高程3总结#10DOM

    摘要:类型对象是的一个实例,表示整个页面,而且,对象是对象的一个属性,因此可以将其作为全局对象来访问。删除指定位置的行。创建创建创建第一行创建第二行将表格添加到文档主体中 DOM 节点层次 Node类型 DOM1级定义了一个Node接口,该接口将由DOM中的所有节点类型实现 节点类型由在Node类型中定义的12个数值常量来表示,任何节点类型必居其一 Node.ELEMENT_NODE(...

    ARGUS 评论0 收藏0
  • 高程3总结#14表单脚本

    表单脚本 表单的基础知识 HTMLFormElement有自己独特的属性和方法 acceptCharset,服务器能够处理的字符集,等价于HTML中的accept-charset特性 action,接受请求的URL,等价于HTML中的action特性 elements,表单中所有控件的集合 enctype,请求的编码类型,等价于HTML中的enctype特性 length,表单中控件的数量 m...

    Tony 评论0 收藏0
  • 高程3总结#18JavaScript与XML

    摘要:在基于使用命名空间的文档求值时,需要使用对象。第四个参数的取值类型是下列常量之一,返回与表达式匹配的数据类型。,返回字符串值。这是最常用的结果类型。集合中节点的次序与它们在文档中的次序一致。 JavaScript与XML 浏览器对XML DOM的支持 DOM2级核心 在通过JavaScript处理XML时,通常只使用参数root,因为这个参数指定的是XML DOM文档元素的标签名 v...

    gaosboy 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<