Comment utiliser du javascript pur pour sélectionner toutes les .dummy
classes mais PAS THIS
? J'ai cherché un moment mais je ne trouve pas la réponse que je veux.
Par exemple. si je clique sur le premier .dummy
div, je veux sélectionner tous les .dummy
div mais pas celui sur lequel j'ai cliqué.
JQuery moyen de réaliser est comme ci-dessous,
var $dummy = $('.dummy');
$dummy.on('click', function(){
$dummy.not(this).......
});
Mais j'aimerais savoir comment y parvenir en utilisant du javascript pur
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>
4 réponses
Étend l'objet intégré "NodeList" comme suit:
//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)'));
});
});
<div class="dummy">One</div>
<div class="dummy">Two</div>
<div class="dummy">Three</div>
<div class="dummy">Four</div>
Vous pouvez l'utiliser comme vous l'avez écrit.
Chaque élément a ses frères et sœurs dans une LinkedList attachée à this.previousSibling
et this.nextSibling
. Bien que vous puissiez filtrer après avoir appelé à nouveau querySelectorAll, je voulais montrer une option où vous n'avez pas besoin d'appeler à nouveau les recherches. De plus, vous pouvez être sûr qu'il s'agit bien de frères et sœurs et non d'autres .dummy
sur la page (vous pouvez également le faire en définissant le contexte approprié pour 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);
});
});
<div>
<div class="dummy">One</div>
<div class="dummy">Two</div>
<div class="dummy">Three</div>
<div class="dummy">Four</div>
</div>
Vous pouvez simplement faire une boucle sur les éléments et utiliser un 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>
Alternativement aux réponses déjà données (qui sont tout à fait utilisables mais pas nécessairement équivalentes), si les éléments ont un autre attribut d'identification, vous pouvez l'utiliser comme ceci:
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>
Questions connexes
Questions liées
De nouvelles questions
javascript
Pour des questions concernant la programmation dans ECMAScript (JavaScript / JS) et ses divers dialectes / implémentations (hors ActionScript). Veuillez inclure toutes les balises pertinentes dans votre question; par exemple, [node.js], [jquery], [json], etc.