Yes/No 按钮选择

Yes/No button selection

我有一个简单的 yes/no 按钮选择代码,它将自动填充要在表单中使用的输入值。我的问题是如何简化代码的 jquery 部分?因为我必须添加更多 yes/no 问题。

$('#y01').click(function() {
  $('#y01').css({'background':'#0080FF', 'color':'white'});
  $('#n01').css({'background':'transparent', 'color':'#808080'});
  $('#ans01').val('Yes');
});

$('#n01').click(function() {
  $('#y01').css({'background':'transparent', 'color':'#808080'});
  $('#n01').css({'background':'#0080FF', 'color':'white'});
  $('#ans01').val('No');
});

$('#y02').click(function() {
  $('#y02').css({'background':'#0080FF', 'color':'white'});
  $('#n02').css({'background':'transparent', 'color':'#808080'});
  $('#ans02').val('Yes');
});

$('#n02').click(function() {
  $('#y02').css({'background':'transparent', 'color':'#808080'});
  $('#n02').css({'background':'#0080FF', 'color':'white'});
  $('#ans02').val('No');
});
body,
html {
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
  background-color: fff;
}

.button {
  background: transparent;
  color: white;
  padding: 15px 20px;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  font-size: 16px;
  margin: 4px 2px;
  cursor: pointer;
  border-radius: 12px;
  width: 100px;
}

.button1 {
  color: #808080;
  border: 2px solid #e7e7e7;
}

.button:active,
.button:focus,
.button:visited {
  outline: none;
}

table {
  font-family: arial, sans-serif;
  border-collapse: collapse;
  width: 100%;
}

td,
th {
  border: none;
  padding: 15px;
  width: 50%;
}

