[英]Vanilla JavaScript equivalent of jQuery(…).parent().nextAll(selector)
我正在嘗試使用 vanilla JavaScript 選擇器(不使用 jQuery)來獲得如下所示的相同選擇:
$('[data-automationid=pictureupload_1]').parent().nextAll('input[type=text]')
有人可以幫幫我嗎? 我一直在掙扎。
據我所知,DOM 中沒有nextAll
方法,因此在不使用 jQuery 的情況下這樣做有點棘手。
我們可以使用生成器來迭代和過濾nextElementSibling
如下所示:
function* myNextAll(e, selector) {
while (e = e.nextElementSibling) {
if ( e.matches(selector) ) {
yield e;
}
}
}
let e1 = document.querySelector("[data-automationid=pictureupload_1]").parentElement;
let siblings = [...myNextAll(e1, "input[type=text]")];
document.querySelector('[data-automationid=pictureupload_1]')
選擇起始節點。parentElement.children
獲取父節點中的所有兄弟節點(包括父節點本身)。為了演示迭代結果並通過測試類更改背景。
如果你想試試: https : //jsfiddle.net/7p8wt4km/2/
let result = []; let par = document.querySelector('[data-automationid=pictureupload_1]').parentElement; let sibling = par.parentElement.children; let found = false; for (let i=0; i< sibling.length; i++) { if (!found && sibling[i] ===par) { found = true; continue; } else if (found) { let sib = sibling[i]; if (sib.nodeName !== 'INPUT' || sib.nodeType!= 1) continue; result.push(sib); } } result.forEach(el => { el.classList.add('test');});
.test { background: green; }
<div> <div> Sibling 0 </div> <div> Parent <div data-automationid='pictureupload_1'> pictureupload_1 </div> </div> <input type='text'> <div type='text'> Sibling 2 </div> <input type='test'> <input type='checkbox'> </div>
您可以嘗試使用我的代碼獲取索引元素
const getIndex = (node, groupNode) => {
return [...groupNode].indexOf(node);
}
Element.prototype.nextAll = function(){
var allChildren = this.parentNode.children;
var index = getIndex(this, allChildren);
allChildren = [...allChildren].filter((item) => {
return getIndex(item, allChildren) > index;
});
return allChildren;
}
正常的jQuery
選擇器函數和parent
方法應該是清楚的:
document.querySelector("[data-automationid=pictureupload_1]").parentNode
nextAll
目前沒有一個原生的 JavaScript 等價物,但我們可以用原生 DOM 方法制作一個。 有兩種方法可以接近它:
使用.parentNode.children
可以部分實現獲取兄弟.parentNode.children
。 但是不要擔心選擇父元素本身,因為按 DOM 順序過濾很容易。 這使用Node.prototype.compareDocumentPosition
和Element.prototype.matches
。 我還包含了一些可選的鏈接,這樣如果parentReference === document
, parentReference.parentNode.children
不會拋出錯誤。 那么它默認為一個空數組。
const selectParentMatchingNextSiblings = (jQuerySelector, siblingSelector) => {
const parentReference = document.querySelector(jQuerySelector).parentNode;
return Array.from(parentReference.parentNode?.children ?? [])
.filter((element) => parentReference.compareDocumentPosition(element) & Document.DOCUMENT_POSITION_FOLLOWING && element.matches(siblingSelector));
};
selectParentMatchingNextSiblings("[data-automationid=pictureupload_1]", "input[type=text]");
Range API還可用於文檔順序比較。
const selectParentMatchingNextSiblings = (jQuerySelector, siblingSelector) => {
const parentReference = document.querySelector(jQuerySelector).parentNode,
nextSiblings = document.createRange();
nextSiblings.setStartAfter(parentReference);
nextSiblings.setEndAfter(parentReference.parentNode?.lastElementChild ?? parentReference);
return Array.from(parentReference.parentNode?.children ?? [])
.filter((element) => nextSiblings.comparePoint(element, 0) === 0 && element.matches(siblingSelector));
};
selectParentMatchingNextSiblings("[data-automationid=pictureupload_1]", "input[type=text]");
請注意,此選項不適用於"html"
作為第一個選擇器。
const selectMatchingNextSiblings = (jQuerySelector, siblingSelector) => {
const parentReference = document.querySelector(jQuerySelector).parentNode,
result = [];
let currentElement = parentReference.nextElementSibling;
while(currentElement){
if(currentElement.matches(siblingSelector)){
result.push(currentElement);
}
currentElement = currentElement.nextElementSibling;
}
return result;
};
selectParentMatchingNextSiblings("[data-automationid=pictureupload_1]", "input[type=text]");
這應該是不言自明的。 其他答案中的選項也很好。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.