当前位置: 首页 > 知识库问答 >
问题:

如何在JavaScript中动态声明选择器?

韦阳辉
2023-03-14

我有重复的变量声明,我认为它们可以通过for循环来改进,但是我的尝试失败了。

我尝试了数组的for-loop声明器,但我的语法不起作用。

我有一个“工作代码”:


<div class ="menu1 item1-1"></div>
<div class ="menu1 item1-2"></div>
<div class ="menu1 item1-3"></div>
<div class ="menu1 item1-4"></div>

<div class ="menu2 item2-1"></div>
<div class ="menu2 item2-2"></div>
<div class ="menu2 item2-3"></div>
<div class ="menu2 item2-4"></div>

<div class ="menu3 item3-1"></div>
<div class ="menu3 item3-2"></div>
<div class ="menu3 item3-3"></div>
<div class ="menu3 item3-4"></div>

<div class ="menu4 item4-1"></div>
<div class ="menu4 item4-2"></div>
<div class ="menu4 item4-3"></div>
<div class ="menu4 item4-4"></div>


var menu1 = document.getElementsByClassName('menu1');
var menu2 = document.getElementsByClassName('menu2');
var menu3 = document.getElementsByClassName('menu3');
var menu4 = document.getElementsByClassName('menu4');

for (let i = 1; i < menu1.length; i++) {

    menu1[i].addEventListener('click', function(){ menu1[i].classList.add("test"); });
}
for (let i = 1; i < menu2.length; i++) {

    menu2[i].addEventListener('click', function(){ menu2[i].classList.add("test"); });
}
for (let i = 1; i < menu3.length; i++) {

    menu3[i].addEventListener('click', function(){ menu3[i].classList.add("test"); });
}
for (let i = 1; i < menu4.length; i++) {

    menu4[i].addEventListener('click', function(){ menu4[i].classList.add("test"); });
}


我试图减少它是这样的:


var MENU = [];

for (let i = 1; i <= 4; i++) {

  MENU.push("menu" + i + =document.getElementsByClassName('menu' + i +));

}
for (let j = 1; j < 5; j++) {
    for (let i = 0; i < MENU[j].length; i++) {
        MENU[j][i].addEventListener('click', function(){ MENU[j][i].classList.add("test"); });
    }
}

预期结果:

与“工作代码”相同的结果:

当我单击“menu1”div时:


<div class ="menu1 item1-1 test"></div>
<div class ="menu1 item1-2 test"></div>
<div class ="menu1 item1-3 test"></div>
<div class ="menu1 item1-4 test"></div>

<div class ="menu2 item2-1"></div>
<div class ="menu2 item2-2"></div>
<div class ="menu2 item2-3"></div>
<div class ="menu2 item2-4"></div>

<div class ="menu3 item3-1"></div>
<div class ="menu3 item3-2"></div>
<div class ="menu3 item3-3"></div>
<div class ="menu3 item3-4"></div>

<div class ="menu4 item4-1"></div>
<div class ="menu4 item4-2"></div>
<div class ="menu4 item4-3"></div>
<div class ="menu4 item4-4"></div>

实际错误消息:“意外标记=”“未捕获的TypeError:菜单[0][i].AddEventListener不是函数”

编辑:我发现了一个巨大的语法错误,已经修复了,但我现在得到了这个错误。

编辑2:我的问题太公开了,不太具体,我缩小了范围,修正了一些评论建议的语法。

编辑3:我正在努力:

单击一个“Menu1”元素以选择所有“Menu1”元素。单击一个“menu2”元素以选择所有“menu2”元素。单击一个“Menu3”元素以选择所有“Menu3”元素。单击一个“Menu4”元素以选择所有“Menu4”元素。

共有3个答案

马欣荣
2023-03-14

为什么不给他们另外一个特殊属性,比如 some Html content

徐涵亮
2023-03-14

向每个menupanl等添加泛型类,例如:menu。以便您的元素看起来像:

<div class="menu menu1"></div>
<div class="menu menu2"></div>
<div class="menu menu3"></div>
<div class="menu menu4"></div>

