[英]Vanilla JavaScript equivalent of jQuery(…).parent().nextAll(selector)
I'm trying to have a vanilla JavaScript selector (without using jQuery) to get the same selection as shown below:我正在尝试使用 vanilla JavaScript 选择器(不使用 jQuery)来获得如下所示的相同选择:
$('[data-automationid=pictureupload_1]').parent().nextAll('input[type=text]')
Can someone please help me?有人可以帮帮我吗? I've been struggling with it.
我一直在挣扎。
There is no nextAll
method in DOM as far as I know, so it is a bit tricky to do that without using jQuery.据我所知,DOM 中没有
nextAll
方法,因此在不使用 jQuery 的情况下这样做有点棘手。
We can use a generator to iterate and filter nextElementSibling
like this:我们可以使用生成器来迭代和过滤
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]')
to select the starting-node.document.querySelector('[data-automationid=pictureupload_1]')
选择起始节点。parentElement.children
all the siblings from the parent-node (including the parent itself).parentElement.children
获取父节点中的所有兄弟节点(包括父节点本身)。 For demonstration iterate over the result and change the background via test-class.为了演示迭代结果并通过测试类更改背景。
If you want try: https://jsfiddle.net/7p8wt4km/2/如果你想试试: 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>
You can try my code get with index element您可以尝试使用我的代码获取索引元素
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;
}
The normal jQuery
selector function and the parent
method should be clear:正常的
jQuery
选择器函数和parent
方法应该是清楚的:
document.querySelector("[data-automationid=pictureupload_1]").parentNode
nextAll
doesn't currently have a vanilla JavaScript equivalent, but we can make one out of native DOM methods. nextAll
目前没有一个原生的 JavaScript 等价物,但我们可以用原生 DOM 方法制作一个。 There are two ways of approaching it:有两种方法可以接近它:
Getting the set of siblings can be partially achieved with .parentNode.children
.使用
.parentNode.children
可以部分实现获取兄弟.parentNode.children
。 But don't worry about selecting the parent element itself, because filtering by DOM order is easy.但是不要担心选择父元素本身,因为按 DOM 顺序过滤很容易。 This uses
Node.prototype.compareDocumentPosition
and Element.prototype.matches
.这使用
Node.prototype.compareDocumentPosition
和Element.prototype.matches
。 I've also included some optional chaining so that if parentReference === document
, parentReference.parentNode.children
won't throw an error.我还包含了一些可选的链接,这样如果
parentReference === document
, parentReference.parentNode.children
不会抛出错误。 It defaults to an empty array, then.那么它默认为一个空数组。
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]");
The Range API can also be used for document order comparison. 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]");
Note that this one won't work with "html"
as the first selector.请注意,此选项不适用于
"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]");
This should be self-explanatory.这应该是不言自明的。 The options from the other answers are also fine.
其他答案中的选项也很好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.