Прокрутите флажки и условно отключите снятые флажки

Я пытаюсь написать базовую функцию на чистом JS, которая просто проверяет количество отмеченных флажков, и если это число превышает определенное количество, отключает остальные. Я легко могу добиться этого в jQuery, но пытаюсь заставить его работать на чистом JS. У меня есть CodePen, настроенный здесь, и я включаю свой рабочий JS ниже. Спасибо за понимание здесь.

(function() {

  var checkboxes = document.querySelectorAll('input[id^ = "mktoCheckbox"]');
  var active = document.querySelectorAll('input[id^ = "mktoCheckbox"]:checked');
  var numActive = active.length;

  console.info(numActive);

  if (numActive > 1) {
    for(var i = 0; i < checkboxes.length; i++){
            if (checkboxes[i].checked == true) {
                return;
            } else {
                checkboxes[i].disabled == true;
            }
        }
  }

})();

У вас есть оператор return; в вашем цикле. Это приведет к выходу из цикла, когда он встретит первый установленный флажок. В вашем примере это первый, поэтому ничего не происходит. Кроме того, вы используете оператор равенства в другом предложении блока if: checkboxes[i].disabled == true; Это должно быть checkboxes[i].disabled = true;, если вы хотите установить для свойства значение true.

JSTL 26.07.2018 17:54

Я подозреваю, что вас сбил с толку тот факт, что при использовании jQuery часто можно использовать $.each, который принимает функцию в качестве аргумента. В этом случае возврат из функции просто прервет текущую итерацию. for не использует обратный вызов функции, а скорее является самостоятельным выражением, поэтому возврат завершит весь цикл.

ChrisM 26.07.2018 18:05
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
2
1 066
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

В вашем коде есть две проблемы:

  1. Вы возвращаетесь из условия if, которое приводит к завершению цикла.
  2. Вы не назначаете true атрибуту disabled, вместо этого вы сравниваете с ==.

Измените связанный фрагмент на следующий, чтобы он работал:

if (numActive > 1) {
  for (var i = 0; i < checkboxes.length; i++) {
    if (checkboxes[i].checked != true) {
      checkboxes[i].disabled = true;
    }
  }
}

Вы можете найти рабочую вилку своего пера здесь. Ниже приведен рабочий фрагмент SO:

(function() {
  var checkboxes = document.querySelectorAll('input[id^ = "mktoCheckbox"]');
  var active = document.querySelectorAll('input[id^ = "mktoCheckbox"]:checked');
  var numActive = active.length;

  console.info(numActive);

  if (numActive > 1) {
    for (var i = 0; i < checkboxes.length; i++) {
      if (checkboxes[i].checked != true) {
        checkboxes[i].disabled = true;
      }
    }
  }
})();
<fieldset>
  <legend>Choose some monster features</legend>

  <div>
    <input type = "checkbox" id = "mktoCheckbox_1" name = "feature" value = "scales" checked />
    <label for = "scales">Scales</label>
  </div>

  <div>
    <input type = "checkbox" id = "mktoCheckbox_2" name = "feature" value = "horns" />
    <label for = "horns">Horns</label>
  </div>

  <div>
    <input type = "checkbox" id = "mktoCheckbox_3" name = "feature" value = "claws" />
    <label for = "claws">Claws</label>
  </div>

  <div>
    <input type = "checkbox" id = "mktoCheckbox_4" name = "feature" value = "tails" checked />
    <label for = "tails">Tails</label>
  </div>

</fieldset>

Вот рабочая ручка.

Прежде всего, imo, вы должны использовать getAttribute и setAttribute на элементах DOM. HTMLInputElement.checked afaik отражает только атрибут checked (и преобразует его в boolean) для удобства.

Имея это в виду, теперь вам нужно протестировать строки с помощью оператора строгого сравнения ===. Например.

if (checkbox.getAttribute('checked') === 'true') {...}

поскольку использование == будет оцениваться как ложное

true == 'true' // false

Кроме того, вместо цикла для вы можете использовать цикл для-из для коллекций DOM. Т.е. это работает:

const checkboxes = document.querySelectorAll('...');
for(const checkbox of checkboxes) {
    ...
}

Имейте в виду, что для управления петлей вы используете continue и break, а не return.

Хотя getAttribute и setAttribute жизненно важно знать в чистом js, .checked все еще работает в этом случае (и может быть быстрее)

ChrisM 26.07.2018 18:08

Из любопытства - я вижу, что этот ответ был отклонен; для моего собственного назидания, есть ли причина, по которой это менее желательный / эффективный подход, чем выбранный ответ выше?

nickpish 26.07.2018 18:12

Боюсь, я проголосовал против, потому что на самом деле он не отвечал на вопрос и на самом деле немного вводил в заблуждение, например в этом случае вы можете полностью использовать атрибут .checked. Также я не совсем уверен, что имелось в виду под комментарием о преобразовании типов, но похоже, что они предполагают, что true == 'true' разрешится как false, что неверно. В противном случае true == 'true' разрешает как истину, а true === 'true' разрешает как ложь (как правило, вы всегда должны использовать строгое равенство === для более надежного кода).

ChrisM 26.07.2018 18:21

@ChrisM Я только что проверил это в консоли в Chrome, и true == 'true' оценивается как false. Не понимаю, почему вы думаете иначе. Спорный вопрос, использовать ли свойство getAttribute/setAttribute или checked. Но они эквивалентны при правильном тесте, и вы можете утверждать, что атрибут является более стандартным, поскольку свойство checked вычисляется из атрибута. Кроме того, я на самом деле отвечаю на вопрос, предоставляя рабочий код?

FK82 26.07.2018 18:38

@ FK82 Верно, мой плохой true == 'true' - фальшивка. Думаю, я, должно быть, думал о случае с числами (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…), но в данном случае это немного спорный вопрос, потому что таков и true === 'true'. Это правда, что нужно иметь привычку использовать ===, но ваш комментарий сбивает с толку в этом контексте. Хотя вы ссылались на рабочий пример, он не был адекватно объяснен в основном тексте вашего ответа. Само по себе это не является основанием для голосования против, но это сбивает с толку тело. Простите. Я ценю, что вы пытаетесь помочь :)

ChrisM 26.07.2018 19:13

Я сейчас почесываю голову, потому что почти уверен, что где-то есть язык, где, к сожалению, true == 'true' верен, но я не уверен, какой именно. Я всегда использую '===' с JS, поэтому мое предположение никогда не проверялось. Возможно, PHP? Хм исчезает в дыре Google

ChrisM 26.07.2018 19:19

@ChrisM Я обновил свой ответ, чтобы прояснить моменты, которые, по вашему мнению, сбивают с толку. Кстати, я почти уверен, что можно забыть любой язык, где true == 'true'. Когда-то можно / нужно терпеть столько гибкости шрифтов. ; )

FK82 26.07.2018 19:47

@ FK82 Я снял голос против. Возможно, мне следовало бы скорее попросить разъяснений, чем просто проголосовать против. Кстати, это было PHP, но только потому, что все непустые строки считаются истинными в этом безумном мире. крики

ChrisM 27.07.2018 15:54

Другие вопросы по теме