Как отменить выбор типа ввода = «кнопка» в JavaScript - PullRequest
0 голосов
/ 17 января 2019

В форме HTML у меня есть следующий раздел, в котором я хочу действовать как переключатели, но отображаются как обычные кнопки.

<span>Minimum Skill Level:</span><br />
<input type='button' id='skMin1' class='btn-sm' name='skMin' value='1' checked>
<input type='button' id='skMin2' class='btn-sm' name='skMin' value='2'>
<input type='button' id='skMin3' class='btn-sm' name='skMin' value='3'>
<input type='button' id='skMin4' class='btn-sm' name='skMin' value='4'>
<input type='button' id='skMin5' class='btn-sm' name='skMin' value='5'>

Делая имя одинаковым для всех кнопок в группе, они действуют как переключатели, когда нажатие на секунду отменяет выбор первой.

У меня есть раздел JavaScript, который добавляет слушателя к каждой кнопке и сохраняет значение. Изменяет цвет фона кнопки, чтобы показать, что она выбрана.

let radioButton1 = document.querySelectorAll("[name=skMin]").forEach(function(e) {
        e.addEventListener('click', () => {
        e.style.background = 'cyan';
        drillSession.skillMin = e.value;
    })
})

Похоже, что я хочу, и я получаю данные просто отлично, но есть одна большая проблема. Нажатие на вторую кнопку в группе меняет значение, но я не могу понять, как отменить выделение ранее выбранной опции, чтобы пользователь не смутился, увидев несколько подсвеченных кнопок. Есть предложения?

Ответы [ 3 ]

0 голосов
/ 17 января 2019

Обратите внимание, что e в обработчике событий часто используется для ссылки на переданный параметр event - во избежание путаницы вы можете использовать другое имя, например, button или skMinButton или что-то в этом роде.

Один из вариантов - сначала перебрать все кнопки и удалить их свойство background:

const buttons = document.querySelectorAll("[name=skMin]");
buttons.forEach((skMinButton) => {
  skMinButton.addEventListener('click', () => {
    buttons.forEach((button) => {
      button.style.removeProperty('background');
    });
    skMinButton.style.background = 'cyan'
    // drillSession.skillMin = e.value
  });
});
<span>Minimum Skill Level:</span><br />
<input type='button' id='skMin1' class='btn-sm' name='skMin' value='1' checked>
<input type='button' id='skMin2' class='btn-sm' name='skMin' value='2'>
<input type='button' id='skMin3' class='btn-sm' name='skMin' value='3'>
<input type='button' id='skMin4' class='btn-sm' name='skMin' value='4'>
<input type='button' id='skMin5' class='btn-sm' name='skMin' value='5'>

Более эффективная возможность - сохранить ранее выбранную кнопку в переменной и удалить только ее background:

const buttons = document.querySelectorAll("[name=skMin]");
let selectedButton;
buttons.forEach((skMinButton) => {
  skMinButton.addEventListener('click', () => {
    if (selectedButton) {
      selectedButton.style.removeProperty('background');
    }
    selectedButton = skMinButton;
    skMinButton.style.background = 'cyan'
    // drillSession.skillMin = e.value
  })
})
<span>Minimum Skill Level:</span><br />
<input type='button' id='skMin1' class='btn-sm' name='skMin' value='1' checked>
<input type='button' id='skMin2' class='btn-sm' name='skMin' value='2'>
<input type='button' id='skMin3' class='btn-sm' name='skMin' value='3'>
<input type='button' id='skMin4' class='btn-sm' name='skMin' value='4'>
<input type='button' id='skMin5' class='btn-sm' name='skMin' value='5'>

Вы также можете рассмотреть возможность использования делегирования событий, чтобы подключался только один слушатель, а не отдельный для каждой кнопки:

let selectedButton;
document.querySelector('.min-skill').addEventListener('click', ({ target }) => {
  if (!target.matches('input')) {
    return;
  }
  if (selectedButton) {
    selectedButton.style.removeProperty('background');
  }
  selectedButton = target;
  target.style.background = 'cyan'

  // drillSession.skillMin = e.value
});
<div class="min-skill">
  <span>Minimum Skill Level:</span><br />
  <input type='button' id='skMin1' class='btn-sm' name='skMin' value='1' checked>
  <input type='button' id='skMin2' class='btn-sm' name='skMin' value='2'>
  <input type='button' id='skMin3' class='btn-sm' name='skMin' value='3'>
  <input type='button' id='skMin4' class='btn-sm' name='skMin' value='4'>
  <input type='button' id='skMin5' class='btn-sm' name='skMin' value='5'>
