简体   繁体   English

如何在 Javascript 中级联单选按钮?

[英]How Can I Cascade Radio Buttons In Javascript?

I'm new to programming and am tasked with creating a clickable tournament bracket.我是编程新手,我的任务是创建一个可点击的锦标赛支架。 8 teams, where you can pick the winners who will advance to the next round. 8 支球队,您可以从中选出晋级下一轮的获胜者。

The problem I'm running into is when a person would want to revise picks in the first or second round after filling out the bracket.我遇到的问题是,当有人在填写完括号后想要修改第一轮或第二轮选秀权时。

For example in the first round the user picks:例如在第一轮中,用户选择:

  • Team1 v. Team8 --> #1 moves on Team1 v. Team8 --> #1 继续前进
  • Team4 v. Team5 --> #4 moves on Team4 v. Team5 --> #4 继续前进
  • Team3 v. Team6 --> #3 moves on Team3 v. Team6 --> #3 继续
  • Team2 v. Team7 --> #2 moves on Team2 v. Team7 --> #2 继续前进

In the Second Round let's say they pick:在第二轮中,假设他们选择:

  • Team1 v. Team4 --> #1 moves on Team1 v. Team4 --> #1 继续前进
  • Team2 v. Team3 --> #2 moves on Team2 v. Team3 --> #2 继续前进

In the Finals, they pick:在总决赛中,他们选择:

  • Team1 v. Team2 --> #1 wins. Team1 对 Team2 --> #1 获胜。

Then, let's say the user changes their mind and picks Team8 to upset Team1 in the first round.然后,假设用户改变主意并在第一轮中选择 Team8 来扰乱 Team1。 Right now the code would still show Team1 as the winner and in the final game.现在,代码仍将 Team1 显示为获胜者并在最后一场比赛中。 How can I remove the text for the future rounds that currently shows Team1?如何删除当前显示 Team1 的未来回合的文本?

Attaching JSFiddle here: https://jsfiddle.net/a4hya2c7/5/ or see below code:在此处附加 JSFiddle: https ://jsfiddle.net/a4hya2c7/5/ 或查看以下代码:

<!DOCTYPE html>
<html>
   <head>
      <title>Button</title>
   </head>
   <body>
      <p>First Round</p>
      <div id="round1">
         <input type="radio" name="g1" id="i1" value="#1" onclick="changeText(this.value);"><label id="r1">#1</label>
         <input type="radio" name="g1" id="i2" value="#8" onclick="changeText(this.value);"><label id="r2">#8</label></br>
         <input type="radio" name="g2" id="i3" value="#4" onclick="changeText2(this.value);"><label id="r3">#4</label>
         <input type="radio" name="g2" id="i4" value="#5" onclick="changeText2(this.value);"><label id="r4">#5</label></br>
         <input type="radio" name="g3" id="i5" value="#3" onclick="changeText3(this.value);"><label id="r5">#3</label>
         <input type="radio" name="g3" id="i6" value="#6" onclick="changeText3(this.value);"><label id="r6">#6</label></br>
         <input type="radio" name="g4" id="i7" value="#7" onclick="changeText4(this.value);"><label id="r7">#7</label>
         <input type="radio" name="g4" id="i8" value="#2" onclick="changeText4(this.value);"><label id="r8">#2</label></br>
      </div>
      </br>
      <p>Second Round</p>
      <div id="round2">
         <input type="radio" name="g5" id="i9" onclick="changeText5(this.value);"><label id="r9"></label>
         <input type="radio" name="g5" id="i10" onclick="changeText5(this.value);"><label id="r10"></label></br>
         <input type="radio" name="g6" id="i11" onclick="changeText6(this.value);"><label id="r11"></label>
         <input type="radio" name="g6" id="i12" onclick="changeText6(this.value);"><label id="r12"></label></br>
      </div>
      </br>
      <p>Finals</p>
      <div id="round3">
         <input type="radio" name="g7" id="i13" onclick="changeText7(this.value);"><label id="r13"></label>
         <input type="radio" name="g7" id="i14" onclick="changeText7(this.value);"><label id="r14"></label></br>
      </div>
      </br>
      <p>Winner</p>
      <div id="round4">
         <label value="#8" id="r15"></label></br>
      </div>
      </br>
   </body>
</html>

JS: JS:

function changeText(value) {
    document.getElementById('r9').innerHTML = value;
    document.getElementById('i9').value = value;
}

function changeText2(value) {
    document.getElementById('r10').innerHTML = value;
    document.getElementById('i10').value = value;
}

function changeText3(value) {
    document.getElementById('r11').innerHTML = value;
    document.getElementById('i11').value = value;
}

