JavaScript总结【10】Document

本文详细介绍了JavaScript中Document对象的相关知识,包括DOM节点类、搜索文档、节点属性、修改文档、样式和类、元素大小和滚动、窗口大小和滚动、禁止滚动以及坐标等。重点讲解了如nodetype、nodeName、innerHTML、offsetParent、style、className、scrollWidth、scrollHeight等属性和方法的使用,帮助开发者更好地理解和操作DOM。
摘要由CSDN通过智能技术生成

JavaScript Document

DOM节点类

每个 DOM 节点都属于相应的内建类。层次结构(hierarchy)的根节点是 EventTarget,Node 继承自它,其他 DOM 节点继承自 Node

  • EventTarget — 是根的抽象类。该类的对象从未被创建。它作为一个基础,以便让所有 DOM 节点都支持所谓的“事件(event)”。
  • Node — 也是一个抽象类,充当 DOM 节点的基础。它提供了树的核心功能:parentNodenextSiblingchildNodes 等(它们都是 getter)。Node 类的对象从未被创建。但是有一些继承自它的具体的节点类,例如:文本节点的 Text元素节点的 Element,以及更多异域(exotic)类,例如注释节点的 Comment
  • Element — 是 DOM 元素的基本类。它提供了元素级的导航(navigation),例如 nextElementSiblingchildren,以及像 getElementsByTagNamequerySelector 这样的搜索方法。浏览器中不仅有 HTML,还会有 XML 和 SVG。Element 类充当更多特定类的基本类:SVGElementXMLElementHTMLElement
  • HTMLElement— 最终是所有 HTML 元素的基本类。各种 HTML 元素均继承自它:

小技巧:

console.dir(elem)console.log(elem)对于 DOM 元素,它们是不同的:

  • console.log(elem) 显示元素的 DOM 树。
  • console.dir(elem) 将元素显示为 DOM 对象,非常适合探索其属性

搜索文档

方法名搜索方式可以在元素上调用?实时的?
querySelectorCSS-selector-
querySelectorAllCSS-selector-
getElementByIdid--
getElementsByNamename-
getElementsByTagNametag or '*'
getElementsByClassNameclass

目前为止,最常用的是 querySelectorquerySelectorAll,但是 getElement(s)By* 可能会偶尔有用,或者可以在旧脚本中找到。

此外:

  • elem.matches(css) 用于检查 elem 与给定的 CSS 选择器是否匹配。
  • elem.closest(css) 用于查找与给定 CSS 选择器相匹配的最近的祖先。elem 本身也会被检查。

让我们在这里提一下另一种用来检查子级与父级之间关系的方法,因为它有时很有用:

  • 如果 elemBelemA 内(elemA 的后代)或者 elemA==elemBelemA.contains(elemB) 将返回 true

节点属性

nodetype

它提供了另一种“过时的”用来获取 DOM 节点类型的方法

它有一个数值型值(numeric value):

  • 对于元素节点 elem.nodeType == 1
  • 对于文本节点 elem.nodeType == 3
  • 对于 document 对象 elem.nodeType == 9

nodeName 和 tagName

获取标签名,差异:tagName 属性仅适用于 Element 节点,nodeName 是为任意 Node 定义的(如注释节点)

innerHTML

将元素中的 HTML 获取为字符串形式,我们也可以修改它。因此,它是更改页面最有效的方法之一。注意,修改时会将内容**“归零”**并从头开始重写,因此所有的图片和其他资源都将重写加载

outerHTML

将元素中的 HTML 获取为字符串形式,除了包含innerHTML的全部内容外, 还包含对象标签本身写入 outerHTML 不会改变元素。而是在 DOM 中替换它

<div>Hello, world!</div>

<script>
  let div = document.querySelector('div');

  // 使用 <p>...</p> 替换 div.outerHTML
  div.outerHTML = '<p>A new element</p>'; // (*)

  // 蛤!'div' 还是原来那样!
  alert(div.outerHTML); // <div>Hello, world!</div> (**)
    
  // 但是这里HTML实际上已经变成了<p>A new element</p>
</script>

上面代码的过程可以理解为:

  • div 被从文档(document)中移除。
  • 另一个 HTML 片段 <p>A new element</p> 被插入到其位置上。
  • div 仍拥有其旧的值。新的 HTML 没有被赋值给任何变量。原来的值不在文档树中,但是仍在内存中!

nodeValue/data

innerHTML 属性仅对元素节点有效。其他节点类型,例如文本节点,具有它们的对应项:nodeValuedata 属性。这两者在实际使用中几乎相同,只有细微规范上的差异。

textContent

textContent 提供了对元素内的 文本 的访问权限:仅文本,去掉所有 <tags>。与用户交互使用这个更加安全

hidden

从技术上来说,hiddenstyle="display:none" 做的是相同的事。但 hidden 写法更简洁。下面时设置元素闪烁的方法

<div id="elem">A blinking element</div>

<script>
  setInterval(() => elem.hidden = !elem.hidden, 1000);
</script>

其他属性

