你不知道的8个DOM功能

本文将介绍八种鲜为人知的DOM功能,这些功能具有强大的浏览器支持。 为了帮助解释每个人的工作方式,我将提供许多交互式演示供您尝试自己的代码。

这些方法和属性的学习曲线并不陡峭,可以与您碰巧带到项目中的任何工具集一起很好地工作。

您肯定可以使用addEventListener()处理将事件附加到网络文档中的元素。 通常,一个addEventListener()调用看起来像这样:

element.addEventListener('click', doSomething, false);

第一个参数是我正在听的事件。 第二个参数是事件发生时将执行的回调函数。 第三个参数是一个名为useCapture的布尔值,用于指示您是否要使用事件冒泡或捕获。

这些都是众所周知的(尤其是前两个)。 但是也许您不知道addEventListener()也接受替换最终布尔值的参数。 这个新参数是一个选项对象,如下所示:

element.addEventListener('click', doSomething, {
  capture: false,
  once: true,
  passive: false
});

注意,语法允许定义三个不同的属性。 下面简要介绍了每个含义:

  • capture —一个布尔值,与前面提到的useCapture参数相同

  • once - 一个布尔值,如果设置为true,则表示该事件只应在目标元素上运行一次,然后被删除

  • passive -最终的布尔值,如果设置为true,则表明该函数将永远不会调用preventDefault(),即使它包含在函数主体中

这三个中最有趣的是一次选项。 在许多情况下,这肯定会派上用场,并使您不必使用removeEventListener()或使用其他复杂的技术来强制执行单个事件触发器。 如果您使用过jQuery,则可能熟悉该库中的类似功能.one()方法。

您可以在以下CodePen中试用一些使用options对象的代码:

请注意,演示页面上的按钮将仅附加一次文本。 如果将一次值更改为false,然后多次单击该按钮,则每次单击按钮后都会附加该文本。

浏览器对options对象的支持非常出色:除IE11和更早版本外,所有浏览器都支持该对象,因此如果您不担心Microsoft Edge之前的浏览器,则可以安全使用。

用于在窗口或元素中平滑滚动的scrollTo()方法

平滑滚动一直是需要的。 当本地页面链接立即跳转到指定位置时,这很震撼(如果您眨眼,甚至可能会错过跳转)。 平滑滚动不仅是看起来不错,而且可以改善页面的用户体验的功能之一。

虽然过去使用jQuery插件已经做到了这一点,但现在可以使用window.scrollTo()方法仅用一行JavaScript来实现。

scrollTo()方法应用于Window对象,以告诉浏览器滚动到页面上的指定位置。 例如,这是使用最简单语法的示例:

window.scrollTo(0, 1000);

这将使窗口向右滚动0px(代表x坐标或水平滚动),向页面下滚动1000px(垂直,通常是您想要的)。 但是在那种情况下,滚动将不是平滑的动画效果。 该页面将突然滚动,就像您使用针对指定哈希URL的本地链接一样。

有时候这就是您想要的。 但是为了获得流畅的滚动,您必须合并鲜为人知的ScrollToOptions对象,如下所示:

window.scrollTo({
  top: 0,
  left: 1000,
  behavior: 'smooth'
});

该代码与前面的示例等效,但是在options对象中为behavior属性添加了平滑值。

尝试在框中输入一个数字(最好是一个较大的数字,例如4000),然后更改“行为”选择框以使用“平滑”或“自动”(这是behavior属性的唯一两个选项)。

有关此功能的一些注意事项:

  • 全面支持scrollTo(),但并非所有浏览器都支持options对象

  • 当应用于元素而不是窗口时,此方法也将起作用

  • 这些选项也适用于scroll()scrollBy()方法

setTimeout()和setInterval()及可选参数

在许多情况下,使用window.setTimeout()window.setInterval()进行基于时间的动画现在已被性能更友好的window.requestAnimationFrame()所取代。

但是在某些情况下,setTimeout()setInterval()是正确的选择,因此很高兴知道这些方法的鲜为人知的功能。

通常,您会使用以下语法看到以下两种方法之一:

let timer = window.setInterval(doSomething, 3000);
function doSomething () {
  // Something happens here...
}

这里的setInterval()调用传入两个参数:回调函数和时间间隔。 使用setTimeout()可以运行一次,但是在这种情况下,它将无限期运行,直到我传入window变量时调用window.clearTimeout()为止。

很简单。 但是,如果我希望回调函数接受参数怎么办? 好吧,这些计时器方法的最新添加允许以下内容:

let timer = window.setInterval(doSomething, 3000, 10, 20);
function doSomething (a, b) {
  // Something happens here…
}

