核心要點(diǎn)
-
NodeList.js 作為 jQuery 的 DOM 操作替代方案,提供類似的功能,但體積更?。▔嚎s后 4k),并利用了原生瀏覽器 API 的改進(jìn)。
-
與 jQuery 不同,NodeList.js 將節(jié)點(diǎn)數(shù)組視為單個(gè)節(jié)點(diǎn),從而實(shí)現(xiàn)更簡(jiǎn)潔的代碼和更輕松的 NodeList 對(duì)象操作。
-
NodeList.js 包含用于設(shè)置和獲取屬性、調(diào)用特定于元素的方法以及訪問(wèn) NodeList 中節(jié)點(diǎn)的特殊方法,以及等同于 jQuery 的
prevObject
屬性的owner
屬性。 -
NodeList.js 與特定版本以后的主流瀏覽器兼容(Firefox 6 、Safari 5.0.5 、Chrome 6 、IE 9 、Opera 11.6 ),并自動(dòng)更新以包含瀏覽器新增的方法/屬性。
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); }
近年來(lái),jQuery 已成為 Web 上事實(shí)上的 JavaScript 庫(kù)。它消除了許多跨瀏覽器的不一致性,并為客戶端腳本添加了一層受歡迎的語(yǔ)法糖。它抽象化處理的主要痛點(diǎn)之一是 DOM 操作,但自 jQuery 問(wèn)世以來(lái),原生瀏覽器 API 已得到顯著改進(jìn),“你可能不需要 jQuery” 的理念開(kāi)始流行起來(lái)。
原因如下:
- jQuery 包含許多您不需要或不使用的功能(因此其體積不必要地龐大)。
- jQuery 對(duì)太多人來(lái)說(shuō)承擔(dān)了太多功能。通常,較小的庫(kù)可以更好地完成某些任務(wù)。
- 就 DOM 操作而言,瀏覽器 API 現(xiàn)在可以完成 jQuery 大部分的功能。
- 瀏覽器 API 現(xiàn)在更加同步,例如使用
addEventListener
代替attachEvent
。
問(wèn)題何在?
問(wèn)題在于,與 jQuery 相比,使用原生(或純)JavaScript 進(jìn)行 DOM 操作可能很麻煩。這是因?yàn)槟仨毦帉懜嗳哂啻a,并處理瀏覽器無(wú)用的 NodeList。
首先,讓我們看看 MDN 對(duì) NodeList 的定義:
NodeList 對(duì)象是節(jié)點(diǎn)的集合,例如 Node.childNodes
和 document.querySelectorAll
方法返回的那些節(jié)點(diǎn)。
有時(shí)還存在動(dòng)態(tài) NodeList(這可能會(huì)令人困惑):
在某些情況下,NodeList 是動(dòng)態(tài)集合,這意味著 DOM 中的更改會(huì)反映在集合中。例如,Node.childNodes
是動(dòng)態(tài)的。
這可能是一個(gè)問(wèn)題,因?yàn)槟鸁o(wú)法分辨哪些是動(dòng)態(tài)的,哪些是靜態(tài)的。除非您從 NodeList 中移除每個(gè)節(jié)點(diǎn),然后檢查 NodeList 是否為空。如果為空,則表示您擁有一個(gè)動(dòng)態(tài) NodeList(這只是一個(gè)壞主意)。
此外,瀏覽器沒(méi)有提供任何有用的方法來(lái)操作這些 NodeList 對(duì)象。
例如,不幸的是,無(wú)法使用 forEach
循環(huán)遍歷節(jié)點(diǎn):
var nodes = document.querySelectorAll('div'); nodes.forEach(function(node) { // do something }); // 錯(cuò)誤:nodes.forEach 不是函數(shù)
因此,您必須執(zhí)行以下操作:
var nodes = document.querySelectorAll('div'); for(var i = 0, l = nodes.length; i < l; i++) { // do something with nodes[i] }
或者甚至只能使用“hack”:
[].forEach.call(document.querySelectorAll('div'), function(node) { // do something });
瀏覽器的原生 NodeList 只有一個(gè)方法:item
。它通過(guò)索引從 NodeList 返回一個(gè)節(jié)點(diǎn)。當(dāng)我們可以像使用數(shù)組一樣訪問(wèn)該節(jié)點(diǎn)(使用 array[index]
)時(shí),它完全沒(méi)用:
var nodes = document.querySelectorAll('div'); nodes.item(0) === nodes[0]; // true
這就是 NodeList.js 的用武之地——使使用瀏覽器原生 API 操作 DOM 變得像使用 jQuery 一樣容易,但僅需 4k 壓縮大小。
解決方案
我創(chuàng)建 NodeList.js 是因?yàn)槲乙恢笔褂迷?DOM API,但希望使它們更簡(jiǎn)潔,從而減少編寫代碼時(shí)的許多冗余(例如 for 循環(huán))。
NodeList.js 是原生 DOM API 的一個(gè)包裝器,它允許您操作節(jié)點(diǎn)數(shù)組(即我的 NodeList),就好像它是一個(gè)單個(gè)節(jié)點(diǎn)一樣。這為您提供了比瀏覽器原生 NodeList 對(duì)象更多的功能。
如果您覺(jué)得這不錯(cuò),請(qǐng)從官方 GitHub 存儲(chǔ)庫(kù)獲取 NodeList.js 的副本,并繼續(xù)閱讀本教程的其余部分。
用法:
選擇 DOM 節(jié)點(diǎn)很簡(jiǎn)單:
$$(selector);
// 返回我的 NodeList
此方法在后臺(tái)使用 querySelectorAll(selector)
。
但它與 jQuery 相比如何?
很高興您提出這個(gè)問(wèn)題。讓我們將原生 JS、jQuery 和 NodeList.js 進(jìn)行比較。
假設(shè)我們有三個(gè)按鈕:
讓我們將每個(gè)按鈕的文本更改為“點(diǎn)擊我”:
原生 JS:
var buttons = document.querySelectorAll('button'); // 返回瀏覽器無(wú)用的 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 視為單個(gè)節(jié)點(diǎn)。也就是說(shuō),我們引用了一個(gè) NodeList,并將它的 textContent
屬性設(shè)置為“點(diǎn)擊我”。然后,NodeList.js 將對(duì) NodeList 中的每個(gè)節(jié)點(diǎn)執(zhí)行此操作。很巧妙,對(duì)吧?
如果我們想要方法鏈(類似于 jQuery),我們會(huì)執(zhí)行以下操作,這將返回對(duì) NodeList 的引用:
$$('button').set('textContent', 'Click Me');
現(xiàn)在,讓我們向每個(gè)按鈕添加一個(gè)點(diǎn)擊事件監(jiān)聽(tīng)器:
原生 JS:
var buttons = document.querySelectorAll('button'); // 返回瀏覽器無(wú)用的 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'); // 或?qū)?jQuery 與原生混合使用 `classList`: this.classList.add('clicked'); });
NodeList.js:
$$('button').addEventListener('click', function() { this.classList.add('clicked'); });
好的,所以 jQuery 的 on
方法相當(dāng)不錯(cuò)。我的庫(kù)使用瀏覽器的原生 DOM API(因此是 addEventListener
),但這并不會(huì)阻止我們?yōu)樵摲椒▌?chuàng)建別名:
$$.NL.on = $$.NL.addEventListener; $$('button').on('click', function() { this.classList.add('clicked'); });
不錯(cuò)!這演示了我們添加自己方法的方式:
var nodes = document.querySelectorAll('div'); nodes.forEach(function(node) { // do something }); // 錯(cuò)誤:nodes.forEach 不是函數(shù)
NodeList.js 對(duì)數(shù)組方法的支持
NodeList.js 確實(shí)繼承自 Array.prototype
,但不是直接繼承,因?yàn)槟承┓椒ㄒ迅?,因此使用它們與 NodeList(節(jié)點(diǎn)數(shù)組)一起使用是有意義的。
push
和 unshift
例如:push
和 unshift
方法只能將節(jié)點(diǎn)作為參數(shù),否則會(huì)拋出錯(cuò)誤:
var nodes = document.querySelectorAll('div'); for(var i = 0, l = nodes.length; i < l; i++) { // do something with nodes[i] }
因此,push
和 unshift
都返回 NodeList 以允許方法鏈,這意味著它與 JavaScript 的原生 Array#push
或 Array#unshift
方法不同,后者接受任何內(nèi)容并返回?cái)?shù)組的新長(zhǎng)度。如果我們確實(shí)想要 NodeList 的長(zhǎng)度,我們只需使用 length
屬性。
這兩個(gè)方法,就像 JavaScript 的原生數(shù)組方法一樣,都會(huì)更改 NodeList。
concat
concat
方法將接受以下內(nèi)容作為參數(shù):
[].forEach.call(document.querySelectorAll('div'), function(node) { // do something });
concat
是一個(gè)遞歸方法,因此這些數(shù)組可以像我們希望的那樣深,并且會(huì)被展平。但是,如果傳遞的數(shù)組中的任何元素不是節(jié)點(diǎn)、NodeList 或 HTMLCollection,它將拋出錯(cuò)誤。
concat
返回一個(gè)新的 NodeList,就像 javascript 的 Array#concat
方法一樣。
pop
、shift
、map
、slice
、filter
pop
和 shift
方法都可以采用可選參數(shù),說(shuō)明要從 NodeList 中彈出或移位多少個(gè)節(jié)點(diǎn)。與 JavaScript 的原生 Array#pop
或 Array#shift
不同,后者總是彈出或移位數(shù)組中的一個(gè)元素,而不管傳遞什么作為參數(shù)。
如果每個(gè)映射值都是一個(gè)節(jié)點(diǎn),map
方法將返回一個(gè) NodeList;如果不是,則返回映射值的數(shù)組。
slice
和 filter
方法的作用與在真實(shí)數(shù)組中的作用一樣,但會(huì)返回一個(gè) NodeList。
由于 NodeList.js 沒(méi)有直接繼承自 Array.prototype
,因此如果在加載 NodeList.js 后向 Array.prototype
添加方法,則不會(huì)繼承該方法。
您可以在此處查看 NodeList.js 的其余數(shù)組方法。
特殊方法
NodeList.js 有四個(gè)獨(dú)特的方法,以及一個(gè)名為 owner
的屬性,它等同于 jQuery 的 prevObject
屬性。
get
和 set
方法:
某些元素具有特定于該類型元素的屬性(例如,錨標(biāo)記上的 href
屬性)。這就是為什么 $$('a').href
將返回未定義的原因——因?yàn)樗皇?NodeList 中每個(gè)元素都繼承的屬性。這就是我們?nèi)绾问褂?get
方法訪問(wèn)這些屬性的方法:
var nodes = document.querySelectorAll('div'); nodes.forEach(function(node) { // do something }); // 錯(cuò)誤:nodes.forEach 不是函數(shù)
set
方法可用于為每個(gè)元素設(shè)置這些屬性:
var nodes = document.querySelectorAll('div'); for(var i = 0, l = nodes.length; i < l; i++) { // do something with nodes[i] }
set
還返回 NodeList 以允許方法鏈。我們可以在 textContent
等方面使用它(兩者都等效):
[].forEach.call(document.querySelectorAll('div'), function(node) { // do something });
我們還可以在一次調(diào)用中設(shè)置多個(gè)屬性:
var nodes = document.querySelectorAll('div'); nodes.item(0) === nodes[0]; // true
以上所有操作都可以使用任意屬性完成,例如 style
:
var buttons = document.querySelectorAll('button'); // 返回瀏覽器無(wú)用的 NodeList for(var i = 0, l = buttons.length; i < l; i++) { buttons[i].textContent = 'Click Me'; }
call
方法
call
方法允許您調(diào)用特定于元素的方法(例如,視頻元素上的 pause
):
$('button').text('Click Me');
item
方法
item
方法等同于 jQuery 的 eq
方法。它返回一個(gè) NodeList,其中只包含傳遞索引的節(jié)點(diǎn):
$$('button').textContent = 'Click Me';
owner
屬性
owner
屬性等同于 jQuery 的 prevObject
。
$$('button').set('textContent', 'Click Me');
btns.style
返回樣式數(shù)組,而 owner
將返回 style
所映射的 NodeList。
NodeList.js 兼容性
我的庫(kù)與所有主要的新瀏覽器兼容,如下所述。
瀏覽器 版本
結(jié)論
現(xiàn)在我們終于可以使用有用的 NodeList 對(duì)象了!
對(duì)于大約 4k 的壓縮大小,您可以獲得上述所有功能以及更多功能,您可以在 NodeList.js 的 GitHub 存儲(chǔ)庫(kù)中了解所有這些功能。
由于 NodeList.js 使用瀏覽器作為依賴項(xiàng),因此無(wú)需進(jìn)行任何升級(jí)。每當(dāng)瀏覽器向 DOM 元素添加新方法/屬性時(shí),您都可以通過(guò) NodeList.js 自動(dòng)使用這些方法/屬性。所有這一切都意味著您唯一需要擔(dān)心的棄用是瀏覽器刪除的方法。這些通常是使用率非常低的方法,因?yàn)槲覀儾荒芷茐?Web。
那么您怎么看?您會(huì)考慮使用這個(gè)庫(kù)嗎?是否缺少任何重要功能?我很樂(lè)意在下面的評(píng)論中聽(tīng)到您的意見(jiàn)。
關(guān)于使用 NodeList.js 進(jìn)行 DOM 操作的常見(jiàn)問(wèn)題
NodeList 和 HTMLCollection 有什么區(qū)別?
NodeList 和 HTMLCollection 都是節(jié)點(diǎn)集合。它們之間的主要區(qū)別在于 NodeList 可以包含任何節(jié)點(diǎn)類型,而 HTMLCollection 是元素節(jié)點(diǎn)的集合。HTMLCollection 也是動(dòng)態(tài)的,這意味著當(dāng)文檔結(jié)構(gòu)發(fā)生更改時(shí),它會(huì)自動(dòng)更新。另一方面,NodeList 是靜態(tài)的,不會(huì)更新以反映文檔中的更改。
如何將 NodeList 轉(zhuǎn)換為數(shù)組?
您可以使用 Array.from()
方法或展開(kāi)運(yùn)算符將 NodeList 轉(zhuǎn)換為數(shù)組。以下是如何操作:
var nodes = document.querySelectorAll('div'); nodes.forEach(function(node) { // do something }); // 錯(cuò)誤:nodes.forEach 不是函數(shù)
為什么 jQuery 選擇器返回 prevObject 而不是普通元素?
jQuery 的鏈?zhǔn)綑C(jī)制通過(guò)在進(jìn)行更改之前存儲(chǔ)之前的對(duì)象來(lái)工作。這允許您使用 .end()
方法恢復(fù)到之前的狀態(tài)。如果您想獲取實(shí)際的 DOM 元素,可以使用 .get()
方法或數(shù)組表示法。
如何循環(huán)遍歷 NodeList?
您可以使用 for 循環(huán)、for...of 循環(huán)或 forEach()
方法循環(huán)遍歷 NodeList。這是一個(gè)使用 for 循環(huán)的示例:
var nodes = document.querySelectorAll('div'); for(var i = 0, l = nodes.length; i < l; i++) { // do something with nodes[i] }
jQuery 中 .prev() 方法有什么用?
jQuery 中的 .prev()
方法用于選擇所選元素的緊鄰前一個(gè)同級(jí)元素。如果提供了選擇器,則只有在匹配該選擇器時(shí)才會(huì)檢索前一個(gè)同級(jí)元素。
jQuery 在 2022 年仍然相關(guān)嗎?
雖然 jQuery 在發(fā)布時(shí)是一個(gè)改變游戲規(guī)則的東西,但現(xiàn)代 JavaScript 生態(tài)系統(tǒng)已經(jīng)發(fā)生了顯著變化。許多使 jQuery 受歡迎的功能現(xiàn)在都內(nèi)置于 JavaScript 本身。但是,jQuery 仍然被廣泛使用和維護(hù),它可能是某些項(xiàng)目的良好選擇。
如何從 NodeList 中選擇特定節(jié)點(diǎn)?
您可以使用數(shù)組表示法或 item()
方法從 NodeList 中選擇特定節(jié)點(diǎn)。以下是如何操作:
[].forEach.call(document.querySelectorAll('div'), function(node) { // do something });
我可以在 NodeList 上使用 map、filter 和 reduce 方法嗎?
NodeList 不是數(shù)組,因此它沒(méi)有像 map、filter 和 reduce 這樣的方法。但是,您可以將 NodeList 轉(zhuǎn)換為數(shù)組,然后使用這些方法。
querySelector 和 querySelectorAll 有什么區(qū)別?
querySelector
返回文檔中與指定的 CSS 選擇器匹配的第一個(gè)元素,而 querySelectorAll
返回與 CSS 選擇器匹配的所有元素的 NodeList。
如何檢查 NodeList 是否為空?
您可以通過(guò)檢查其 length
屬性來(lái)檢查 NodeList 是否為空。如果長(zhǎng)度為 0,則 NodeList 為空。以下是如何操作:
var nodes = document.querySelectorAll('div'); nodes.item(0) === nodes[0]; // true
以上是失去jQuery膨脹的詳細(xì)內(nèi)容。更多信息請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

熱AI工具

Undress AI Tool
免費(fèi)脫衣服圖片

Undresser.AI Undress
人工智能驅(qū)動(dòng)的應(yīng)用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover
用于從照片中去除衣服的在線人工智能工具。

Clothoff.io
AI脫衣機(jī)

Video Face Swap
使用我們完全免費(fèi)的人工智能換臉工具輕松在任何視頻中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費(fèi)的代碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
功能強(qiáng)大的PHP集成開(kāi)發(fā)環(huán)境

Dreamweaver CS6
視覺(jué)化網(wǎng)頁(yè)開(kāi)發(fā)工具

SublimeText3 Mac版
神級(jí)代碼編輯軟件(SublimeText3)

Java和JavaScript是不同的編程語(yǔ)言,各自適用于不同的應(yīng)用場(chǎng)景。Java用于大型企業(yè)和移動(dòng)應(yīng)用開(kāi)發(fā),而JavaScript主要用于網(wǎng)頁(yè)開(kāi)發(fā)。

JavascriptconcommentsenceenceEncorenceEnterential gransimenting,reading and guidingCodeeXecution.1)單inecommentsareusedforquickexplanations.2)多l(xiāng)inecommentsexplaincomplexlogicorprovideDocumentation.3)

JavaScript中的日期和時(shí)間處理需注意以下幾點(diǎn):1.創(chuàng)建Date對(duì)象有多種方式,推薦使用ISO格式字符串以保證兼容性;2.獲取和設(shè)置時(shí)間信息可用get和set方法,注意月份從0開(kāi)始;3.手動(dòng)格式化日期需拼接字符串,也可使用第三方庫(kù);4.處理時(shí)區(qū)問(wèn)題建議使用支持時(shí)區(qū)的庫(kù),如Luxon。掌握這些要點(diǎn)能有效避免常見(jiàn)錯(cuò)誤。

PlacingtagsatthebottomofablogpostorwebpageservespracticalpurposesforSEO,userexperience,anddesign.1.IthelpswithSEObyallowingsearchenginestoaccesskeyword-relevanttagswithoutclutteringthemaincontent.2.Itimprovesuserexperiencebykeepingthefocusonthearticl

JavaScriptIspreferredforredforwebdevelverment,而Javaisbetterforlarge-ScalebackendsystystemsandSandAndRoidApps.1)JavascriptexcelcelsincreatingInteractiveWebexperienceswebexperienceswithitswithitsdynamicnnamicnnamicnnamicnnamicnemicnemicnemicnemicnemicnemicnemicnemicnddommanipulation.2)

javascripthassevenfundaMentalDatatypes:數(shù)字,弦,布爾值,未定義,null,object和symbol.1)numberSeadUble-eaduble-ecisionFormat,forwidevaluerangesbutbecautious.2)

事件捕獲和冒泡是DOM中事件傳播的兩個(gè)階段,捕獲是從頂層向下到目標(biāo)元素,冒泡是從目標(biāo)元素向上傳播到頂層。1.事件捕獲通過(guò)addEventListener的useCapture參數(shù)設(shè)為true實(shí)現(xiàn);2.事件冒泡是默認(rèn)行為,useCapture設(shè)為false或省略;3.可使用event.stopPropagation()阻止事件傳播;4.冒泡支持事件委托,提高動(dòng)態(tài)內(nèi)容處理效率;5.捕獲可用于提前攔截事件,如日志記錄或錯(cuò)誤處理。了解這兩個(gè)階段有助于精確控制JavaScript響應(yīng)用戶操作的時(shí)機(jī)和方式。

Java和JavaScript是不同的編程語(yǔ)言。1.Java是靜態(tài)類型、編譯型語(yǔ)言,適用于企業(yè)應(yīng)用和大型系統(tǒng)。2.JavaScript是動(dòng)態(tài)類型、解釋型語(yǔ)言,主要用于網(wǎng)頁(yè)交互和前端開(kāi)發(fā)。
