前端温习(二): Javascriput 核心对象 Document 对象(二)

简介: 当浏览器载入 HTML 文档, 它就会成为 Document 对象。Document 对象是 HTML 文档的根节点。Document 对象使我们可以从脚本中对 HTML 页面中的所有元素进行访问。

使用

由于属性和方法比较多,就把一些常用的一些属性和方法展开说明。

属性

  • doctype
    对于 HTML 文档来说,document 对象一般有两个子节点。第一个子节点是 document.doctype,它是一个对象,包含了当前文档类型(Document Type Declaration,简写DTD)信息。对于 HTML5 文档,该节点就代表 <!DOCTYPE html>。如果网页没有声明 DTD,该属性返回 null
// document.firstChild 通常就返回这个节点
var doctype = document.doctype;
doctype 
// "<!DOCTYPE html>"
doctype.name 
// "html"

  • documentElement
    document.documentElement 属性,表示当前文档的根节点(root)。它通常是 document 节点的第二个子节点,紧跟在 document.doctype 节点后面。
    对于 HTML 网页,该属性返回 HTML 节点,代表 <html lang="en">
  • defaultView
    defaultView 属性,在浏览器中返回 document 对象所在的 window 对象,否则返回 null
  • body
    body 属性返回当前文档的 bodyframeset 节点,如果不存在这样的节点,就返回 null

这个属性是可写的,如果对其写入一个新的节点,会导致原有的所有子节点被移除。

  • head
    head 属性返回当前文档的 head 节点。如果当前文档有多个 head,则返回第一个。
  • activeElement
    activeElement 属性返回当前文档中获得焦点的那个元素。用户通常可以使用 tab 键移动焦点,使用空格键激活焦点,比如如果焦点在一个链接上,此时按一下空格键,就会跳转到该链接。
  • documentURI、URL
    documentURI 属性和 URL 属性都返回当前文档的网址。不同之处是 documentURI 属性是所有文档都具备的,URL 属性则是 HTML 文档独有的。
  • domain
    domain 属性返回当前文档的域名。比如,某张网页的网址是 http://www.example.com/hello.htmldomain 属性就等于 www.example.com 。如果无法获取域名,该属性返回 null
// 如果当前域名等于指定域名,则关闭窗口。
var badDomain = "www.example.xxx";
if (document.domain === badDomain)
  window.close();

二级域名的情况下,domain 属性可以设置为对应的一级域名。比如,当前域名是 sub.example.com,则 domain 属性可以设置为 example.com。除此之外的写入,都是不可以的。

  • lastModified
    lastModified 属性返回当前文档最后修改的时间戳,格式为字符串。
document.lastModified
// '08/05/2021 17:34:49'
if (Date.parse(doc1.lastModified) Date.parse(doc2.lastModified)) {
  // ...
}

注意,lastModified 属性的值是字符串,所以不能用来直接比较,两个文档谁的日期更新,需要用 Date.parse 方法转成时间戳格式,才能进行比较。

  • location
    location 属性返回一个只读对象,提供了当前文档的 URL 信息。
// 假定当前网址为http://user:passwd@www.example.com:4097/path/a.html?x=111#part1
document.location.href // "http://user:passwd@www.example.com:4097/path/a.html?x=111#part1"
document.location.protocol // "http:"
document.location.host // "www.example.com:4097"
document.location.hostname // "www.example.com"
document.location.port // "4097"
document.location.pathname // "/path/a.html"
document.location.search // "?x=111"
document.location.hash // "#part1"
document.location.user // "user"
document.location.password // "passed"
// 跳转到另一个网址
document.location.assign('http://www.google.com')
// 优先从服务器重新加载
document.location.reload(true)
// 优先从本地缓存重新加载(默认值)
document.location.reload(false)
// 跳转到另一个网址,但当前文档不保留在history对象中,
// 即无法用后退按钮,回到当前文档
document.location.assign('http://www.google.com')
// 将location对象转为字符串,等价于document.location.href
document.location.toString()

  • referrer
    referrer 属性返回一个字符串,表示前文档的访问来源,如果是无法获取来源或是用户直接键入网址,而不是从其他网页点击,则返回一个空字符串。
  • title
    title 属性返回当前文档的标题,该属性是可写的。