请注意,我在setInterval()调用中又添加了两个参数。 然后,我的doSomething()函数将其接受为参数,并可以根据需要进行操作。

这是一个CodePen演示,演示了如何使用setTimeout()进行工作:

当您单击按钮时,将使用两个传入的值进行计算。 可以通过页面上的数字输入更改值。

至于浏览器支持,关于此的信息似乎不一致,但看起来几乎所有使用中的浏览器都支持可选参数功能,包括IE10。

单选按钮和复选框的defaultChecked属性

您可能知道,对于单选按钮和复选框,如果要获取或设置checked属性,则可以使用checked属性,如下所示(假设radioButton是对特定表单输入的引用):

console.log(radioButton.checked); // true
radioButton.checked = false;
console.log(radioButton.checked); // false

但是,还有一个名为defaultChecked的属性,可以将其应用于单选按钮或复选框组,以找出最初设置为选中状态的组中的哪个。

以下是一些示例HTML:

<form id="form">
  <input type="radio" value="one" name="setOne"> One
  <input type="radio" value="two" name="setOne" checked> Two<br />
  <input type="radio" value="three" name="setOne"> Three
</form>

这样,即使已更改选中的单选按钮,我也可以遍历输入并找出最初检查的是哪个,如下所示:

for (i of myForm.setOne) {
  if (i.defaultChecked === true) {
    console.log(‘i.value’);
  }
}

下面是一个CodePen演示,将显示当前选中的单选按钮或默认选中的单选按钮,具体取决于您使用的按钮:

该示例中的defaultChecked选项将始终是“ Two”单选按钮。 如前所述,这也可以通过复选框组来完成。 尝试更改HTML中的默认选中选项,然后再次尝试按钮。

这是另一个演示,它与一组复选框相同:

在这种情况下,您会注意到默认情况下选中了两个复选框,因此当使用defaultChecked查询时,它们都将返回true

使用normalize()和WholeText处理文本节点

HTML文档中的文本节点可能很挑剔,尤其是在动态插入或创建节点时。 例如,如果我具有以下HTML:

<p id="el">This is the initial text.</p>

然后,我可以在该段落元素中添加一个文本节点:

let el = document.getElementById('el');
el.appendChild(document.createTextNode(' Some more text.'));
console.log(el.childNodes.length); // 2

请注意,在附加了文本节点之后,我记录了段落内子节点的长度,并说有两个节点。 这些节点是单个字符串,但是由于文本是动态附加的,因此它们被视为单独的节点。

在某些情况下,如果将文本像单个文本节点一样对待,将会更加有用,这使文本更易于操作。 这是normalize()WholeText()进入的地方。

normalize()方法可用于合并单独的文本节点:

el.normalize();
console.log(el.childNodes.length); // 1

在元素上调用normalize()将合并该元素内的所有相邻文本节点。 如果在相邻的文本节点之间散布了一些HTML,则HTML将保持原样,而所有相邻的文本节点将被合并。

但是,如果出于某种原因我想将文本节点分开,但仍然希望能够将文本作为一个单元来抓取,那么在那,WholeText很有用。 因此,我可以在相邻的文本节点上执行此操作,而不是调用normalize()

console.log(el.childNodes[0].wholeText);
// This is the initial text. Some more text.
console.log(el.childNodes.length); // 2

只要我没有调用normalize(),文本节点的长度就会保持为2,并且我可以使用WholeText记录整个文本。 但请注意以下几点:

  • 我必须在文本节点之一而不是元素上调用全文本(因此代码中的el.childNodes [0]el.childNodes [1]也可以工作)

  • 文本节点必须相邻,没有HTML分隔它们

您可以看到在此CodePen演示中使用的两个功能以及splitText()方法。 打开CodePen控制台或浏览器的开发人员工具控制台,查看生成的日志。

insertAdjacentElement()和insertAdjacentText()

你们中的许多人可能会熟悉insertAdjacentHTML()方法,该方法使您可以轻松地将文本或HTML字符串添加到页面中与其他元素相关的特定位置。

但是也许您没有意识到该规范还包括两个以类似方式工作的相关方法:insertAdjacentElement()insertAdjacentText()

insertAdjacentHTML()的缺陷之一是插入的内容必须为字符串形式。 因此,如果包含HTML,则必须这样声明:

el.insertAdjacentHTML('beforebegin', '<p><b>Some example</b> text goes here.</p>');

但是,使用insertAdjacentElement()时,第二个参数可以是元素引用:

let el = document.getElementById('example'),
addEl = document.getElementById('other');
el.insertAdjacentElement('beforebegin', addEl);

