选择输入广播时更改最接近类的样式-Javascript

时间:2018-09-18 11:16:43

标签: javascript html input radio-button onchange

我必须做一个真正简单的任务,但我无法弄清楚。

我有一些卡,用户可以通过单选按钮选择。当用户单击相对输入单选按钮时,我想突出显示选中的卡。

我不明白如何选择所选收音机中最接近的课程。

我的HTML看起来像这样:

<div class="box">
    <div class="box-content">
        <input type="radio" name="box-input">
        <label>Label One</label>
    </div>
</div>

<div class="box">
    <div class="box-content">
        <input type="radio" name="box-input">
        <label>Some Two</label>
    </div>
</div>

And so on...

<button onclick="submit()">Submit</button>

如果我这样做:

let boxes = document.querySelectAll('input');
const submit = () => {
    for (let i=0;i<boxes.length;i++) {
        boxes[i].checked? this.closest('.box').classList.add('selected'): console.log('nothing is selected')
    }
}

它说this.closestundefined,并且只有在用户单击“提交”按钮时它才起作用。

我想做的只是在选择单选输入时向div .box添加一个类,并在将状态更改为未选择时将其删除。

如果可能的话,我也希望避免内联HTML“ onclick”。

请仅使用纯JavaScript

编辑

在@somethinghere的建议下,我向每个输入广播添加了onchange="change(this)",并以此方式更改了脚本:

const change = el => {
    el.checked?el.closest('.box').classList.add('selected'):el.closest('.box').classList.remove('selected')
;

它有效,当我单击输入广播时,它将添加类selected。但是,如果我单击其他输入,则不会删除类selected

建议?

2 个答案:

答案 0 :(得分:0)

添加代码以在选择输入广播时更改最接近的班级样式

var radioAll = document.querySelectorAll('input');

for(var i = 0; i < radioAll.length; i++) 
{
   radioAll[i].onclick = function() 
   {
      //remove selected class from all box classs
      var boxElems = document.querySelectorAll(".box");
      [].forEach.call(boxElems, function(el) {
         el.classList.remove("selected");
      });
      if(this.checked)
      {
         this.closest('.box').classList.add('selected');
      }    
    };
}
.selected{
background-color: coral;
}
<div class="box">
    <div class="box-content">
        <input type="radio" name="box-input">
        <label>Label One</label>
    </div>
</div>

<div class="box">
    <div class="box-content">
        <input type="radio" name="box-input">
        <label>Some Two</label>
    </div>
</div>

And so on...

<button onclick="submit()">Submit</button>

答案 1 :(得分:0)

虽然您已经接受了答案,但我想我会添加另一种方法:

// get a reference to the <button> element; here you only have the one <button>,
// so document.querySelector() will suffice (as it returns either the first
// Node that matches the supplied selector or null):
let submitButton = document.querySelector('button'),
  inputs = document.querySelectorAll('input');

// here we use the same Arrow function syntax, which does not - by design - get
// its own 'this' reference:
const submit = () => {

  // since we have the <input> elements already we use that, along with the
  // NodeList.prototype.forEach() method:
  inputs.forEach(
  
    // here 'input' is a reference to the current <input> element of the
    // NodeList of <input> elements over which we're iterating.
    // we use Element.closest() to find the relevant '.box' element, and
    // use the Element.classList API to toggle the 'hasSelected'
    // class-name based on the supplied 'switch', the 'input.checked'; if
    // 'input.checked' is true the class-name is added to the '.box', if
    // 'input.checked' is false the class-name is removed (if the class-name
    // is already present, or not-present, when it's added or removed no
    // error is thrown and it presents no problem):
    (input) => input.closest('.box').classList.toggle('hasSelected', input.checked)
  )
}

// using the EventTarget.addEventListener() method, in place of the obtrusive
// 'onclick' in-line event-handling; here we bind the submit() function 
// (note the deliberate lack of parentheses) as the event-handler for the
// 'click' event:
submitButton.addEventListener('click', submit);
*,
::before,
::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  font-size: 1rem;
  line-height: 1.5;
}

body>div {
  display: flex;
  justify-content: space-between;
  width: 50vw;
  margin: 1em auto;
}

div.box {
  display: grid;
  grid-template-columns: 1fr 30px;
  grid-gap: 0 10px;
  border: 2px solid transparent;
  padding: 0.5em;
  border-radius: 1em;
}

div.box.hasSelected {
  border-color: limegreen;
}

div.box.hasSelected::after {
  display: contents;
  content: '✓';
  font-weight: bold;
  color: limegreen;
}
<div>
  <div class="box">
    <div class="box-content">
      <label><input type="radio" name="box-input">
      Label One</label>
    </div>
  </div>

  <div class="box">
    <div class="box-content">
      <label><input type="radio" name="box-input">
      Some Two</label>
    </div>
  </div>

  <button>Submit</button>
</div>

JS Fiddle demo

参考文献: