p.tip {background-color: rgba(128,128,128,0.05);border-top-right-radius: 5px;border-bottom-right-radius: 5px;padding: 15px 20px;border-left: 10px solid rgba(128,128,128,0.075);}

近年来,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像使用jQuery一样容易地操作DOM,但最小化了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叠加?

很高兴你问。 让我们将香草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 (节点数组)一起使用。

推入和放开

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

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确实会像javascript的Array#concat方法一样返回新的NodeList

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

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

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

slice和filter方法的行为就像在实际数组上一样,但是将返回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+
6+
IE浏览器 9+
歌剧 11.6+

结论

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

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

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

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

From: https://www.sitepoint.com/dom-manipulation-with-nodelist-js/

失去jQuery Bloat ­ —使用NodeList.js进行DOM操作相关推荐

  1. js hover 触发事件_为什么说JS的DOM操作很耗性能

    想问这样的问题,其实是自己心中没有个谱,一直用 js 计算性能来衡量 浏览器dom 操作性能.js性能和浏览器性能其实是两码事. 这个问题很抽象,它里面涉及挺多个小的知识点. 重申一点,js 操作 D ...

  2. jQuery中的事件机制与DOM操作

    jQuery事件机制 jQuery的事件机制,指的是jQuery对JavaScript操作DOM事件的封装,包括了:事件绑定.事件解绑.事件触发. 下面我们先来回顾一下事件的几种类型. 事件 描述 c ...

  3. 原生js循环展示dom_为什么说JS的DOM操作很耗性能

    想问这样的问题,其实是自己心中没有个谱,一直用 js 计算性能来衡量 浏览器dom 操作性能.js性能和浏览器性能其实是两码事. 这个问题很抽象,它里面涉及挺多个小的知识点. 重申一点,js 操作 D ...

  4. 锋利的jQuery学习笔记(4)-DOM操作

    1. DOM操作的分类: DOM Core:JavaScript中的getElementByID,getElementByTagName,getAttribute,setAttribute等方法都是其 ...

  5. JS的DOM操作1--获取元素与修改元素(附带动图案例)

    1.获取元素与修改元素 https://blog.csdn.net/TroyeSivanlp/article/details/120580055 2.创建自定义属性和节点 https://blog.c ...

  6. JS的DOM操作3--删除事件,注册事件与冒泡⭐⭐⭐(附带动图案例)

    1.获取元素与修改元素 https://blog.csdn.net/TroyeSivanlp/article/details/120580055 2.创建自定义属性和节点 https://blog.c ...

  7. js 原生dom 操作

    一. 首先要了解什么是 DOM? DOM: 全称 Document Object Mode 文档对象模型,表示由多层节点构成的文档. document: 表示每个文档的根节点,它的唯一子结点是 htm ...

  8. JS的DOM操作——style的操作

    对于JS操作文档中的元素,改变其的样式特征需要用到一个属性--style 常见操作:获取的元素点(·)style.xx(需要设置或修改的属性) 代码演示:例如修改div块的背景颜色 <style ...

  9. js之dom操作练习 ---- js篇

    一.自动计数器 <html> <head> <script type="text/javascript"> var c=0 var t func ...

最新文章

  1. The bean 'xxxx.FeignClientSpecification', defined in null, could not be registered. A bean with that
  2. 在wpf中运行EXE文件
  3. Delphi下利用WinIo模拟鼠标键盘详解
  4. 如何添加ORACLE 的 ODBC
  5. 10 分钟学会 5 个酷炫 Linux 命令
  6. 如何用matlab消除谐波,如何在含有整次谐波和非整次谐波的信号中去除整次谐波?...
  7. 线性动态电路的复频域分析
  8. 锁屏面试题百日百刷-VUE篇(一)
  9. 一个转行学习前端的初学者,应该如何计划自己的学习规划?
  10. SSM框架(Spring + Spring MVC + Mybatis)搭建
  11. 反射系数、驻波比、S参数之间的关系!
  12. 微信号,手机号,邮箱验证格式
  13. html文件svchost,解决html文件的DropFileName = svchost.exe木马
  14. vue 电视看板_基于Vue的拖放看板
  15. 模拟题【枚举计数】咒语
  16. (五)SGE 命令 (1)qsub
  17. 设计模式之观察者模式(Observable与Observer)
  18. h3c无线管理 dns服务器,H3C FIT AP与AC连接时三种的注册流程
  19. 孟岩:区块链的原则与价值观
  20. Linux负载均衡脚本,linux负载均衡软件设置(一)

热门文章

  1. 按钮自动发光用html怎么弄,HTML+CSS+JS发光开关按钮
  2. DataGrid 数据绑定使用小结二(自定义列)
  3. 推荐10款设计软件,全是设计大牛收藏夹里的
  4. 蓝桥杯 算法训练 Cowboys
  5. 构建云视频平台的七种武器分别包括长生剑、孔雀翎、碧玉刀、多情环、离别钩、霸王枪、拳头,这七种武器分别对应的是什么技术呢?该文将揭晓答案。
  6. wildfly常用配置说明
  7. redis事件通知(notify-keyspace-events Ex)
  8. SSLHandshakeException: No appropriate protocol
  9. http请求报错SSLError: HTTPSConnectionPool:Max retries exceeded with url
  10. 小白MAC下安装Caffe 2019最新血泪史