如何通过单击对元素进行循环类更改?

问题描述 投票:3回答:4

有多个按钮。

按钮按钮必须更改其样式/类三次,而不更改其他按钮的样式。

var bt = document.getElementById('b1');  
var cl = ['cls cls1', 'cls cls2', 'cls cls3'];   
var current = 0;                     

bt.addEventListener ('click', function() {
  current++; 
  current %= cl.length; 
  bt.className = cl[current]; 
});
.cls  {margin:10px 0; padding:3px 30px; 
       border:1px solid gray; outline:0; cursor:pointer;}
.cls1 {background:gold;}
.cls2 {background:aqua;}
.cls3 {background:lime;}
<button class="cls cls1" id="b1">b1</button>
<button class="cls cls1" id="">b2</button>
<button class="cls cls1" id="">b3</button>

fiddle example 但适用于一个按钮'b1'逐个id。

如何通过id修改所有按钮的示例?

有没有一种方法没有id,纯粹的javascript上课? 谢谢。

javascript css
4个回答
3
投票

通过使用getElementById(),您只定位一个按钮,并将特定的id作为参数传递。

要将event附加到所有按钮,您必须先选择所有按钮。你可以使用querySelectorAll()。然后使用forEach()循环每个按钮并附加event

querySelectorAll()

Element方法querySelectorAll()返回一个静态(非实时)NodeList,表示与指定的选择器组匹配的文档元素列表。

forEach()

forEach()方法为每个数组元素执行一次提供的函数。

工作守则:

var bt = document.querySelectorAll('.cls.cls1');  
var cl = ['cls cls1', 'cls cls2', 'cls cls3'];                    
bt.forEach(function(b){
  var current = 0;    
  b.addEventListener ('click', function() {
    current++; 
    current %= cl.length; 
    b.className = cl[current]; 
  });
});
.cls  {margin:10px 0; padding:3px 30px; 
       border:1px solid gray; outline:0; cursor:pointer;}
.cls1 {background:gold;}
.cls2 {background:aqua;}
.cls3 {background:lime;}
<button class="cls cls1" id="b1">b1</button>
<button class="cls cls1" id="">b2</button>
<button class="cls cls1" id="">b3</button>

请注意:querySelectorAll()有一些浏览器问题。在这种情况下,您可以使用getElementsByClassName()尝试以下方式:

var bt = document.getElementsByClassName('cls');  
var cl = ['cls cls1', 'cls cls2', 'cls cls3'];                    
[].forEach.call(bt, function(b){
  var current = 0;    
  b.addEventListener ('click', function() {
    current++; 
    current %= cl.length; 
    b.className = cl[current]; 
  });
});
.cls  {margin:10px 0; padding:3px 30px; 
       border:1px solid gray; outline:0; cursor:pointer;}
.cls1 {background:gold;}
.cls2 {background:aqua;}
.cls3 {background:lime;}
<button class="cls cls1" id="b1">b1</button>
<button class="cls cls1" id="">b2</button>
<button class="cls cls1" id="">b3</button>

2
投票

这很简单:只需使用document.querySelectorAll('.cls')选择所有按钮,然后遍历NodeList集合并将click事件监听器附加到每个按钮:

var buttons = document.querySelectorAll('.cls');
var cl = ['cls cls1', 'cls cls2', 'cls cls3'];

Array.prototype.slice.call(buttons).forEach(function(button) {
  // Each button should have its own store for the current index
  var current = 0;

  // Add event listener
  button.addEventListener('click', function() {
    current++;
    current %= cl.length;
    button.className = cl[current];
  });
});

这样,您就不必担心为要应用此行为的所有按钮分配唯一ID。

笔记:

  • 使用Array.prototype.slice.call(<NodeList>),因为NodeList返回的document.querySelectorAll本身不是数组。这样做会将它转换为一个数组,你可以使用.forEach :)
  • 请记住为每个按钮指定其当前索引的“存储”。因此,您必须将var current = 0移动到循环中。

概念验证示例:

var buttons = document.querySelectorAll('.cls');
var cl = ['cls cls1', 'cls cls2', 'cls cls3'];

Array.prototype.slice.call(buttons).forEach(function(button) {
  // Each button should have its own store for the current index
  var current = 0;
  
  // Add event listener
  button.addEventListener('click', function() {
    current++;
    current %= cl.length;
    button.className = cl[current];
  });
});
.cls {
  color: white;
}

