js nodelist_失去jQuery膨胀-使用NodeList.js进行DOM操作

js nodelist

近年来,jQuery已成为网络上事实上JavaScript库。 它消除了许多跨浏览器的不一致之处,并在客户端脚本中添加了可喜的语法糖。 它抽象化的主要痛点之一是DOM操作,但是自其诞生以来,本机浏览器API有了显着改善,并且您可能不需要jQuery的想法开始流行。

原因如下:

  1. jQuery包含了许多您不需要或不使用的功能(因此权重是不必要的)。
  2. jQuery对太多人来说太多了。 通常,较小的库可以更好地完成某些任务。
  3. 在DOM操作方面,浏览器API现在可以完成jQuery的大部分工作。
  4. 浏览器的API现在更加同步,例如使用addEventListener而不是attatchEvent

所以有什么问题?

问题在于,与jQuery相比,使用原始(或普通)JavaScript进行DOM操作可能会很痛苦。 这是因为您必须读写更多的冗余代码,并处理浏览器的无用NodeList

首先让我们看一下根据MDN的NodeList

NodeList对象是节点的集合,例如由Node.childNodes和document.querySelectorAll方法返回的那些节点。

有时还有实时的NodeList (可能会引起混淆):

在某些情况下,NodeList是一个实时集合,这意味着DOM中的更改会反映在集合中。 例如,Node.childNodes处于活动状态。

这可能是一个问题,因为您无法分辨哪些是实时的,哪些是静态的。 除非您从NodeList删除每个节点,然后检查NodeList是否为空。 如果为空,那么您将拥有一个活动的NodeList (这是一个坏主意)。

而且浏览器也没有提供任何有用的方法来操纵这些NodeList对象。

例如,不幸的是,不可能使用forEach遍历节点:

var nodes = document.querySelectorAll('div');
nodes.forEach(function(node) {
  // do something
});
// Error: nodes.forEach is not a function

因此,您必须执行以下操作:

var nodes = document.querySelectorAll('div');
for(var i = 0, l = nodes.length; i < l; i++) {
  var node = nodes[i];
  // do something
}

甚至还可以使用“ hack”:

[].forEach.call(document.querySelectorAll('div'), function(node) {
    // do something
});

浏览器的本机NodeList只有一种方法: item 。 这将通过索引从NodeList返回一个节点。 当我们可以像访问数组一样(使用array[index] )访问该节点时,它是完全没有用的:

var nodes = document.querySelectorAll('div');
nodes.item(0) === nodes[0]; // true

这就是NodeList.js的用处 -使得使用浏览器的本机API操纵DOM就像使用jQuery一样容易,但是仅需4k即可。

解决方案

我创建NodeList.js的原因是我一直使用本机DOM API,但希望使其更加简洁,以便在编写代码时消除大量冗余(例如for循环)。

NodeList.js是本机DOM API的包装,它使您可以像对待单个节点一样操作节点数组(又称为NodeList )。 这为您提供了比浏览器的本机NodeList对象更多的功能。

如果这对您来说听起来不错,请从官方的GitHub存储库中获取NodeList.js的副本,然后继续本教程的其余部分。

用法:

选择DOM节点很简单:

$$(selector); // returns my NodeList

此方法在querySelectorAll(selector)使用querySelectorAll(selector)

但是它如何与jQuery叠在一起?

免费学习PHP!

全面介绍PHP和MySQL,从而实现服务器端编程的飞跃。

原价$ 11.95 您的完全免费

很高兴你问。 让我们将香草JS,jQuery和NodeList.js放在首位。

假设我们有三个按钮:

<button></button>
<button></button>
<button></button>

让我们将每个按钮的文本更改为“ Click Me”

香草JS:

var buttons = document.querySelectorAll('button'); // returns browser's useless NodeList
for(var i = 0, l = buttons.length; i < l; i++) {
  buttons[i].textContent = 'Click Me';
}

jQuery的:

$('button').text('Click Me');

NodeList.js:

$$('button').textContent = 'Click Me';

在这里,我们看到NodeList.js可以有效地将NodeList视为单个节点。 也就是说,我们已经引用了NodeList ,我们只是将其textContent属性设置为“ Click Me” 。 然后NodeList.js将在每个节点上执行此NodeList 。 整洁吧?

如果我们想要方法链接(jQuery类),我们将执行以下操作,返回对NodeList的引用:

$$('button').set('textContent', 'Click Me');

现在,我们向每个按钮添加一个click事件监听器:

香草JS:

var buttons = document.querySelectorAll('button'); // returns browser's useless NodeList
for(var i = 0, l = buttons.length; i < l; i++) {
  buttons[i].addEventListener('click', function() {
    this.classList.add('clicked');
  });
}

jQuery的:

$('button').on('click', function() {
  $(this).addClass('click');
  // or mix jQuery with native using `classList`:
  this.classList.add('clicked');
});

NodeList.js:

$$('button').addEventListener('click', function() {
  this.classList.add('clicked');
});

好的,因此jQuery on方法相当不错。 我的库使用浏览器的本机DOM API(因此为addEventListener ),但并不能阻止我们为该方法创建别名:

$$.NL.on = $$.NL.addEventListener;

$$('button').on('click', function() {
  this.classList.add('clicked');
});

真好! 这恰好演示了我们添加自己的方法的方式:

$$.NL.myNewMethod = function() {
  // loop through each node with a for loop or use forEach:
  this.forEach(function(element, index, nodeList) {...}
  // where `this` is the NodeList being manipulated
}

数组方法上的NodeList.js

NodeList.js确实从Array.prototype继承,但不是直接继承,因为某些方法已更改,因此可以将它们与NodeList (节点数组)一起使用。

推入和放开

例如: pushunshift方法只能将节点作为参数,否则它们将引发错误:

var nodes = $$('body');
nodes.push(document.documentElement);
nodes.push(1); // Uncaught Error: Passed arguments must be a Node

因此pushunshift返回NodeList以允许方法链接,这意味着它与JavaScript的本机Array#pushArray#unshift方法不同,后者可以接受任何内容并返回Array的新长度。 如果我们确实想要NodeList的长度,我们只使用length属性。

就像JavaScript的本机Array方法一样,这两种方法都会更改NodeList

康卡特

concat方法将以下内容作为参数:

  • Node
  • NodeList (浏览器的本机版本和NodeList.js版本)
  • HTMLCollection
  • Array of Nodes
  • Array of NodeList
  • Array of HTMLCollection

concat是一种递归方法 ,因此这些数组可以像我们想要的那样深,并且将被展平。 但是,如果传递的数组中的任何元素都不属于NodeNodeListHTMLCollection则它将引发Error

concat确实会返回一个新的NodeList ,就像javascript的Array#concat方法一样。

弹出,移位,地图,切片,过滤器

popshift方法都可以使用一个可选参数来确定要从NodeList popshift多少个节点。 与JavaScript的本机Array#popArray#shift ,无论将什么作为参数传递,后者总是会popshift数组中的一个元素。

如果每个映射值都是一个Node ,则map方法将返回一个NodeList如果不是,则返回一个映射值的数组。

slicefilter方法的行为就像在实际数组上一样,但是将返回NodeList

由于NodeList.js并不直接从继承Array.prototype如果一个方法被添加到Array.prototype NodeList.js被加载之后,也不会被继承。

您可以在此处检查其余的NodeList.js数组方法

特殊方法

NodeList.js独有四种方法,还有一个名为owner的属性,它等同于jQuery的prevObject属性。

getset方法:

有些元素具有该类元素独有的属性(例如,anchor标签上的href属性)。 这就是$$('a').href返回undefined原因-因为它是NodeList中并非每个元素都继承的属性。 这就是我们使用get方法访问这些属性的方式:

$$('a').get('href'); // returns array of href values

set方法可用于为每个元素设置这些属性:

$$('a').set('href', 'https://sitepoint.com/');

set还返回NodeList以允许方法链接。 我们可以在textContent东西上使用它(两者都是等效的):

$$('button').textContent = 'Click Me';

$$('button').set('textContent', 'Click Me'); // returns NodeList so you can method chain

我们还可以在一个调用中设置多个属性:

$$('button').set({
    textContent: 'Click Me',
    onclick: function() {...}
});

以上所有操作都可以通过任意属性来完成,例如style

$$('button').style; // this returns an `Array` of `CSSStyleDeclaration`

$$('button').style.set('color', 'white');

$$('button').style.set({
    color: 'white',
    background: 'lightblue'
});

call方式

通过call方法 ,您可以调用元素独有的那些方法(例如,在视频元素上pause ):

$$('video').call('pause'); // returns NodeList back to allow Method Chaining

item方法

item方法等效于jQuery的eq方法 。 它返回一个NodeList ,它仅包含传递的索引的节点:

$$('button').item(1); // returns NodeList containing the single Node at index 1

owner财产

owner属性与jQuery的prevObject等效。

var btns = $$('button');
btns.style.owner === btns; // true

btns.style返回一个样式数组, owner返回给您映射styleNodeList

NodeList.js兼容性

我的媒体库与所有主要的新浏览器兼容,如下所述。

浏览器
火狐 6+
苹果浏览器 5.0.5+
Chrome 6+
IE浏览器 9+
歌剧 11.6+

结论

现在,我们终于可以使用一个有用的NodeList对象了!

只需花大约4k的时间,您就可以得到上面提到的所有功能,并且可以在NodeList.jsGitHub存储库中学习更多的功能。

由于NodeList.js使用浏览器作为依赖项,因此无需进行任何升级。 每当浏览器向DOM元素添加新的方法/属性时,您都可以通过NodeList.js自动使用这些方法/属性。 所有这一切都意味着您唯一需要担心的弃用方法是浏览器摆脱的方法。 这些通常使用率很低,因为我们无法破坏网络。

所以你怎么看? 这是您要考虑使用的库吗? 是否缺少任何重要功能? 我希望在下面的评论中收到您的来信。

翻译自: https://www.sitepoint.com/dom-manipulation-with-nodelist-js/

js nodelist

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值