如何从前一个元素的 NodeList 中获取所有类名?
Posted
技术标签:
【中文标题】如何从前一个元素的 NodeList 中获取所有类名?【英文标题】:How to get all classname from previous element's NodeList? 【发布时间】:2019-10-12 17:33:40 【问题描述】:我想为放置在某个元素块之后的每个按钮添加一些事件侦听器。如果单击,此按钮旨在返回上一个元素块中的所有元素类。
我在这里找到了从 NodeList 获取类的脚本,https://gist.github.com/cssence/41c8279810b1db71670d.js
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);
我想要一些数组包含单击按钮后返回的前一个块的所有类。如果结果是唯一的并且没有任何重复项会更好。
【问题讨论】:
你也想要前一个元素的嵌套元素类吗? 是否有任何解决方案,所以结果是唯一的,而不是重复的。我想在这里使用数组来获取一些元素样式。 您应该在发布问题时详细说明要求。 是的,我想要前一个元素的嵌套元素类。与 DOM 树一样深。但没有重复值。 【参考方案1】:要获取上一个元素,请使用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>
【讨论】:
嗨,@randomSoul,在我在深度 DOM 树中测试它们之后,因为每个父母都有三四个孩子,每个孩子都有自己的孩子。出现错误:Uncaught TypeError: classes.push is not iterable (cannot read property Symbol(Symbol.iterator)) @ian - 如果有多个嵌套,第一个代码 sn-p 用于一级嵌套,请使用递归。我还添加了用于多个嵌套的代码以删除重复的类。见编辑。以上是关于如何从前一个元素的 NodeList 中获取所有类名?的主要内容,如果未能解决你的问题,请参考以下文章
在javascript将NodeList作为Array数组处理的方法