【问题标题】:Add eventListener to buttons to change class onmouseup/down将 eventListener 添加到按钮以更改类 onmouseup/down
【发布时间】:2018-02-09 00:36:01
【问题描述】:

我有几个红色和黑色按钮,我想将 'onmousedown' 和 'onmouseup' 事件添加到共享同一类的一组红色按钮(“按钮红色”)中。

onmousedown 我要更改添加类“opaque”,然后 onmouseup 再次删除它。

因此,onmousedown 已“选中”的红色按钮略微透明,而 onmouseup 恢复正常(红色)。其他按钮不受影响。

css

.button {
   background-color: black;
   color: white;
   height: 30px;
   width: 150px; 
   text-align: center;
}

.button.red {
  background-color: red;
}

.button.red.opaque { 
  opacity: 0.7;
}

javascript(到目前为止)

var classname = this.document.getElementsByClassName("button red");

for (var i = 0; i < classname.length; i++) { 
   classname[i].addEventListener('onmousedown', classList.add("opaque"), false);
   classname[i].addEventListener('onmouseup', classList.remove("opaque"), false);
}

【问题讨论】:

  • 欢迎来到 Stack Overflow,您的问题应包含a Minimal, Complete, and Verifiable example。 FWIW 你可以用 CSS 做到这一点。你用 JS 做这件事有什么原因吗?
  • 你能添加你的 HTML
  • 您的选择器错误。 .button red opaque 查找作为&lt;red&gt; 元素(不是类)的后代的&lt;opaque&gt; 元素(不是类),这些元素是使用button 类的元素的后代。应该是.button.red.opaque。与您的 .button red 选择器相同。
  • "button red" 不是类的有效名称。 getElementsByClassName 不支持同时选择多个类名,请使用 querySelectorAll() 和适当的 CSS 选择器。而.button red opaque 表示&lt;opaque&gt; 节点内的&lt;red&gt; 节点内的某个节点内的类button。你的意思可能是.button.red.opaque
  • getElementsByClassName 确实支持多个类名:developer.mozilla.org/en-US/docs/Web/API/Document/…

标签: javascript jquery css addeventlistener


【解决方案1】:

您只能使用 CSS 来做到这一点。

button {
  padding: 0.5rem 1rem;
  background-color: lightgray;
  border: 1px solid gray;
}

button:active {
  background-color: salmon;
  opacity: 0.5;
}
&lt;button&gt;Click Me!&lt;/button&gt;

要像现在这样在 JS 中解决这个问题,你需要解决一些问题。

如 cmets 中所述,getElementsByClassName() 有一个类型。我会使用querySelectorAll() 而不是getElementsByClassName(),因为它可以更灵活地选择元素。

classList 是 DOM 元素的属性,不能单独使用。做这个element.classList.add( 'class' ),而不是这个classList.add( 'class' )

您的 CSS 选择器不正确,即 .button red opaque 将尝试选择类为 .button 的元素,其中包含 &lt;red&gt; 的元素,而 &lt;opaque&gt; 的元素。

您的标记和选择器可能有问题,但我没有要验证的 HTML。我假设你的标记是我的例子。

var $btns = [].slice.call( document.querySelectorAll( '.button.red' ) );

$btns.map( function ( btn ) {

  btn.addEventListener( 'mousedown', function ( e ) {
    btn.classList.add( 'opaque' );
  } );

  btn.addEventListener( 'mouseup', function ( e ) {
    btn.classList.remove( 'opaque' );
  } );
  
} );
.button {
  padding: 0.5rem 1rem;
  background-color: lightgray;
  border: 1px solid gray;
}

.button.red {
  background-color: indianred;
}

.button.opaque {
  opacity: 0.5;
}
&lt;button class="button red"&gt;Click Me!&lt;/button&gt;

【讨论】:

  • 这是一个很好的解决方案,但没有回答 OP 关于他的代码的问题。
  • 很好,但没有回答实际问题。
  • 不错,后面我会添加JS解决方案。
【解决方案2】:

可以用 css 来做,但是这里有一个解决方案,可以在鼠标上移和下鼠标时添加 jquery 侦听器。

$('.button' + '.red').each(function() {
  $(this).mousedown(function() {
    $(this).toggleClass('opaque');
  });
  $(this).mouseup(function() {
    $(this).toggleClass('opaque');
  });
});
.button {
  background-color: black;
  color: white;
  height: 30px;
  width: 150px;
  text-align: center;
}

.red {
  background-color: red;
}

.black {
  background-color: black;
}