DOM 元素还有其他属性,特别是那些依赖于 class 的属性:

  • value<input><select><textarea>HTMLInputElementHTMLSelectElement……)的 value。
  • href<a href="...">HTMLAnchorElement)的 href。
  • id — 所有元素(HTMLElement)的 “id” 特性(attribute)的值。
  • ……

修改文档

  • 创建新节点的方法:
    • document.createElement(tag) — 用给定的标签创建一个元素节点,
    • document.createTextNode(value) — 创建一个文本节点(很少使用)
    • elem.cloneNode(deep) — 克隆元素,如果 deep==true 则与其后代一起克隆。如果为false则只会克隆标签和标签内的东西,如类,不包括子节点(含文本节点)
// 创建新节点
// 1. 创建 <div> 元素
let div = document.createElement('div');
// 2. 将元素的类设置为 "alert"
div.className = "alert";
// 3. 填充消息内容
div.innerHTML = "<strong>Hi there!</strong> You've read an important message.";
  • 插入和移除节点的方法:

    • node.append(...nodes or strings) — 在 node 末尾插入,
    • node.prepend(...nodes or strings) — 在 node 开头插入,
    • node.before(...nodes or strings) — 在 node 之前插入,
    • node.after(...nodes or strings) — 在 node 之后插入,
    • node.replaceWith(...nodes or strings) — 替换 node
    • node.remove() — 移除 node

    注意:所有插入方法都会自动从旧位置删除该节点。

    参数为strings时,文本字符串被“作为文本”插入。

  • 这里还有“旧式”的方法:

    • parent.appendChild(node)
    • parent.insertBefore(node, nextSibling)
    • parent.removeChild(node)
    • parent.replaceChild(newElem, node)

    这些方法都返回 node

  • html 中给定一些 HTML,elem.insertAdjacentHTML(where, html) 会根据 where 的值来插入它:

    • "beforebegin" — 将 html 插入到 elem 前面,
    • "afterbegin" — 将 html 插入到 elem 的开头,
    • "beforeend" — 将 html 插入到 elem 的末尾,
    • "afterend" — 将 html 插入到 elem 后面。
      在这里插入图片描述

另外,还有类似的方法,elem.insertAdjacentTextelem.insertAdjacentElement,它们会插入文本字符串和元素,但很少使用。

  • 要在页面加载完成之前将 HTML 附加到页面:
    • document.write(html)

样式和类

className 、 classList 和 style

  1. className
<body class="main page">
  <script>
    alert(document.body.className); // main page
  </script>
</body>
  1. classList
    • elem.classList.add/remove(class) — 添加/移除类。
    • elem.classList.toggle(class) — 如果类不存在就添加类,存在就移除它。
    • elem.classList.contains(class) — 检查给定类,返回 true/false
<body class="main page">
  <script>
    // 添加一个 class
    document.body.classList.add('article');
    alert(document.body.className); // main page article
  </script>
</body>
  1. style

    • 普通属性:elem.style.attr
    • 前缀属性:如button.style.MozBorderRadius = '5px';。连字符-表示大写
    • 重置样式属性:置空即可,如document.body.style.display = ""
  2. style.cssText

    不能直接通过改变style来进行批量更改,因为style对象是只读的(只有style是可读的因此可以改变引用指向地址上的内容,即attr),但是可以通过**style.cssText**进行完全的重写。注意,该方法会删除现有样式!

<div id="div">Button</div>

<script>
  // 我们可以在这里设置特殊的样式标记,例如 "important"
  div.style.cssText=`color: red !important;
    background-color: yellow;
    width: 100px;
    text-align: center;
  `;

  alert(div.style.cssText);
</script>

也可以通过setAttribute('style','css')达到效果,如div.setAttribute('style', 'color: red...')

计算样式

  1. style 属性仅对 "style" 特性(attribute)值起作用,而没有任何 CSS 级联(cascade),因此我们无法使用 elem.style 读取来自 CSS 类(可以读取行内式)的任何内容:
<head>
  <style> body { color: red; margin: 5px } </style>
</head>
<body>

  The red text
  <script>
    alert(document.body.style.color); // 空的
    alert(document.body.style.marginTop); // 空的
  </script>
</body>
  1. 解决方案:getComputedStyle(element, [pseudo])
    • element:需要被读取样式值的元素
    • pseudo:伪元素,例如 ::before。空字符串或无参数则意味着元素本身
    • 返回值:结果是一个具有样式属性的对象。类似于elem.style。返回的值都需要完整的如paddingLeft
<head>
  <style> body { color: red; margin: 5px } </style>
</head>
<body>

  <script>
    let computedStyle = getComputedStyle(document.body);
    // 现在我们可以读取它的 margin 和 color 了
    alert( computedStyle.marginTop ); // 5px
    alert( computedStyle.color ); // rgb(255, 0, 0)
  </script>
</body>

元素大小和滚动

几何

在这里插入图片描述

offsetParent、offsetLeft、offsetTop(只读)

  1. offsetParent 是最接近的祖先(ancestor),在浏览器渲染期间,它被用于计算坐标。最近的祖先为下列之一:

    • CSS 定位的(positionabsoluterelativefixed),
    • <td><th><table>
    • <body>
  2. 属性 offsetLeft/offsetTop 提供相对于 offsetParent 左上角的 x/y 坐标。如:

在这里插入图片描述

  1. 有以下几种情况下,offsetParent 的值为 null
    • 对于未显示的元素(display:none 或者不在文档中)。
    • 对于 <body><html>
    • 对于带有 position:fixed 的元素

offsetWidth、offsetHeight(只读)

它们提供了元素的“外部” width/height。或者,换句话说,它的完整大小(包括边框)

在这里插入图片描述

检查元素是否被隐藏

function isHidden(elem) {
  return !elem.offsetWidth && !elem.offsetHeight;
}

clientTop、clientLeft、clientWidth、clientHeight(只读)

  1. clientLeft:表示一个元素的左边框的宽度,以像素表示。如果元素的文本方向是从右向左(RTL, right-to-left),并且由于内容溢出导致左边出现了一个垂直滚动条,则该属性包括滚动条的宽度clientLeft 不包括左外边距和左内边距

  2. clientTop:一个元素顶部边框的宽度(以像素表示)。不包括顶部外边距或内边距。
    在这里插入图片描述

  3. clientWidth:内联元素以及没有 CSS 样式的元素的 **clientWidth** 属性值为 0。**Element.clientWidth** 属性表示元素的内部宽度,以像素计。该属性包括内边距 padding,但不包括边框 border、外边距 margin 和垂直滚动条(如果有的话)

  4. clientHeight:对于没有定义CSS或者内联布局盒子的元素为0,否则,它是元素内部的高度(单位像素),包含内边距,但不包括水平滚动条、边框和外边距

scrollWidth、scrollHeight(只读)scrollLeft、scrollTop(可写)

  1. scrollwidth、scrollHeight:这些属性就像 clientWidth/clientHeight,但它们还包括滚动出(隐藏)的部分
    在这里插入图片描述

  2. scrollLeft、scrollTop:(可写)属性 scrollLeft/scrollTop 是元素的隐藏、滚动部分的 width/height。在下图中,我们可以看到带有垂直滚动块的 scrollHeightscrollTop
    在这里插入图片描述

Window大小和滚动

窗口的width/height

document.documentElementclientWidth/clientHeight(会去除滚动条的高宽,window.innerWidth/Height不会 )

在这里插入图片描述

文档width/height

规定:

let scrollHeight = Math.max(
  document.body.scrollHeight, document.documentElement.scrollHeight,
  document.body.offsetHeight, document.documentElement.offsetHeight,
  document.body.clientHeight, document.documentElement.clientHeight
);

alert('Full document height, with scrolled out part: ' + scrollHeight);

获取当前滚动

window.pageXOffset/pageYOffset

滚动

  1. 可以通过更改 scrollTop/scrollLeft滚动常规元素。我们可以使用 document.documentElement.scrollTop/scrollLeft 对页面进行相同的操作(Safari 除外,而应该使用 document.body.scrollTop/Left 代替)

  2. 通用解决方案:window.scrollBy(x,y) window.scrollTo(pageX,pageY)其中x、y是相对于当前坐标的x、y值,pageX、pageY是绝对坐标

scrollIntoView

elem.scrollIntoView(top) 的调用将滚动页面以使 elem 可见。它有一个参数:

  • 如果 top=true(默认值),页面滚动,使 elem 出现在窗口顶部。元素的上边缘将与窗口顶部对齐。
  • 如果 top=false,页面滚动,使 elem 出现在窗口底部。元素的底部边缘将与窗口底部对齐

禁止滚动

document.body.style.overflow = "hidden"

坐标

两种坐标系

  1. **相对于窗口:**类似于 position:fixed,从窗口的顶部/左侧边缘计算得出,我们将这些坐标表示为 clientX/clientY
  2. 相对于文档:与文档根(document root)中的 position:absolute 类似,从文档的顶部/左侧边缘计算得出。我们将它们表示为 pageX/pageY
    在这里插入图片描述

元素坐标:getBoundingClientRect

方法 elem.getBoundingClientRect() 返回最小矩形的窗口坐标,该矩形将 elem 作为内建 DOMRect 类的对象。主要的 DOMRect 属性:

  • x/y — 矩形原点相对于窗口的 X/Y 坐标,
  • width/height — 矩形的 width/height(可以为负)。

此外,还有派生(derived)属性:

  • top/bottom — 顶部/底部矩形边缘的 Y 坐标,
  • left/right — 左/右矩形边缘的 X 坐标。

在这里插入图片描述

elementFromPoint(x,y)

document.elementFromPoint(x, y) 的调用会返回在窗口坐标 (x, y) 处嵌套最多(the most nested)的元素。

Element.getBoundingClientRect()

Element.getBoundingClientRect() 方法返回元素的大小及其相对于视口的位置。如果是标准盒子模型,元素的尺寸等于width/height + padding + border-width的总和。如果box-sizing: border-box,元素的的尺寸等于 width/height。返回值是一个 DOMRect 对象,拥有left, top, right, bottom, x, y, width, 和 height这几个以像素为单位的只读属性

在这里插入图片描述
图片来源:https://zh.javascript.info

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值