这种方法的有趣之处在于,它不仅将引用的元素添加到指定位置,而且还将其从文档中的原始位置删除。 因此,这是将元素从DOM中的一个位置转移到另一个位置的简便方法。

这是一个使用insertAdjacentElement()的CodePen演示。 单击按钮可以有效地“移动”目标元素:

insertAdjacentText()方法的工作原理类似,但是所提供的文本字符串将仅作为文本插入,即使它包含HTML。 请注意以下演示:

您可以将自己的文本添加到输入字段,然后使用按钮将其添加到文档。 请注意,所有特殊字符(例如HTML标记)都将作为HTML实体插入,与insertAdjacentHTML()相比,此方法的行为有所不同。

这三个方法(insertAdjacentHTML()insertAdjacentElement()insertAdjacentText())对于第一个参数都采用相同的值。 参数为:

  • beforebegin:在调用该方法的元素之前插入

  • afterbegin:在第一个子元素之前插入元素中

  • beforeend:在元素的最后一个子元素之后插入

  • afterend:在元素之后插入

event.detail属性

如前所述,事件是使用熟悉的addEventListener()方法附加到网页上的元素的。 例如:

btn.addEventListener('click', function () {
  // do something here...
}, false);

使用addEventListener()时,可能有必要防止函数调用内的默认浏览器行为。 例如,也许您想拦截<a>元素上的点击并使用JavaScript处理这些点击。 您可以这样做:

btn.addEventListener('click', function (e) {
  // do something here...
  e.preventDefault();
}, false);

这使用了preventDefault(),这与老式的return false语句在现代上等效。 这要求您将事件对象传递到函数中,因为在该对象上调用了preventDefault()方法。

但是您可以使用该事件对象做更多的事情。 实际上,当使用某些事件(例如clickdbclickmouseupmousedown)时,这些事件会显示为UIEvent接口。

正如MDN所指出的,此接口上的许多功能已被弃用或未标准化。 但是最有趣和有用的一个是detail属性,它是官方规范的一部分。

在同一事件侦听器示例中的外观如下:

btn.addEventListener('click', function (e) {
  // do something here...
  console.log(e.detail);
}, false);

我已经建立了一个CodePen演示,它使用许多不同的事件来演示结果:

演示中的每个按钮将以按钮文本描述的方式响应,并显示一条消息,显示当前的点击计数。 注意事项:

  • WebKit浏览器允许无限制的点击计数,但dbclick除外(始终为2)。 Firefox最多只允许单击三下,然后重新开始计数

  • 我添加了模糊和重点说明这些内容不合格,并且始终会返回0(即无点击)

  • IE11等旧版浏览器的行为非常不一致

注意,该演示包括一个很好的用例,用于模仿三次单击事件:

btnT.addEventListener('click', function (e) {
  if (e.detail === 3) {
    trpl.value = 'Triple Click Successful!';
  }
}, false);

如果所有浏览器的点击次数都超过了3次,那么您还可以检测到更高的点击次数,但是我认为对于大多数目的,只需单击一次三下即可。

scrollHeight和scrollWidth属性

您可能对scrollHeightscrollWidth属性感到熟悉,因为您可能会将它们与其他与宽度和高度相关的DOM功能混淆。 例如,offsetWidthoffsetHeight属性将返回元素的高度或宽度,而不考虑溢出。

例如,请注意以下演示:

演示中的列具有相同的内容。左侧列的溢出设置为“自动”,而右侧列的溢出设置为“隐藏”。offsetHeight属性为每个元素返回相同的值,因为它不考虑可滚动区域或隐藏区域;它只测量元素的实际高度,包括任何垂直填充和边框。

另一方面,恰当命名的scrollHeight属性将计算元素的完整高度,包括可滚动(或隐藏)区域:

上面的演示与上一个演示相同,除了它使用scrollHeight来获取每一列的高度。 再次注意,两列的值都相同。 但是这次的数字要高得多,因为溢出区域也被算作高度的一部分。

上面的示例着重于元素高度,这是最常见的用例,但是您也可以使用offsetWidthscrollWidth,它们相对于水平滚动的应用方式相同。

结论

就是这样的DOM功能列表,这些可能是我在过去几年中遇到的一些最有趣的功能,所以我希望至少可以在其中的项目中使用这些功能。

原文地址:https://blog.logrocket.com/8-dom-features-you-didnt-know-existed-ec2a0a28fd89/

以上就是你不知道的8个DOM功能的详细内容,更多请关注0133技术站其它相关文章!

赞(0) 打赏
未经允许不得转载:0133技术站首页 » JavaScript 教程