.cls1 {
  background-color: red;
}

.cls2 {
  background-color: green;
}

.cls3 {
  background-color: blue;
}
<button class="cls cls1" id="b1">b1</button>
<button class="cls cls1" id="">b2</button>
<button class="cls cls1" id="">b3</button>

如果你在ES6中写作很舒服,它会变得更好:

const buttons = document.querySelectorAll('.cls');
const cl = ['cls cls1', 'cls cls2', 'cls cls3'];

Array.from(buttons).forEach((button) => {
  // Each button should have its own store for the current index
  let current = 0;
  
  // Add event listener
  button.addEventListener('click', () => {
    current++;
    current %= cl.length;
    button.classList = cl[current];
  });
});
.cls {
  color: white;
}

.cls1 {
  background-color: red;
}

.cls2 {
  background-color: green;
}

.cls3 {
  background-color: blue;
}
<button class="cls cls1" id="b1">b1</button>
<button class="cls cls1" id="">b2</button>
<button class="cls cls1" id="">b3</button>

1
投票

而不是id,在querySelectorAll中使用tagname并使用forEach进行迭代(大多数逻辑保持相同)

var btns = document.querySelectorAll('button');
var cl = ['cls cls1', 'cls cls2', 'cls cls3'];
var current = 0;

Array.from(btns).forEach(bt => bt.addEventListener('click', function(e) {
  current++;
  current %= cl.length;
  e.currentTarget.className = cl[current];
}));

演示

var btns = document.querySelectorAll('button');
var cl = ['cls cls1', 'cls cls2', 'cls cls3'];
var current = 0;

Array.from(btns).forEach(bt => bt.addEventListener('click', function(e) {
  current++;
  current %= cl.length;
  e.currentTarget.className = cl[current];
}));
.cls1
{
   background-color: red;
}
.cls2
{
   background-color: blue;
}
.cls3
{
   background-color: green;
}
<button class="cls cls1" id="b1">b1</button>
<button class="cls cls1" id="">b2</button>
<button class="cls cls1" id="">b3</button>

1
投票

这里有四个概念可以帮到你:

1)您可以向元素询问其当前类,而不是使用计数器来跟踪状态。这样每个按钮都可以跟踪自己的状态,而不是每个按钮需要一个变量。

2)事件可能会冒泡。因此,如果您将单击处理程序放置在按钮的包装元素上,则所有按钮都将使用相同的事件,因此您只需添加所需数量的按钮,而无需为每个按钮添加事件。

3)所有事件在其回调中都有一个event参数。通过使用event.target,您可以直接引用所单击的元素。

4)所有元素都有一个classList对象,您可以使用它来检查有关其CSS类的各种事物。

因此,如果我们将这些结合起来,我们最终会得到这样的结果:

const DEFAULT_CLASSES = [ 'cls1', 'cls2', 'cls3' ];
document.querySelector( '#comp_buttons' ).addEventListener( 'click', event => {
	if ( event.target.nodeName === 'BUTTON' ) {
		const button = event.target;
		const cls_current = DEFAULT_CLASSES.find( cls => button.classList.contains( cls ) );
		const cls_index = DEFAULT_CLASSES.indexOf( cls_current );
		const cls_next = DEFAULT_CLASSES[ cls_index + 1 ] || DEFAULT_CLASSES[ 0 ];
		button.classList.replace( cls_current, cls_next );
	}
} );
.cls {
  color: white;
}

.cls1 {
  background-color: red;
}

.cls2 {
  background-color: green;
}

.cls3 {
  background-color: blue;
}
.cls4 {
  background-color: yellow;
}
<div id="comp_buttons">
	<button class="cls cls1">b1</button>
	<button class="cls cls1">b2</button>
	<button class="cls cls1">b3</button>
</div>

这种方法的最大优点是可以在div中添加任意数量的按钮,而无需更改事件处理程序。

您也可以添加任意数量的类,只要在css中定义类并将其名称放入DEFAULT_CLASSES数组中即可。这些类现在甚至可以有随机名称,sicne我们不依赖于计数器或数字来标识按钮的当前类。

© www.soinside.com 2019 - 2024. All rights reserved.