如何将所有包含连字符/破折号(?)的类应用于任何 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 =&gt; 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 中的数组中?的主要内容,如果未能解决你的问题,请参考以下文章

如何防止 LaTeX 连字符包含破折号的单词?

如何将破折号 (-) 的所有实例替换为 pandas 数据帧中字符串中间的数字零 (0)?

使用 lodash _.words 时如何不分隔破折号/连字符?

如何从字符串中获取某些内容

jQuery 事件命名空间可以包含破折号吗?

带有破折号/连字符的架构名称 i HyperSQL