function changeText4(value) {
    document.getElementById('r12').innerHTML = value;
    document.getElementById('i12').value = value;
}

function changeText5(value) {
    document.getElementById('r13').innerHTML = value;
    document.getElementById('i13').value = value;
}

function changeText6(value) {
    document.getElementById('r14').innerHTML = value;
    document.getElementById('i14').value = value;
}
function changeText7(value) {
    document.getElementById('r15').innerHTML = value;
    document.getElementById('r15').value = value;
}

Firstly your <br> tags aren't correct as you can see here:首先,您的<br>标签不正确,如下所示:

</div>
</br>

You are using the close tag without the opening.您正在使用没有开头的关闭标签。 You can either use:您可以使用:

<br/>

Or use the newer html5 self closing tags style:或者使用较新的 html5 自结束标签样式:

<br>

As to the JS itself, you can simplify it a lot if you use an attribute, similar as the name you are already using to point where it must put the value.至于 JS 本身,如果您使用一个属性,您可以将其简化很多,类似于您已经使用的name来指出它必须放置值的位置。 With that change the code would be a lot smaller and simpler:有了这个改变,代码会更小更简单:

 const inputs = document.querySelectorAll("input[type=radio]"); for (let inp of inputs){ inp.addEventListener("change", function(){ let targetLabel = document.getElementById(inp.dataset.target); targetLabel.previousSibling.value = inp.value; targetLabel.innerHTML = inp.value; }); }
 <p>First Round</p> <div id="round1"> <input type="radio" name="g1" id="i1" value="#1" data-target="r9"><label id="r1">#1</label> <input type="radio" name="g1" id="i2" value="#8" data-target="r9"><label id="r2">#8</label><br> <input type="radio" name="g2" id="i3" value="#4" data-target="r10"><label id="r3">#4</label> <input type="radio" name="g2" id="i4" value="#5" data-target="r10"><label id="r4">#5</label><br> <input type="radio" name="g3" id="i5" value="#3" data-target="r11"><label id="r5">#3</label> <input type="radio" name="g3" id="i6" value="#6" data-target="r11"><label id="r6">#6</label><br> <input type="radio" name="g4" id="i7" value="#7" data-target="r12"><label id="r7">#7</label> <input type="radio" name="g4" id="i8" value="#2" data-target="r12"><label id="r8">#2</label><br> </div> <br> <p>Second Round</p> <div id="round2"> <input type="radio" name="g5" id="i9" data-target="r13"><label id="r9"></label> <input type="radio" name="g5" id="i10" data-target="r13"><label id="r10"></label><br> <input type="radio" name="g6" id="i11" data-target="r14"><label id="r11"></label> <input type="radio" name="g6" id="i12" data-target="r14"><label id="r12"></label><br> </div> <br> <p>Finals</p> <div id="round3"> <input type="radio" name="g7" id="i13" data-target="r15"><label id="r13"></label> <input type="radio" name="g7" id="i14" data-target="r15"><label id="r14"></label><br> </div> <br> <p>Winner</p> <div id="round4"> <label value="#8" id="r15"></label><br> </div> <br>

Note that the targets i set were directly to the labels:请注意,我设置的目标直接指向标签:

<input type="radio" ... data-target="r9">

Then to get to the corresponding radio i used previousSibling .然后为了获得相应的收音机,我使用了previousSibling

I used several functions that you may not know:我使用了几个你可能不知道的函数:

  • querySelectorAll - to get an array of elements matching the selector passed querySelectorAll - 获取与传递的选择器匹配的元素数组
  • for ... of to iterate on all inputs retrieved by the querySelectorAll for ... ofquerySelectorAll检索到的所有输入进行迭代
  • addEventListener - to set the event handler directly on Javascript and make the code cleaner addEventListener - 直接在 Javascript 上设置事件处理程序并使代码更清晰

And with just those little lines of Javascript you have the same functionality, and most importantly, without code duplication.只需使用 Javascript 的那些小行,您就可以拥有相同的功能,而且最重要的是,无需重复代码。

Now if you want to cascade a change on the first radios to the lower ones, you can call the change event directly with:现在,如果您想将第一个收音机上的更改级联到较低的收音机上,您可以直接使用以下命令调用更改事件:

const event = new Event('change');
element.dispatchEvent(event);