.opaque {
  opacity: 0.7;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="button red">Button</button>
<button class="button black">Button</button>

【讨论】:

  • 你可以用.button.red代替'.button' + '.red'并缓存$( this )而不是重复调用。
【解决方案3】:

演示

var form = document.forms.main;

form.addEventListener('mousedown', fade, false);
form.addEventListener('mouseup', fade, false);

function fade(e) {

  if (e.target !== e.currentTarget) {

      e.target.classList.toggle('opq');
  }
}
.btn {
  background-color: black;
  color: white;
  height: 30px;
  width: 50px;
  text-align: center;
  opacity: 1;
  cursor: pointer;
  border-radius: 10px;
  transition: all .5s ease;
}

.red {
  background-color: red;
  transition: all .5s ease
}

.btn.red.opq {
  opacity: 0.7;
  transition: all .5s ease
}
<form id='main'>

  <button class='red btn' type='button'>RED</button>
  <button class='red btn' type='button'>RED</button>
  <button class='btn' type='button'>BLK</button>
  <button class='red btn' type='button'>RED</button>
  <button class='btn' type='button'>BLK</button>
  <button class='red btn' type='button'>RED</button>
  <button class='btn' type='button'>BLK</button>
  <button class='red btn' type='button'>RED</button>
  <button class='btn' type='button'>BLK</button>
  <button class='red btn' type='button'>RED</button>
  <button class='btn' type='button'>BLK</button>
  <button class='btn' type='button'>BLK</button>
  <button class='red btn' type='button'>RED</button>
  <button class='btn' type='button'>BLK</button>
  <button class='red btn' type='button'>RED</button>
  <button class='red btn' type='button'>RED</button>
  <button class='btn' type='button'>BLK</button>
  <button class='red btn' type='button'>RED</button>
  <button class='btn' type='button'>BLK</button>
  <button class='red btn' type='button'>RED</button>
  <button class='btn' type='button'>BLK</button>
  <button class='red btn' type='button'>RED</button>
  <button class='btn' type='button'>BLK</button>
  <button class='red btn' type='button'>RED</button>
  <button class='btn' type='button'>BLK</button>
  <button class='btn' type='button'>BLK</button>
  <button class='red btn' type='button'>RED</button>
  <button class='btn' type='button'>BLK</button>
  <button class='red btn' type='button'>RED</button>
  <button class='red btn' type='button'>RED</button>
  <button class='btn' type='button'>BLK</button>
  <button class='red btn' type='button'>RED</button>
  <button class='btn' type='button'>BLK</button>
  <button class='red btn' type='button'>RED</button>
  <button class='btn' type='button'>BLK</button>
  <button class='red btn' type='button'>RED</button>
  <button class='btn' type='button'>BLK</button>
  <button class='red btn' type='button'>RED</button>
  <button class='btn' type='button'>BLK</button>
  <button class='btn' type='button'>BLK</button>

</form>

【讨论】:

  • 没有必要将按钮包裹在&lt;form&gt; 标签中。
  • 如果你使用 HTMLFormControlsCollection 这使得表单很容易处理,当 OP 扩展到按钮之外时,这是必要的。另外,为了利用冒泡,有必要将按钮包装在一个共同的祖先中(事件委托使得可以使用单个事件侦听器来处理覆盖无限量 event.targets 的事件。)
  • 这可能是真的,但如果按钮遍布整个页面怎么办?我也喜欢事件委托,但是如果祖先中有来自不同元素的多个 mouseupmousedown 事件怎么办?使用这个e.target.classList.toggle( 'opq', !e.target.classList.contains( 'opq' ) ); 摆脱 if 语句。
  • 你是对的,我习惯于为不止一个州写作,我完全忘记了.toggle(),更新谢谢。
  • e.stopPropagation() 用于混合事件和自定义eventTrigger() 如果它真的很混乱(这意味着我可能继承了某人的混乱)。
【解决方案4】:
var classname = this.document.getElementsByClassName("button red");

for (var i = 0; i < classname.length; i++) { 
  classname[i].addEventListener('mousedown', function () {
    this.classList.add("opaque")
  }, false);
  classname[i].addEventListener('mouseup', function () {
    this.classList.remove("opaque")
  }, false);
}

CSS:

.button {
   background-color: black;
   color: white;
   height: 30px;
   width: 150px;
   text-align: center;
}

.button.red {
  background-color: red;
}

.button.red.opaque { 
  opacity: 0.7;
}
  1. getElementByClassName 应该是 getElementsByClassName
  2. 您需要传递一个函数作为事件监听器的第二个参数
  3. 您需要为 classList 属性提供上下文
  4. 事件的正确名称是mousedownmouseup
  5. CSS 属性需要以分号结尾
  6. CSS 选择器不正确

【讨论】:

  • 这也行不通。将得到一个无法读取未定义的类列表的错误。
  • 正确,我刚刚修好了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-21
  • 2020-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-22
相关资源
最近更新 更多