document.title = '新标题';

  • characterSet
    characterSet 属性返回渲染当前文档的字符集,比如 UTF-8ISO-8859-1
  • readyState
    readyState 属性返回当前文档的状态,共有三种可能的值,加载 HTML 代码阶段(尚未完成解析)是“loading”,加载外部资源阶段是“interactive”,全部加载完成是“complete”。
// 基本检查
if (document.readyState === 'complete') {
  // ...
}
// 轮询检查
var interval = setInterval(function() {
  if (document.readyState === 'complete') {
    clearInterval(interval);
    // ...
  }
}, 100);
  • designModed
    designMode 属性控制当前 document 是否可编辑。通常会打开 iframedesignMode 属性,将其变为一个所见即所得的编辑器。
iframe_node.contentDocument.designMode = "on";
  • implementation
    implementation 属性返回一个对象,用来甄别当前环境部署了哪些 DOM 相关接口。implementation 属性的 hasFeature 方法,可以判断当前环境是否部署了特定版本的特定接口。
// 当前环境部署了DOM HTML 2.0版和MutationEvents的2.0版。
document.implementation.hasFeature( 'HTML, 2.0 ')
// true
document.implementation.hasFeature('MutationEvents','2.0')
// true
  • compatMode
    compatMode 属性返回浏览器处理文档的模式,可能的值为 BackCompat(向后兼容模式)和 CSS1Compat(严格模式)。
  • anchors,embeds,forms,images,links,scripts,styleSheets这几个属性都是返回文档内部特定元素的集合。这些集合都是动态的,原节点有任何变化,立刻会反映在集合中
  • anchors 返回网页中所有的 a 节点元素【必须指定了 name属性的 a 元素】
  • embeds 返回网页中所有嵌入对象【即embed标签】,返回的格式为类似数组的对象(nodeList)
  • forms 返回页面中所有表单
  • images 返回页面所有图片元素【即img标签】
  • links 返回当前文档所有的链接元素【即 a 标签,或者说具有 href 属性的元素】
  • scripts 返回当前文档的所有脚本【script标签】
  • styleSheets 返回一个类似数组的对象,包含了当前网页的所有样式表

方法

  • open()
    用于新建一个文档,供 write 方法写入内容。它实际上等于清除当前文档,重新写入内容。不要将此方法与 window.open() 混淆,后者用来打开一个新窗口,与当前文档无关。
  • close
    用于关闭 open 方法所新建的文档。一旦关闭,write 方法就无法写入内容了。如果再调用 write 方法,就等同于又调用 open 方法,新建一个文档,再写入内容。
  • write()
    用于向当前文档写入内容。只要当前文档还没有用 close 方法关闭,它所写入的内容就会追加在已有内容的后面。
// 页面显示“helloworld”
document.open();
document.write("hello");
document.write("world");
document.close();
  • 如果页面已经渲染完成(DOMContentLoaded 事件发生之后),再调用 write 方法,它会先调用 open 方法,擦除当前文档所有内容,然后再写入。
document.addEventListener("DOMContentLoaded", function(event) {
  document.write('<p>Hello World!</p>');
});
// 等同于
document.addEventListener("DOMContentLoaded", function(event) {
  document.open();
  document.write('<p>Hello World!</p>');
  document.close();
});
  • 如果在页面渲染过程中调用 write 方法,并不会调用 open 方法。(可以理解成,open 方法已调用,但 close 方法还未调用。)
<html>
<body>
hello
<script type="text/javascript">
  document.write("world")
</script>
</body>
</html>

注意:虽然调用close方法之后,无法再用write方法写入内容,但这时当前页面的其他DOM节点还是会继续加载。

// 还是会显示“hello world”
<script type="text/javascript">
  document.open();
  document.write("hello");
  document.close();
</script>

总之,除了某些特殊情况,应该尽量避免使用document.write这个方法

  • writeln()
    document.writeln 方法与 write 方法完全一致,除了会在输出内容的尾部添加换行符