</div>
0 голосов
/ 17 января 2019

При написании кода OP он создает замыкания и циклические ссылки, которые могут быть бременем в памяти. Возможно, вы захотите очистить его, сделав слушателей дискретными функциями, а не выражениями анонимных функций. Кроме того, добавление слушателей в качестве ссылок делает это более полезным.

Один простой способ сделать выделение / выделение - добавить и удалить класс, затем вы можете использовать селектор, чтобы эффективно найти выделенные, например,

var utils = {
  toggleSelected: function(evt) {
    let hClass = 'btn_selected';
    document.querySelectorAll('.' + hClass).forEach(el => el.classList.remove(hClass));  
    this.classList.add(hClass);    
  }
};

window.addEventListener('DOMContentLoaded',function(){
  document.querySelectorAll('input.btn-sm').forEach(btn =>
    btn.addEventListener('click', utils.toggleSelected, false));
}, false);
.btn_selected {
  background-color: #ffbb99;
}
<span>Minimum Skill Level:</span><br/>
<input type='button' class='btn-sm' name='skMin' value='1'>
<input type='button' class='btn-sm' name='skMin' value='2'>
<input type='button' class='btn-sm' name='skMin' value='3'>
<input type='button' class='btn-sm' name='skMin' value='4'>
<input type='button' class='btn-sm' name='skMin' value='5'>

Радиокнопки делают это по умолчанию, поэтому, возможно, вам стоит взглянуть на стилизованные радиокнопки вместо скриптовых кнопок.

var utils = {
  toggleSelected: function(evt) {
    let tgt = this;
    let div = this.closest('div')
    let hClass = 'btn_selected';
    div.querySelectorAll('.' + hClass).forEach(el => el.classList.remove(hClass));
    this.classList.add(hClass);
  },
  removeAllSelected: function(evt) {
    let hClass = 'btn_selected';
    document.querySelectorAll('.' + hClass).forEach(el => el.classList.remove(hClass));

  }
};

window.addEventListener('DOMContentLoaded', function() {
  document.querySelectorAll('input.btn-sm').forEach(btn =>
    btn.addEventListener('click', utils.toggleSelected, false));
    document.getElementById('theReset').addEventListener('click', utils.removeAllSelected, false);
}, false);
.btn_selected {
  background-color: #ffbb99;
}
<fieldset><legend>Select some values&hellip;</legend>
<div id="set0">
  <span>Minimum Skill Level:</span><br>
  <input type='button' class='btn-sm' name='skMin' value='1'>
  <input type='button' class='btn-sm' name='skMin' value='2'>
  <input type='button' class='btn-sm' name='skMin' value='3'>
</div>
<div id="set1">
  <span>Minimum Education Level:</span><br>
  <input type='button' class='btn-sm' name='skMin' value='1'>
  <input type='button' class='btn-sm' name='skMin' value='2'>
  <input type='button' class='btn-sm' name='skMin' value='3'>
</div>
<div id="set2">
  <span>Minimum Confidence Level:</span><br>
  <input type='button' class='btn-sm' name='skMin' value='1'>
  <input type='button' class='btn-sm' name='skMin' value='2'>
  <input type='button' class='btn-sm' name='skMin' value='3'>
</div>
<button id="theReset">Reset All</button>
</fieldset>
0 голосов
/ 17 января 2019

Попробуйте

let radioButton1 = document.querySelectorAll("[name=skMin]").forEach(function(e,i,a) {
    e.addEventListener('click', (event) => {
        a.forEach(x=>x.style.background = 'white')
        e.style.background = 'cyan'
        //drillSession.skillMin = e.value       
    })
})
<span>Minimum Skill Level:</span><br />
<input type='button' id='skMin1' class='btn-sm' name='skMin' value='1' checked>
<input type='button' id='skMin2' class='btn-sm' name='skMin' value='2'>
<input type='button' id='skMin3' class='btn-sm' name='skMin' value='3'>
<input type='button' id='skMin4' class='btn-sm' name='skMin' value='4'>
<input type='button' id='skMin5' class='btn-sm' name='skMin' value='5'>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...