tr:nth-child(even) {
  background-color: #f2f2f2;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>

  <tr>
    <td style="text-align:right;">
      Do you have any question #1?
    </td>
    <td>
      <input type="text" id="ans01" hidden/>
      <input type="button" id="y01" class="button button1" value="Yes" />
      <input type="button" id="n01" class="button button1" value="No" />
    </td>
  </tr>

  <tr>
    <td style="text-align:right;">
      Do you have any question #2?
    </td>
    <td>
      <input type="text" id="ans02" hidden/>
      <input type="button" id="y02" class="button button1" value="Yes" />
      <input type="button" id="n02" class="button button1" value="No" />
    </td>
  </tr>



</table>

一个简单的辅助函数应该可以工作:

function assignYesNoStyle(yesId, noId, ansId) {
    $(yesId).click(function() {
        $(yesId).css({'background':'#0080FF', 'color':'white'});
        $(noId).css({'background':'transparent', 'color':'#808080'});
        $(ansId).val('Yes');
    });

    $(noId).click(function() {
        $(yesId).css({'background':'transparent', 'color':'#808080'});
        $(noId).css({'background':'#0080FF', 'color':'white'});
        $(ansId).val('No');
    });
}

然后在您的脚本初始化的地方,只需说:

assignYesNoStyle('#y01', '#n01', '#ans01');
assignYesNoStyle('#y02', '#n02', '#ans02');

Copy/paste 根据需要

使用DOM导航方法来引用您点击的按钮和同组中的兄弟。

给隐藏的答案字段一个 class 以便您可以类似地引用它。

$(".button1").click(function() {
  var otherButton = this.value == "Yes" ? "No" : "Yes";
  $(this).css({'background':'#0080FF', 'color':'white'});
  $(this).siblings(`.button1[value=${otherButton}]`).css({'background':'transparent', 'color':'#808080'});
  $(this).siblings(".answer").val(this.value);
});
body,
html {
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
  background-color: fff;
}

.button {
  background: transparent;
  color: white;
  padding: 15px 20px;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  font-size: 16px;
  margin: 4px 2px;
  cursor: pointer;
  border-radius: 12px;
  width: 100px;
}

.button1 {
  color: #808080;
  border: 2px solid #e7e7e7;
}

.button:active,
.button:focus,
.button:visited {
  outline: none;
}

table {
  font-family: arial, sans-serif;
  border-collapse: collapse;
  width: 100%;
}

td,
th {
  border: none;
  padding: 15px;
  width: 50%;
}

tr:nth-child(even) {
  background-color: #f2f2f2;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>

  <tr>
    <td style="text-align:right;">
      Do you have any question #1?
    </td>
    <td>
      <input type="text" id="ans01" class="answer" hidden/>
      <input type="button" id="y01" class="button button1" value="Yes" />
      <input type="button" id="n01" class="button button1" value="No" />
    </td>
  </tr>

  <tr>
    <td style="text-align:right;">
      Do you have any question #2?
    </td>
    <td>
      <input type="text" id="ans02" class="answer" hidden/>
      <input type="button" id="y02" class="button button1" value="Yes" />
      <input type="button" id="n02" class="button button1" value="No" />
    </td>
  </tr>



</table>

将它们视为两个独立的问题:首先,切换同级按钮,其次,设置隐藏元素的值。 YMMV

$('td input[type="button"]').click(function() {
  // get the clicked element.
  let clickedBtn = $(this);
  // set its css...
  clickedBtn.css({'background':'#0080FF', 'color':'white'})
  // find its sibling button(s)...
  .siblings('[type="button"]')
  // and set THEIR css
  .css({'background':'transparent', 'color':'#808080'});
});

$("[value='No'], [value='Yes']").click(function(){
  let clickedBtn = $(this);
  clickedBtn.siblings('[hidden]').val(clickedBtn.val() );
  console.log(clickedBtn.val() );
});
body,
html {
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
  background-color: fff;
}

.button {
  background: transparent;
  color: white;
  padding: 15px 20px;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  font-size: 16px;
  margin: 4px 2px;
  cursor: pointer;
  border-radius: 12px;
  width: 100px;
}

.button1 {
  color: #808080;
  border: 2px solid #e7e7e7;
}

.button:active,
.button:focus,
.button:visited {
  outline: none;
}

table {
  font-family: arial, sans-serif;
  border-collapse: collapse;
  width: 100%;
}

td,
th {
  border: none;
  padding: 15px;
  width: 50%;
}

tr:nth-child(even) {
  background-color: #f2f2f2;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>

  <tr>
    <td style="text-align:right;">
      Do you have any question #1?
    </td>
    <td>
      <input type="text" id="ans01" hidden/>
      <input type="button" id="y01" class="button button1" value="Yes" />
      <input type="button" id="n01" class="button button1" value="No" />
    </td>
  </tr>

  <tr>
    <td style="text-align:right;">
      Do you have any question #2?
    </td>
    <td>
      <input type="text" id="ans02" hidden/>
      <input type="button" id="y02" class="button button1" value="Yes" />
      <input type="button" id="n02" class="button button1" value="No" />
    </td>
  </tr>



</table>

是的,这似乎只需要一对按钮,所以您可以使用事件委托将您的方法提升到一个新的水平,所以基本上您应该委托特定 类 的事件点击并使用每个节点(按钮)的属性

想象一下你有

<button class="delegated-node" value="yes">Yes</button>
<button class="delegated-node" value="no">No</button>

那么你的 JS 应该像

$('table').on('click', '.delegated-node', function(event) {
   const target = event.target;
   const currentValue = $(this).val();
   const targetHiddenInput = $(this).data('target-input');
   var targetInput = $('#'+targetHiddenInput);
   // if input doesn't exist yet
   if (!targetInput.length) {
     $('table').append($('<input id="'+ targetHiddenInput +'" type="hidden" />'));
     targetInput = $('#'+targetHiddenInput)
   }
   targetInput.val(currentValue);
});

var tableId = "tableResponse";
$('#'+tableId).on('click', '.delegated-node', function(event) {
   const target = event.target;
   const currentValue = $(this).val();
   const targetHiddenInput = $(this).data('target-input');
   var targetInput = $('#'+targetHiddenInput);
   // if input doesn't exist yet
   if (!targetInput.length) {
     $('table').append($('<input id="'+ targetHiddenInput +'" type="hidden" />'));
     targetInput = $('#'+targetHiddenInput)
   }
   targetInput.val(currentValue);
});
body,
html {
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
  background-color: fff;
}

.button {
  background: transparent;
  color: white;
  padding: 15px 20px;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  font-size: 16px;
  margin: 4px 2px;
  cursor: pointer;
  border-radius: 12px;
  width: 100px;
}

.button1 {
  color: #808080;
  border: 2px solid #e7e7e7;
}

.button:active,
.button:focus,
.button:visited {
  outline: none;
}

table {
  font-family: arial, sans-serif;
  border-collapse: collapse;
  width: 100%;
}

td,
th {
  border: none;
  padding: 15px;
  width: 50%;
}

tr:nth-child(even) {
  background-color: #f2f2f2;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="tableResponse">

  <tr>
    <td style="text-align:right;">
      Do you have any question #1?
    </td>
    <td>
      <input type="button" data-target-input="ans1" class="button button1 delegated-node" value="Yes" />
      <input type="button" data-target-input="ans1" class="button button1 delegated-node" value="No" />
    </td>
  </tr>

  <tr>
    <td style="text-align:right;">
      Do you have any question #2?
    </td>
    <td>
      <input type="button" data-target-input="ans2" class="button button1 delegated-node" value="Yes" />
      <input type="button" data-target-input="ans2" class="button button1 delegated-node" value="No" />
    </td>
  </tr>
  
  <tr>
    <td style="text-align:right;">
      Do you have any question #3?
    </td>
    <td>
      <input type="button" data-target-input="ans3" class="button button1 delegated-node" value="Yes" />
      <input type="button" data-target-input="ans3" class="button button1 delegated-node" value="No" />
    </td>
  </tr>



</table>

您只需复制按钮代码并将 target-input 数据信息更改为下一个保留答案的隐藏输入的名称。

所以输入将在用户点击每对按钮时创建,将其检查到您的控制台

没有 jQuery 你可以这样做:

Array.from(document.querySelectorAll("tr")).forEach((tr, i) => {
  const buttons = Array.from(tr.querySelectorAll(".button"))
  const hidden = tr.querySelector(".hidden")
  buttons.forEach(button => {
    button.addEventListener("click", evt => {
      const val = evt.target.value
      console.log(`Answer ${i+1}: ${val}`)
      hidden.value = val
      buttons.forEach(button => button.classList.remove('active'))
      evt.target.classList.toggle('active')
    })
  })
})
body,
html {
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
  background-color: fff;
}

.button {
  background: transparent;
  color: white;
  padding: 15px 20px;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  font-size: 16px;
  margin: 4px 2px;
  cursor: pointer;
  border-radius: 12px;
  width: 100px;
}

.button1 {
  color: #808080;
  border: 2px solid #e7e7e7;
}

.button:active,
.button:focus,
.button:visited {
  outline: none;
}

table {
  font-family: arial, sans-serif;
  border-collapse: collapse;
  width: 100%;
}

td,
th {
  border: none;
  padding: 15px;
  width: 50%;
}

tr:nth-child(even) {
  background-color: #f2f2f2;
}

.active {
  background: #0080FF;
  color: white;
}
<table>

  <tr>
    <td style="text-align:right;">
      Do you have any question #1?
    </td>
    <td>
      <input type="text" id="ans01" class="hidden" hidden/>
      <input type="button" id="y01" class="button yes button1" value="Yes" />
      <input type="button" id="n01" class="button no button1" value="No" />
    </td>
  </tr>

  <tr>
    <td style="text-align:right;">
      Do you have any question #2?
    </td>
    <td>
      <input type="text" id="ans02" class="hidden" hidden/>
      <input type="button" id="y02" class="button yes button1" value="Yes" />
      <input type="button" id="n02" class="button no button1" value="No" />
    </td>
  </tr>



</table>

使用 .addClass().removeClass() 而不是 .css()。也不要重复代码。您使用的是#id,它会强制您执行 one-off 函数。 jQuery 很灵活,99.9% 的情况下使用 类 是最佳做法。为了引用用户单击的按钮,请使用 this 关键字或 event.target 事件 属性。顺便说一句:

"Do you have any question #1?"

不仅是错误的,而且语法上很痛苦。

$('.button').on('click', function(e) {
  const cell = $(this).parent('td');
  if ($(this).is('.y')) {
    $(this).addClass('active');
    cell.find('.answer').val($(this).val());
    cell.find('.n').removeClass('active');
  } else if ($(this).is('.n')) {
    $(this).addClass('active');
    cell.find('.answer').val($(this).val());
    cell.find('.y').removeClass('active');
  } else {
    return false;
  }
  console.log(cell.find('.answer').val());
});
body,
html {
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
  background-color: fff;
}

.button {
  padding: 15px 20px;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  font-size: 16px;
  margin: 4px 2px;
  cursor: pointer;
  border-radius: 12px;
  width: 100px;
  color: #808080;
  border: 2px solid #e7e7e7;
  background: transparent;
}

.active {
  background: #0080FF;
  color: white;
}

.button:active,
.button:focus,
.button:visited {
  outline: none;
}

table {
  font-family: arial, sans-serif;
  border-collapse: collapse;
  width: 100%;
}

td,
th {
  border: none;
  padding: 15px;
  width: 50%;
}

tr:nth-child(even) {
  background-color: #f2f2f2;
}

.question::after {
  content: ' #'attr(data-id)'?'
}
<table>

  <tr>
    <td class='question' data-id='1'>
      Do you have any questions
    </td>
    <td>
      <input class="answer" name='answer' type="hidden">
      <input class="button y" type="button" value="Yes">
      <input class="button n" type="button" value="No">
    </td>
  </tr>
  <tr>
    <td class='question' data-id='2'>
      Do you have any questions
    </td>
    <td>
      <input class="answer" name='answer' type="hidden">
      <input class="button y" type="button" value="Yes">
      <input class="button n" type="button" value="No">
    </td>
  </tr>
  <tr>
    <td class='question' data-id='3'>
      Do you have any questions
    </td>
    <td>
      <input class="answer" name='answer' type="hidden">
      <input class="button y" type="button" value="Yes">
      <input class="button n" type="button" value="No">
    </td>
  </tr>
  <tr>
    <td class='question' data-id='4'>
      Do you have any questions
    </td>
    <td>
      <input class="answer" name='answer' type="hidden">
      <input class="button y" type="button" value="Yes">
      <input class="button n" type="button" value="No">
    </td>
  </tr>
  <tr>
    <td class='question' data-id='5'>
      Do you have any questions
    </td>
    <td>
      <input class="answer" name='answer' type="hidden">
      <input class="button y" type="button" value="Yes">
      <input class="button n" type="button" value="No">
    </td>
  </tr>
  <tr>
    <td class='question' data-id='6'>
      Do you have any questions
    </td>
    <td>
      <input class="answer" name='answer' type="hidden">
      <input class="button y" type="button" value="Yes">
      <input class="button n" type="button" value="No">
    </td>
  </tr>
</table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

这就是我希望它有所帮助的诀窍。

$('input[type="button"]').each(function() {
  $(this).click(function() {

    if ($(this).attr('id').slice(0, 1) == 'y') {
      $(this).closest('td').find($('input[type="button"]')).css({
        'background': 'transparent',
        'color': '#808080'
      });
      $(this).css({
        'background': '#0080FF',
        'color': 'white'
      });
      $(this).closest('td').find($('input[type="text"]')).attr('value', 'Yes');
    } else {
      $(this).closest('td').find($('input[type="button"]')).css({
        'background': 'transparent',
        'color': '#808080'
      });
      $(this).css({
        'background': '#0080FF',
        'color': 'white'
      });
      $(this).closest('td').find($('input[type="text"]')).attr('value', 'No');
    }
  });
});
/*
$('input[type="text"]')
$('#y01').click(function() {
  $('#y01').css({'background':'#0080FF', 'color':'white'});
  $('#n01').css({'background':'transparent', 'color':'#808080'});
  $('#ans01').val('Yes');
});

$('#n01').click(function() {
  $('#y01').css({'background':'transparent', 'color':'#808080'});
  $('#n01').css({'background':'#0080FF', 'color':'white'});
  $('#ans01').val('No');
});

$('#y02').click(function() {
  $('#y02').css({'background':'#0080FF', 'color':'white'});
  $('#n02').css({'background':'transparent', 'color':'#808080'});
  $('#ans02').val('Yes');
});

$('#n02').click(function() {
  $('#y02').css({'background':'transparent', 'color':'#808080'});
  $('#n02').css({'background':'#0080FF', 'color':'white'});
  $('#ans02').val('No');
});*/
body,
html {
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
  background-color: fff;
}

.button {
  background: transparent;
  color: white;
  padding: 15px 20px;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  font-size: 16px;
  margin: 4px 2px;
  cursor: pointer;
  border-radius: 12px;
  width: 100px;
}

.button1 {
  color: #808080;
  border: 2px solid #e7e7e7;
}

.button:active,
.button:focus,
.button:visited {
  outline: none;
}

table {
  font-family: arial, sans-serif;
  border-collapse: collapse;
  width: 100%;
}

td,
th {
  border: none;
  padding: 15px;
  width: 50%;
}

tr:nth-child(even) {
  background-color: #f2f2f2;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>

  <tr>
    <td style="text-align:right;">
      Do you have any question #1?
    </td>
    <td>
      <input type="text" id="ans01" hidden/>
      <input type="button" id="y01" class="button button1" value="Yes" />
      <input type="button" id="n01" class="button button1" value="No" />
    </td>
  </tr>

  <tr>
    <td style="text-align:right;">
      Do you have any question #2?
    </td>
    <td>
      <input type="text" id="ans02" hidden/>
      <input type="button" id="y02" class="button button1" value="Yes" />
      <input type="button" id="n02" class="button button1" value="No" />
    </td>
  </tr>



</table>

您可以将 jquery/javascript 全部放在这里,然后使用带有 CSS 的单选按钮。

有了这个,您不再真正需要隐藏字段,因为您可以在服务器端和客户端检索所选单选按钮的值。

body,
html {
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
  background-color: fff;
}

.button {
  background: transparent;
  color: white;
  padding: 15px 20px;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  font-size: 16px;
  margin: 4px 2px;
  cursor: pointer;
  border-radius: 12px;
  width: 100px;
}

.button1 {
  color: #808080;
  border: 2px solid #e7e7e7;
}

.button:active,
.button:focus,
.button:visited {
  outline: none;
}

table {
  font-family: arial, sans-serif;
  border-collapse: collapse;
  width: 100%;
}

td,
th {
  border: none;
  padding: 15px;
  width: 50%;
}

tr:nth-child(even) {
  background-color: #f2f2f2;
}

.hidden {display:none;}

/*Change the color of our "buttons"*/
[type=radio]:checked + .button1 {
 background-color: #0080FF;
 color:#FFF;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>

  <tr>
    <td style="text-align:right;">
      Do you have any question #1?
    </td>
    <td>
      <input type="text" id="ans01" hidden/>
      <input type="radio" id="ans01_yes" value="Yes" name="ans01" class="hidden"><label class="button button1" for="ans01_yes">Yes</label>
      <input type="radio" id="ans01_no" value="No" name="ans01" class="hidden"><label class="button button1" for="ans01_no">No</label>
      
    </td>
  </tr>

  <tr>
    <td style="text-align:right;">
      Do you have any question #2?
    </td>
    <td>
      <input type="text" id="ans02" hidden/>
      <input type="radio" id="ans02_yes" value="Yes" name="ans02" class="hidden"><label class="button button1" for="ans02_yes">Yes</label>
      <input type="radio" id="ans02_no" value="No" name="ans02" class="hidden"><label class="button button1" for="ans02_no">No</label>
    </td>
  </tr>



</table>

附带说明,为表格数据保留 table 标签。有 许多 更好的布局元素的方法,使用 CSS 一起避免 table 标签。