document.write(1);
document.write(2);
// 12
document.writeln(1);
document.writeln(2);
// 1
// 2
//

注意:writeln方法添加的是ASCII码的换行符,渲染成HTML网页时不起作用。

  • hasFocus()
    返回一个布尔值,表示当前文档之中是否有元素被激活或获得焦点。
focused = document.hasFocus();

注意:有焦点的文档必定被激活(active),反之不成立,激活的文档未必有焦点。比如如果用户点击按钮,从当前窗口跳出一个新窗口,该新窗口就是激活的,但是不拥有焦点。

  • querySelector()
    返回匹配指定的 CSS 选择器的元素节点。如果有多个节点满足匹配条件,则返回第一个匹配的节点。如果没有发现匹配的节点,则返回 null
var el1 = document.querySelector('.myclass');
var el2 = document.querySelector('#myParent > [ng-click]');

querySelector 方法无法选中 CSS 伪元素

  • **getElementById()**【非常常用的一个方法】
    返回匹配指定 ID 属性的元素节点。如果没有发现匹配的节点,则返回 null
var elem = document.getElementById("para1");
  • getElementById 方法与 querySelector 方法都能获取元素节点,不同之处是 querySelector 方法的参数使用 CSS 选择器语法,getElementById 方法的参数是 HTML 标签元素的 id 属性。
// 两个方法都能选中id为myElement的元素,但是getElementById()比querySelector()效率高得多
document.getElementById('myElement')
document.querySelector('#myElement')

注意:在搜索匹配节点时,id 属性是大小写敏感的。比如,如果某个节点的 id 属性是 main,那么 document.getElementById("Main") 将返回 null,而不是指定节点。

  • querySelectorAll()
    返回匹配指定的 CSS 选择器的所有节点,返回的是 NodeList 类型的对象。NodeList 对象不是动态集合,所以元素节点的变化无法实时反映在返回结果中。
// 返回class属性是note或alert的div元素
elementList = document.querySelectorAll(selectors);
// 逗号分隔的多个CSS选择器,返回所有匹配其中一个选择器的元素
var matches = document.querySelectorAll('div.note, div.alert');
// 支持复杂的CSS选择器。
// 选中data-foo-bar属性等于someval的元素
document.querySelectorAll('[data-foo-bar="someval"]');
// 选中myForm表单中所有不通过验证的元素
document.querySelectorAll('#myForm :invalid');
// 选中div元素,那些class含ignore的除外
document.querySelectorAll('DIV:not(.ignore)');
// 同时选中div,a,script三类元素
document.querySelectorAll('DIV, A, SCRIPT');

如果 querySelectorAll 方法和 getElementsByTagName 方法的参数是字符串“*”,则会返回文档中的所有 HTML 元素节点。与 querySelector 方法一样,querySelectorAll 方法无法选中 CSS 伪元素。

  • **getElementsByClassName()**【非常常用的一个方法】
    返回一个类似数组的对象(HTMLCollection类型的对象),包括了所有 class 名字符合指定条件的元素(搜索范围包括本身),元素的变化实时反映在返回结果中。这个方法不仅可以在 document 对象上调用,也可以在任何元素节点上调用。
// document对象上调用
var elements = document.getElementsByClassName(names);
// 非document对象上调用
var elements = rootElement.getElementsByClassName(names);
// 参数可以是多个空格分隔的class名字,返回同时具有这些节点的元素。
// 选择同时具有red和test的元素
document.getElementsByClassName('red test');
  • **getElementsByTagName()**【非常常用的一个方法】
    返回所有指定标签的元素(搜索范围包括本身)。返回值是一个 HTMLCollection 对象,也就是说,搜索结果是一个动态集合,任何元素的变化都会实时反映在返回的集合中。这个方法不仅可以在 document 对象上调用,也可以在任何元素节点上调用。
// 返回当前文档的所有p元素节点
var paras = document.getElementsByTagName("p");

注意:getElementsByTagName方法会将参数转为小写后,再进行搜索

  • getElementsByName()
    用于选择拥有 name 属性的 HTML 元素,比如 formimgframeembedobject,返回一个 NodeList 格式的对象,不会实时反映元素的变化