现在您可以使用单个选择器选择所有元素。

var menus = document.getElementsByClassName('menu');
console.log(menus[0]); // <div class="menu menu1"></div>
console.log(menus[1]); // <div class="menu menu2"></div>
console.log(menus[2]); // <div class="menu menu3"></div>
console.log(menus[3]); // <div class="menu menu4"></div>

并且它们存储在HTMLCollection中,您可以使用for循环来循环该HTMLCollection

for (var i = 0; i < menus.length; i++) {
    console.log(menus[i]); // Logs each <div class="menu"> element.
}

查看MDN的文档以查看有关如何使用getElementsByClassName方法的更多示例。

楚煜
2023-03-14

可以使用QuerySelectorAll

类似这样的事情:

const selector = '';
for (let i = 1; i <= 4; i++) {
  selector += `${selector ? ', ' : ''}menu${i}, panel${i}, navprev${i}, navrtrn${i}, navnext${i}`
}

document.querySelectorAll(selector).forEach(element => {
  element.addEventListener('click', (event) => {
    // check if it is a menu:
    if (event.target.matches('[class^=menu]')) {
       // a menu was clicked
    }
  });
});

如果您不想更改任何其他代码,可以这样做:

const classNamePrefixes = ['menu', 'panel', 'navprev', 'navrtrn', 'navnext'];
const varNameAndClassNamePrefix = classNamePrefixes.map((cnp) => {
  const varName = cnp.replace('nav', '').replace('panel', 'panl');
  return {
    varName,
    cnp
  };
});

for (let i = 1; i <= 4; i++) {
  varNameAndClassNamePrefix.forEach(({ varName, cnp }) => {
     window[`${varName}${i}`] = document.getElementsByClassName(`${cnp}${i}`)
  });
}
 类似资料:
  • 本文向大家介绍在SAP ABAP中动态声明,包括了在SAP ABAP中动态声明的使用技巧和注意事项,需要的朋友参考一下 我认为对于您的实现,您可以动态地声明一个内部表。

  • 给定一个对象 我可以定义一个新对象,其字段取决于s的内容, 说些像 然后字段d的值取决于s.a(d的值取决于是否定义了s.a)。 如何根据s的值排除对象中的字段,类似于 但这不起作用。。。 我知道这可以通过两个if来实现,但我正在寻找一个优雅的解决方案 我的物体非常大,所以我不想做类似的事情 编辑我看到了各种各样的解决方案,我正在寻找一种单一/变化最小且可读的解决方案。类似于惯用javascrip

  • 问题内容: 我想问一个关于Java的问题。我有一个用户定义的对象类,学生,它有2个数据成员,名称和ID。在另一个类中,我必须声明那个object [](例如)。但是,我不知道对象数组的大小。是否可以声明对象数组但不知道大小?谢谢。 问题答案: 用户。添加新元素时,它将自动扩展。以后,您可以根据需要将其转换为数组。 作为另一个选择(不确定您到底想要什么),您可以声明字段,而不必立即对其进行初始化。

  • 问题内容: 我想选择列名,但我不知道表结构是否会提前更改,因此它可能会发生变化,因此我不能只对带有列名的select语句进行硬编码。我也不想选择每一列。有没有简单的方法可以做到这一点? 我的想法是这两个查询的某种组合,但是我的SQL并不是那么好。 我尝试使用子选择,但没有用。似乎什么都没发生,我没有收到错误,只是没有结果 也许我需要参加吗?..无论如何,任何帮助都将是很大的,谢谢 问题答案: 试试

  • 问题内容: 如何在JavaScript中创建名称空间,以使我的对象和函数不会被其他同名对象和函数覆盖?我使用了以下内容: 有没有更优雅或更简洁的方法? 问题答案: 我喜欢这个:

  • 问题内容: 如何在JavaScript中声明全局变量? 问题答案: 如果必须在生产代码中生成全局变量(应避免使用),请 始终 明确 声明它们: 虽然可以通过省略来定义全局变量(假设没有同名的局部变量),但这样做会生成 隐式 全局,这是一件不好的事情,并且在 严格模式下 会产生错误。