我想向放置在某个元素块后面的每个按钮添加一些事件侦听器。如果单击此按钮,将返回上一个元素块中的所有元素类。
我在这里https://gist.github.com/cssence/41c8279810b1db71670d.js
找到了从NodeList获取类的脚本for (var k = 0; k < trigger.length; k++) {
trigger[k].addEventListener('click', function(e) {
nav.classList.toggle('hidden');
(function listAllUsedClassNames() {
var classNames = {};
Array.prototype.forEach.call(this.previousElementSibling.querySelectorAll("*"), function(element) {
if (typeof element.className === "string") {
element.className.split(" ").forEach(function(className) {
if (className) {
classNames[className] = true;
}
});
};
});
return Object.keys(classNames);
}());
}, false);
}
我希望某个数组包含单击按钮后返回的上一个块的所有类。如果结果是唯一的并且没有重复的项目,那会更好。
答案 0 :(得分:0)
要获取上一个元素,请使用previousElementSibling
。遍历childNodes
以使用classList
获得元素的类。
let classes = [];
document.querySelectorAll('button')
.forEach(button => {
button.addEventListener('click', function() {
classes = [];
const prev = this.previousElementSibling;
classes.push(...prev.classList);
prev.childNodes.forEach(child => {
if(child.nodeType == 3) return; // Ignore text node
classes.push(...child.classList);
})
console.log(classes);
});
});
<div class="first">
<p class="childOfFirst">Lorem ipsum dolor sit amet consectetur, adipisicing elit. Repudiandae totam dicta libero vero dolore aperiam consectetur. Non veritatis quo praesentium!</p>
</div>
<button>Button1</button>
<div class="second">
<p class="childOfSecond">Lorem ipsum dolor sit amet consectetur adipisicing elit. Aspernatur, hic.</p>
</div>
<button>Button2</button>
要进行多次嵌套,请使用recursion
let classes = [];
document.querySelectorAll('button')
.forEach(button => {
button.addEventListener('click', function() {
classes = [];
const prev = this.previousElementSibling;
if(prev.children.length > 0) {
const output = getNestedClasses([...prev.children]);
classes.push(...prev.classList, ...output);
console.log('With Duplicates', classes);
const uniqueClassList = removeDuplicateClasses(classes)
console.log('Without Duplicates', uniqueClassList);
}
});
});
function getNestedClasses(childrens) {
return childrens.reduce((accu, ele) => {
if(ele.children.length > 0) {
accu.push(...ele.classList);
return accu.concat(getNestedClasses([...ele.children]));
} else {
return accu.concat([...ele.classList]);
}
}, []);
}
function removeDuplicateClasses(classArr) {
return Object.keys(classArr.reduce((accu, name) => {
accu[name] += (accu[name] || 0);
return accu;
}, {}));
}
<div class="first">
<p class="firstChild">First Child
<span class="firstGrandChild">First Grand Child</span>
<span class="secondGrandChild">Second Grand Child</span>
</p>
<p class="secondChild duplicate">Second Child</p>
<p class="duplicate"></p>
<p class="thirdChild">Third Child</p>
</div>
<button>Button1</button>