// 假定有一个表单是<form name="x"></form>
var forms = document.getElementsByName("x");
forms[0].tagName // "FORM"

注意:在IE浏览器使用这个方法,会将没有 name 属性、但有同名 id 属性的元素也返回,所以name和id属性最好设为不一样的值。

  • elementFromPoint()
    返回位于页面指定位置的元素
// 返回相对于当前窗口左上角的横坐标和纵坐标,单位是CSS像素
var element = document.elementFromPoint(x, y);
  • createElement()
    用来生成 HTML 元素节点
var element = document.createElement(tagName);
// 实例
var newDiv = document.createElement("div");

注意:createElement 方法的参数为元素的标签名,即元素节点的 tagName 属性。如果传入大写的标签名,会被转为小写。如果参数带有尖括号(即<和>)或者是 null,会报错。

  • createTextNode()
    用来生成文本节点,参数为所要生成的文本节点的内容
// 新建一个div节点和一个文本节点,文本节点插入div节点
var newDiv = document.createElement("div");
var newContent = document.createTextNode("Hello");
newDiv.appendChild(newContent);
  • createAttribute()
    生成一个新的属性对象节点,并返回它。
attribute = document.createAttribute(name);
// createAttribute 方法的参数 name,是属性的名称
var node = document.getElementById("div1");
var a = document.createAttribute("my_attrib");
a.value = "newVal";
node.setAttributeNode(a);
// 等同于
var node = document.getElementById("div1");
node.setAttribute("my_attrib", "newVal");
  • createDocumentFragment()
    生成一个 DocumentFragment 对象。DocumentFragment 对象是一个存在于内存的 DOM 片段,但是不属于当前文档,常常用来生成较复杂的 DOM 结构,然后插入当前文档。这样做的好处在于,因为 DocumentFragment 不属于当前文档,对它的任何改动,都不会引发网页的重新渲染,比直接修改当前文档的 DOM 有更好的性能表现。
var docfrag = document.createDocumentFragment();
[1, 2, 3, 4].forEach(function(e) {
  var li = document.createElement("li");
  li.textContent = e;
  docfrag.appendChild(li);
});
document.body.appendChild(docfrag);
  • createEvent()
    生成一个事件对象,该对象可以被 element.dispatchEvent 方法使用,触发指定事件
// createEvent 方法的参数是事件类型,比如 UIEvents、MouseEvents、MutationEvents、HTMLEvents
var event = document.createEvent('Event');
event.initEvent('build', true, true);
document.addEventListener('build', function (e) {
  // ...
}, false);
document.dispatchEvent(event);
  • reateNodeIterator()
    createNodeIterator 方法返回一个 DOM 的子节点遍历器。
var nodeIterator = document.createNodeIterator(
  document.body,
  NodeFilter.SHOW_ELEMENT
);
  • 上面代码返回 body 元素的遍历器。createNodeIterator 方法的第一个参数为遍历器的根节点,第二个参数为所要遍历的节点类型,这里指定为元素节点。其他类型还有所有节点(NodeFilter.SHOW_ALL)、文本节点(NodeFilter.SHOW_TEXT)、评论节点(NodeFilter.SHOW_COMMENT)等。
    所谓“遍历器”,在这里指可以用 nextNode 方法和 previousNode 方法依次遍历根节点的所有子节点。
var nodeIterator = document.createNodeIterator(document.body);
var pars = [];
var currentNode;
while (currentNode = nodeIterator.nextNode()) {
  pars.push(currentNode);
}
  • 上面代码使用遍历器的 nextNode 方法,将根节点的所有子节点,按照从头部到尾部的顺序,读入一个数组。nextNode 方法先返回遍历器的内部指针所在的节点,然后会将指针移向下一个节点。所有成员遍历完成后,返回 nullpreviousNode 方法则是先将指针移向上一个节点,然后返回该节点。
