如何将所有包含连字符/破折号(?)的类应用于任何 DOM 元素并将它们保存到 JavaScript 中的数组中?
Posted
技术标签:
【中文标题】如何将所有包含连字符/破折号(?)的类应用于任何 DOM 元素并将它们保存到 JavaScript 中的数组中?【英文标题】:How to get all classes containing hyphen/dash(?) applied to any DOM element and save them into array in JavaScript? 【发布时间】:2020-03-01 03:04:59 【问题描述】:我失败的方法:
var getClasses = [];
var classesContain = [];
document.querySelectorAll('*').forEach( x =>
var y = x.className.split(' ');
getClasses.push(y);
);
getClasses.forEach( c =>
if(c.contains('-'))
classesContain.push(c);
);
【问题讨论】:
没有contains()
方法,但是有includes()
方法。
【参考方案1】:
您的尝试非常接近工作。问题是您将 array 推入 getClasses
而不是单个类,并且字符串和数组都没有标准的 contains
方法(有 includes
,这可能就是您的意思)。此外,如果您只想要包含-
的内容,您可以提前过滤掉它们:
let classesWithDash = new Set();
document.querySelectorAll('*').forEach(element =>
for (const cls of element.className.split(' ').filter(name => name.includes("-")))
classesWithDash.add(cls);
);
// Now, `classesWithDash` is a set containing the class names with dashes
// If you want an array:
classesWithDash = [...classesWithDash];
现场示例:
let classesWithDash = new Set();
document.querySelectorAll('*').forEach(element =>
for (const cls of element.className.split(' ').filter(name => name.includes("-")))
classesWithDash.add(cls);
);
// Now, `classesWithDash` is a set containing the class names with dashes
// If you want an array:
classesWithDash = [...classesWithDash];
console.log(classesWithDash);
<div class="foo foo-bar"></div>
<div class="another-one"></div>
<div class="nodash"></div>
(我一直不明白为什么Set
没有addAll
方法,或者至少像push
那样接受多个值给add
...) p>
【讨论】:
Set.prototype.add = (addImpl => function add (value, ...values) addImpl.call(this, value); for (const value of values) addImpl.call(this, value); return this; )(Set.prototype.add);
多田! (编辑以保持零参数的向后兼容性)
@PatrickRoberts - 是的。一个人可以添加它(呃,没有双关语),我只是担心它一开始就没有。也许我会建议addAll
,尽管答案通常是“你可以在用户空间处理它”。 (由于规范中没有 add
抛出第二个参数,因此现在无法追溯更新。)
我想最好的推论是在 ES6 容器类的规范中添加一个 concat()
方法,尽管我从来都不喜欢 Symbol.isConcatSpreadable
语义......
@PatrickRoberts - 我可能应该让你校对这本书。 :-D
我通过这个得到TypeError: element.className.split is not a function
。我想这是我的错,但我不知道为什么?【参考方案2】:
将document.querySelectorAll()
与attribute selector 结合使用,以获取类中包含(=*
) 连字符的所有元素。使用Array.from()
将结果转换为数组。现在使用Array.flatMap()
迭代元素,获取classlist
并转换为数组,并过滤掉不包含连字符的类。使用 Set 使项目唯一,并传播回数组。
const result = [...new Set( // use a Set to get an array of unique items
Array.from(document.querySelectorAll('[class*="-"]')) // select all elements with classes that contain hyphens
.flatMap(el => Array.from(el.classList).filter(c => c.includes('-'))) // create an array of all classes with hyphens
)]
console.log(result)
<div class="something a-b something-else x-y"></div>
<div class="something"></div>
<div class="a-b c-d"></div>
【讨论】:
【参考方案3】:您没有意识到的是,您正在将一个类数组推入您的getClasses
数组。所以你最终得到了一个数组数组,也就是一个二维数组。
另外请注意,您可以在一个步骤中提取类并仅过滤那些包含破折号的类,而不必处理列表两次。
var classesContain = [];
document.querySelectorAll('*').forEach(x =>
var y = (x.className || '').split(/\s+/g); // use a regex to cater for multiple spaces
y.forEach(className =>
if (className.includes('-'))
classesContain.push(className);
);
);
console.log('Final class list: ', classesContain);
<div class="foo-bar bar-baz foo">
<div class="foo-baz">
<span class="single">Example markup</span>
</div>
</div>
【讨论】:
我通过这个得到TypeError: x.className.split is not a function
。我想这是我的错,但我不知道为什么?
@RE666 我的错,我完全忘记了不是每个元素都有一个类!我更新了我的代码以适应这种情况。原因是如果没有类,element.className
将为空或未定义。您不能在undefined
上致电.split()
。 :-)
@Patrick Roberts 感谢代码审查!相应地更新了我的答案。以上是关于如何将所有包含连字符/破折号(?)的类应用于任何 DOM 元素并将它们保存到 JavaScript 中的数组中?的主要内容,如果未能解决你的问题,请参考以下文章
如何将破折号 (-) 的所有实例替换为 pandas 数据帧中字符串中间的数字零 (0)?