如何使用纯JavaScript来选择所有.dummy
类但不是THIS
?
我搜索了一会儿但找不到我想要的答案。
e.g。如果我点击第一个.dummy
div,我想选择所有.dummy
div而不是我点击的div。
jQuery的实现方式如下,
var $dummy = $('.dummy');
$dummy.on('click', function(){
$dummy.not(this).......
});
但我想知道如何通过使用纯javascript来实现它
document.querySelectorAll('.dummy').forEach(function(e, i){
e.addEventListener('click', function(){
console.log(document.querySelectorAll('.dummy').not(this));
// WRONG not working, also querySelectorAll('.dummy:not(this)'));
});
});
<div class="dummy">One</div>
<div class="dummy">Two</div>
<div class="dummy">Three</div>
<div class="dummy">Four</div>
答案 0 :(得分:5)
您可以使用内置的Array.prototype.filter()
功能简单地过滤元素数组,以找到您要查找的内容;但是,document.querySelectorAll
返回节点列表对象,而不是数组。
棘手的部分是,您首先需要将Node List对象转换为数组,然后才能对其进行过滤。
这可以通过两种方式完成:
ES6方式(Spread Operator)。
[...document.querySelectorAll('.dummy')];
。
前ES6方式(Array.prototype.slice)
Array.prototype.slice.call(document.querySelectorAll('.dummy'));
。
您已经e
存储了对每个虚拟元素的引用,可以在事件侦听器中使用它来过滤掉匹配元素。
elements.filter(function(element) {
return element !== e;
});
document.querySelectorAll('.dummy').forEach(function(e, i){
e.addEventListener('click', function(){
var elements = [...document.querySelectorAll('.dummy')];
var otherElements = elements.filter(function(element) {
return element !== e;
});
console.log(otherElements);
});
});
&#13;
<div class="dummy">One</div>
<div class="dummy">Two</div>
<div class="dummy">Three</div>
<div class="dummy">Four</div>
&#13;
答案 1 :(得分:1)
除了已经给出的答案(它们非常有用但不一定等效),如果元素有其他识别属性,你可以这样使用:
document.querySelectorAll('.dummy').forEach(function(e, i){
e.addEventListener('click', function(event){
console.log(document.querySelectorAll('.dummy:not([myattr="' + event.target.getAttribute("myattr") + '"])'));
});
});
<div class="dummy" myattr="1">One</div>
<div class="dummy" myattr="2">Two</div>
<div class="dummy" myattr="3">Three</div>
<div class="dummy" myattr="4">Four</div>
答案 2 :(得分:1)
每个元素都在this.previousSibling
和this.nextSibling
上附加了LinkedList的兄弟姐妹中。虽然您可以在再次调用querySelectorAll后进行过滤,但我想显示一个您不需要再次调用查询的选项。此外,您可以确定这些实际上是兄弟姐妹,而不是页面上的其他.dummy
(您也可以通过为querySelectorAll
设置正确的上下文来实现此目的)
/**
* @param acc {Array} An array to push onto
* @param el {Node} The element to cycle over
*/
function getPrevSiblings(acc, el) {
if(el.previousSibling) {
// Ignores #text elements
if(el.previousSibling.nodeName !== "#text" ) {
acc.push(el.previousSibling);
}
return getPrevSiblings(acc, el.previousSibling)
}
return acc;
}
/**
* @param acc {Array} An array to push onto
* @param el {Node} The element to cycle over
*/
function getNextSiblings(acc, el) {
if(el.nextSibling) {
// Ignores #text elements
if(el.previousSibling.nodeName !== "#text" ) {
acc.push(el.nextSibling);
}
return getNextSiblings(acc, el.nextSibling)
}
return acc;
}
document.querySelectorAll('.dummy').forEach(function(e, i){
e.addEventListener('click', function(){
var prev = getPrevSiblings([], this)
var next = getNextSiblings([], this)
var allElsForLogging = [].concat(prev, next);
console.log(allElsForLogging);
});
});
&#13;
<div>
<div class="dummy">One</div>
<div class="dummy">Two</div>
<div class="dummy">Three</div>
<div class="dummy">Four</div>
</div>
&#13;
答案 3 :(得分:1)
扩展内置对象&#34; NodeList&#34;如下:
//Extends NodeList
NodeList.prototype.not = function ( cssSelectorOrNodeOrNodeList ) {
//Change object name(constructor.name) to "NodeList" from "Array" in console window
let list = ( () => { class NodeList extends Array {} return new NodeList(); } )(), excludes;
if ( typeof cssSelectorOrNodeOrNodeList === "string" ) excludes = document.querySelectorAll( cssSelectorOrNodeOrNodeList );
else if ( cssSelectorOrNodeOrNodeList instanceof NodeList ) excludes = cssSelectorOrNodeOrNodeList;
else if ( cssSelectorOrNodeOrNodeList instanceof Node ) excludes = [ cssSelectorOrNodeOrNodeList ];
if ( excludes === undefined || !excludes.length ) return this;
for ( const node of this ) {
let flag = true;
for ( const compare of excludes ) {
if ( node === compare ) {
flag = false;
break;
}
}
if ( flag ) list.push( node );
}
Object.setPrototypeOf( list, NodeList.prototype );
return list;
};
//Object information
{
let test = document.childNodes.not( document.body );
console.log( test.constructor.name ); //NodeList
console.log( test.constructor === NodeList ); //true
console.log( test instanceof NodeList ); //true
console.log( test instanceof Array ); //false
console.dir( test ); //NodeList .... not Array ....;
}
//Your test code
document.querySelectorAll('.dummy').forEach(function(e, i){
e.addEventListener('click', function(){
console.log(document.querySelectorAll('.dummy').not(this));
// WRONG not working, also querySelectorAll('.dummy:not(this)'));
});
});
&#13;
<div class="dummy">One</div>
<div class="dummy">Two</div>
<div class="dummy">Three</div>
<div class="dummy">Four</div>
&#13;
您可以像刚写的那样使用它。
答案 4 :(得分:0)
您可以循环回复元素并使用if
document.querySelectorAll('.dummy').forEach(function(e, i){
e.addEventListener('click', function(){
console.log(document.querySelectorAll('.dummy').forEach((e) => {
if (e !== this) {
e.style.color = 'red';
}
}));
});
});
<div class="dummy">One</div>
<div class="dummy">Two</div>
<div class="dummy">Three</div>
<div class="dummy">Four</div>