// currentNode和previousNode都指向同一个的节点
var nodeIterator = document.createNodeIterator(
  document.body,
  NodeFilter.SHOW_ELEMENT
);
var currentNode = nodeIterator.nextNode();
var previousNode = nodeIterator.previousNode();
currentNode === previousNode // true

注意:遍历器返回的第一个节点,总是根节点

  • createTreeWalker()
    返回一个 DOM 的子树遍历器。它与 createNodeIterator 方法的区别在于,后者只遍历子节点,而它遍历整个子树。
// createTreeWalker 第一个参数,是所要遍历的根节点,第二个参数指定所要遍历的节点类型
// 遍历body节点下属的所有元素节点,将它们插入nodeList数组
var treeWalker = document.createTreeWalker(
  document.body,
  NodeFilter.SHOW_ELEMENT
);
var nodeList = [];
while(treeWalker.nextNode()) nodeList.push(treeWalker.currentNode);
  • adoptNode()
    将某个节点,从其原来所在的文档移除,插入当前文档,并返回插入后的新节点。
// importNode 方法从外部文档拷贝指定节点,插入当前文档
var node = document.importNode(externalNode, deep);
  • importNode()
    用于创造一个外部节点的拷贝,然后插入当前文档。它的第一个参数是外部节点,第二个参数是一个布尔值,表示对外部节点是深拷贝还是浅拷贝,默认是浅拷贝(false)。虽然第二个参数是可选的,但是建议总是保留这个参数,并设为true。
// 从iframe窗口,拷贝一个指定节点myNode,插入当前文档
var iframe = document.getElementsByTagName("iframe")[0];
var oldNode = iframe.contentWindow.document.getElementById("myNode");
var newNode = document.importNode(oldNode, true);
document.getElementById("container").appendChild(newNode);

注意:importNode 方法只是拷贝外部节点,这时该节点的父节点是 null。下一步还必须将这个节点插入当前文档的 DOM 树。

相关实践学习
基于函数计算快速搭建Hexo博客系统
本场景介绍如何使用阿里云函数计算服务命令行工具快速搭建一个Hexo博客。
目录
相关文章
|
3天前
|
前端开发 JavaScript
【Web 前端】$(document).ready() 是个什么函数?为什么要用它?
【5月更文挑战第2天】【Web 前端】$(document).ready() 是个什么函数?为什么要用它?
|
6天前
|
前端开发 JavaScript 数据安全/隐私保护
前端javascript的DOM对象操作技巧,全场景解析(二)
前端javascript的DOM对象操作技巧,全场景解析(二)
|
6天前
|
移动开发 缓存 JavaScript
前端javascript的DOM对象操作技巧,全场景解析(一)
前端javascript的DOM对象操作技巧,全场景解析(一)
|
6天前
|
缓存 编解码 自然语言处理
前端javascript的BOM对象知识精讲
前端javascript的BOM对象知识精讲
|
6天前
|
JavaScript 前端开发 索引
【Web 前端】JQ对象和DOM元素之间如何转换?
【4月更文挑战第22天】【Web 前端】JQ对象和DOM元素之间如何转换?
|
3月前
|
前端开发 JavaScript Java
前端(JavaScript)------函数与对象
前端(JavaScript)------函数与对象
54 0
|
9月前
|
Web App开发 前端开发 JavaScript
前端学习笔记202307学习笔记第五十七天-模拟面试笔记react-fiber解决了什么问题
前端学习笔记202307学习笔记第五十七天-模拟面试笔记react-fiber解决了什么问题
98 0
|
9月前
|
前端开发 定位技术
前端学习笔记202305学习笔记第二十三天-地图单线程配置
前端学习笔记202305学习笔记第二十三天-地图单线程配置
66 0
前端学习笔记202305学习笔记第二十三天-地图单线程配置
|
9月前
|
前端开发 API
前端学习笔记202307学习笔记第五十七天-模拟面试笔记react-react-redux的工作流程
前端学习笔记202307学习笔记第五十七天-模拟面试笔记react-react-redux的工作流程
55 0
|
9月前
|
前端开发
前端学习笔记202306学习笔记第五十一天-工厂模式4
前端学习笔记202306学习笔记第五十一天-工厂模式
34 0