Добавьте прослушиватель событий к кнопкам, чтобы изменить класс onmouseup/down

У меня есть несколько красных и черных кнопок, и я хочу добавить события onmousedown и onmouseup к набору красных кнопок, которые имеют один и тот же класс («кнопка красная»).

onmousedown Я хочу изменить, добавить класс «непрозрачный», а 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);
}

person Shh    schedule 08.02.2018    source источник
comment
Добро пожаловать в Stack Overflow! Ваш вопрос должен содержать минимальный, полный и проверяемый пример. FWIW вы можете сделать это с помощью CSS. Есть ли причина, по которой вы делаете это с JS?   -  person hungerstar    schedule 08.02.2018
comment
Можете ли вы добавить свой HTML   -  person Gerardo BLANCO    schedule 08.02.2018
comment
Ваши селекторы ошибаются. .button red opaque ищет <opaque> элементов (не классов), которые являются потомками <red> элементов (не классов), которые являются потомками элементов, использующих класс button. Должно быть .button.red.opaque. То же самое с вашим селектором .button red.   -  person Scott Marcus    schedule 08.02.2018
comment
"button red" не является допустимым именем для класса. getElementsByClassName не поддерживает одновременный выбор по нескольким именам классов, используйте для этого querySelectorAll() с правильным селектором CSS. И .button red opaque означает узел <opaque> внутри узла <red> внутри некоторого узла с классом button. Вы, вероятно, имели в виду .button.red.opaque   -  person Thomas    schedule 08.02.2018
comment
и используйте точки с запятой в конце определений свойств в CSS, а не запятые   -  person Johannes    schedule 08.02.2018
comment
getElementsByClassName поддерживает несколько имен классов: developer.mozilla.org/en- США/документы/Интернет/API/Документ/   -  person sliptype    schedule 08.02.2018


Ответы (4)


Вы можете сделать это только с помощью CSS.

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

button:active {
  background-color: salmon;
  opacity: 0.5;
}
<button>Click Me!</button>

Чтобы решить эту проблему в JS, как вы делаете, вам нужно исправить пару вещей.

Как упоминалось в комментариях, был тип для getElementsByClassName(). Я бы использовал querySelectorAll() вместо getElementsByClassName(), потому что он более гибкий в том, как вы можете выбирать элементы.

classList является свойством элемента DOM и не может использоваться сам по себе. Делай это element.classList.add( 'class' ), а не это classList.add( 'class' ).

Ваши селекторы CSS были неверными, т. е. .button red opaque попытается выбрать элемент с классом .button, который содержит элемент <red>, содержащий элемент <opaque>.

Возможно, что-то не так с вашей разметкой и селекторами, но у меня нет вашего 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;
}
<button class="button red">Click Me!</button>

person hungerstar    schedule 08.02.2018
comment
Это хорошее решение, но оно не отвечает на вопрос ОП о его коде. - person Scott Marcus; 08.02.2018
comment
Отлично, но не отвечает на настоящий вопрос. - person epascarello; 08.02.2018
comment
Правда, JS-решение добавлю после. - person hungerstar; 08.02.2018

Это можно сделать с помощью 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>

person Gerardo BLANCO    schedule 08.02.2018
comment
Вы можете сделать .button.red вместо '.button' + '.red' и кэшировать $( this ) вместо повторного вызова. - person hungerstar; 08.02.2018

  • Нет необходимости в итерации (циклах)
  • Обернутые кнопки в теге <form>
  • Использование HTMLFormControlsCollection API для доступа кнопки
  • Использованы только 2 обработчика событий для 20 красных кнопок в сочетании с 20 черными кнопками с использованием Делегирование событий
  • CSS-анимация через transition имущество

Демо

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>

person zer00ne    schedule 08.02.2018
comment
Нет необходимости заключать кнопки в тег <form>. - person hungerstar; 08.02.2018
comment
Это необходимо, если вы используете HTMLFormControlsCollection, что упрощает работу с формами, когда OP выходит за рамки кнопок. Кроме того, необходимо обернуть кнопки в общего предка, чтобы использовать всплытие (делегирование событий, которое позволяет использовать один прослушиватель событий для события, охватывающего неограниченное количество event.targets.) - person zer00ne; 08.02.2018
comment
Это может быть правдой, но что, если кнопки разбросаны по всей странице? Мне также нравится делегирование событий, но что, если есть несколько событий mouseup и mousedown из разных элементов в предке? Используйте этот e.target.classList.toggle( 'opq', !e.target.classList.contains( 'opq' ) );, чтобы избавиться от оператора if. - person hungerstar; 08.02.2018
comment
Вы правы, я привык писать для более чем одного состояния, я совсем забыл о .toggle(), обновил, спасибо. - person zer00ne; 08.02.2018
comment
e.stopPropagation() для смешанных событий и пользовательский eventTrigger(), если он действительно загроможден (что означает, что я, вероятно, унаследовал чей-то беспорядок). - person zer00ne; 08.02.2018

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. Правильные имена для событий mousedown и mouseup
  5. Свойства CSS должны заканчиваться точкой с запятой
  6. Селекторы CSS неверны
person sliptype    schedule 08.02.2018
comment
И это тоже не сработает. Будет получена ошибка, которая не может прочитать classList of undefined. - person epascarello; 08.02.2018
comment
Правильно, я только что исправил - person sliptype; 08.02.2018