Whenever you see that the target element already has a value set.每当您看到目标元素已经有一个值集。 This works like a recursive call:这就像一个递归调用:

 const inputs = document.querySelectorAll("input[type=radio]"); for (let inp of inputs){ inp.addEventListener("change", function(){ let targetLabel = document.getElementById(inp.dataset.target); let targetRadio = targetLabel.previousSibling; targetRadio.value = inp.value; targetLabel.innerHTML = inp.value; //if this isn't the last and it's checked, to not cascade non selected radios if (targetRadio.hasAttribute && targetRadio.checked){ const nextTargetLabel = document.getElementById(targetRadio.dataset.target); if (nextTargetLabel.innerHTML != ''){ //if it has a value then cascade targetRadio.dispatchEvent(new Event('change')); } } }); }
 <p>First Round</p> <div id="round1"> <input type="radio" name="g1" id="i1" value="#1" data-target="r9"><label id="r1">#1</label> <input type="radio" name="g1" id="i2" value="#8" data-target="r9"><label id="r2">#8</label><br> <input type="radio" name="g2" id="i3" value="#4" data-target="r10"><label id="r3">#4</label> <input type="radio" name="g2" id="i4" value="#5" data-target="r10"><label id="r4">#5</label><br> <input type="radio" name="g3" id="i5" value="#3" data-target="r11"><label id="r5">#3</label> <input type="radio" name="g3" id="i6" value="#6" data-target="r11"><label id="r6">#6</label><br> <input type="radio" name="g4" id="i7" value="#7" data-target="r12"><label id="r7">#7</label> <input type="radio" name="g4" id="i8" value="#2" data-target="r12"><label id="r8">#2</label><br> </div> <br> <p>Second Round</p> <div id="round2"> <input type="radio" name="g5" id="i9" data-target="r13"><label id="r9"></label> <input type="radio" name="g5" id="i10" data-target="r13"><label id="r10"></label><br> <input type="radio" name="g6" id="i11" data-target="r14"><label id="r11"></label> <input type="radio" name="g6" id="i12" data-target="r14"><label id="r12"></label><br> </div> <br> <p>Finals</p> <div id="round3"> <input type="radio" name="g7" id="i13" data-target="r15"><label id="r13"></label> <input type="radio" name="g7" id="i14" data-target="r15"><label id="r14"></label><br> </div> <br> <p>Winner</p> <div id="round4"> <label value="#8" id="r15"></label><br> </div> <br>

Edit :编辑

To clear the following radios instead of cascading the values you can use a while , and navigating with the targets until you reach the end:要清除以下无线电而不是级联值,您可以使用while ,并使用targets导航直到到达终点:

 const inputs = document.querySelectorAll("input[type=radio]"); for (let inp of inputs){ inp.addEventListener("change", function(){ let targetLabel = document.getElementById(inp.dataset.target); let targetRadio = targetLabel.previousSibling; targetLabel.innerHTML = inp.value; targetRadio.value = inp.value; //while there is a next target clear it while (targetLabel.previousSibling.hasAttribute){ targetLabel = document.getElementById(targetRadio.dataset.target); targetRadio = targetLabel.previousSibling; targetRadio.checked = false; targetLabel.innerHTML = ''; } }); }
 <p>First Round</p> <div id="round1"> <input type="radio" name="g1" id="i1" value="#1" data-target="r9"><label id="r1">#1</label> <input type="radio" name="g1" id="i2" value="#8" data-target="r9"><label id="r2">#8</label><br> <input type="radio" name="g2" id="i3" value="#4" data-target="r10"><label id="r3">#4</label> <input type="radio" name="g2" id="i4" value="#5" data-target="r10"><label id="r4">#5</label><br> <input type="radio" name="g3" id="i5" value="#3" data-target="r11"><label id="r5">#3</label> <input type="radio" name="g3" id="i6" value="#6" data-target="r11"><label id="r6">#6</label><br> <input type="radio" name="g4" id="i7" value="#7" data-target="r12"><label id="r7">#7</label> <input type="radio" name="g4" id="i8" value="#2" data-target="r12"><label id="r8">#2</label><br> </div> <br> <p>Second Round</p> <div id="round2"> <input type="radio" name="g5" id="i9" data-target="r13"><label id="r9"></label> <input type="radio" name="g5" id="i10" data-target="r13"><label id="r10"></label><br> <input type="radio" name="g6" id="i11" data-target="r14"><label id="r11"></label> <input type="radio" name="g6" id="i12" data-target="r14"><label id="r12"></label><br> </div> <br> <p>Finals</p> <div id="round3"> <input type="radio" name="g7" id="i13" data-target="r15"><label id="r13"></label> <input type="radio" name="g7" id="i14" data-target="r15"><label id="r14"></label><br> </div> <br> <p>Winner</p> <div id="round4"> <label value="#8" id="r15"></label><br> </div> <br>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM