简体   繁体   English

如何使用javascript根据另一个单元格上的单选按钮更改表格单元格颜色?

[英]How to change a table cell color based on radio button on another cell with javascript?

I want to change a cell color in case one of the radio buttons in other cells are being clicked.如果单击其他单元格中的单选按钮之一,我想更改单元格颜色。 I don't know why my code doesn't work我不知道为什么我的代码不起作用

 <tr> <td>class</td> <td><input name="class"type="radio" onClick="enableElement1(this.form.work_permit);"/></td> <td><input name="class"type="radio" onClick="enableElement2(this.form.work_permit);"/></td> <td><input name="class"type="radio" onclick="disableElement(this.form.work_permit);"/></td> <td><textarea for="work_permit"name="comments"rows="4"cols="20"></textarea></td> </tr> <script> function disableElement() { text.value = ' - NA - '; obj.disabled= true; function enableElement1(obj) { obj.value = ''; obj.disabled = false; } function enableElement2(obj) { obj.value = ''; obj.disabled = false; } </script> <style> enableElement1{ color:green; } enableElement2{ color:red; } </style>

There are a few problems with your current implementation:您当前的实现存在一些问题:

  1. the <tr> element is not wrapped in either a <tbody> . <tr>元素未包含在<tbody> <thead> , <tfoot> or <table> element (the only elements of which a <tr> element may be a child, <thead><tfoot><table>元素( <tr>元素可能是其子元素的唯一元素,
  2. the only element with a for attribute is the <label> element;唯一具有for属性的元素是<label>元素; the value of the for attribute should be equal to the id attribute-value of the element to which that <label> refers (a <label> element can refer to only one element, though an <input> , <textarea> or <select> element can be associated with multiple <label> elements), for属性的值应该等于<label>引用的元素的id属性值(一个<label>元素只能引用一个元素,尽管<input><textarea><select>元素可以关联多个<label>元素),
  3. Your <table> data doesn't appear to be tabular in nature (from the short, incomplete sample provided);您的<table>数据本质上似乎不是表格(来自提供的简短、不完整的样本); if you're using a <table> for layout reasons then you should consider changing your approach,如果您出于布局原因使用<table>那么您应该考虑改变您的方法,
  4. you're using multiple functions to do the same thing, albeit with different elements;你正在使用多个函数来做同样的事情,尽管有不同的元素; remember the DRY principle: D on't R epeat Y ourself, and记得DRY原则:d on't [R EPEATŸ我们自己,和
  5. you're using obtrusive JavaScript – with event-handlers (the onclick ) in the HTML – this complicates future maintenance of your code.您正在使用引人注目的 JavaScript – 在 HTML 中带有事件处理程序( onclick ) – 这会使您的代码的未来维护变得复杂。

With all that in mind, might I suggest an alternative:考虑到所有这些,我是否可以提出一个替代方案:

 // creating a single named function to handle the required functionality: const activateElement = function() { // here 'this' refers to the element to which the event-listener was bound, // automagically supplied from the EventTarget.addEventListener() method; // from the changed <input> we find the closest <tr> ancestor element: let textarea = this.closest('tr').querySelector('textarea'), // from the chnaged <input> we find the closest <td> ancestor element: cell = this.closest('td'), // from the <td> (the 'cell' variable) we retrieve the textContent, // and convert it to lower-case, using String.prototype.toLowerCase(): active = cell.textContent.toLowerCase(); // here set the custom data-* attribute-value to be equal to the // value retrieved from the <td> ('cell') element: textarea.dataset.isactive = active; // here we set the disabled property to the result of the expression, // if the 'active' variable is exactly equal to 'none' the disabled // property is set to true (and the element is disabled), otherwise // the disabled property is set to false (and the element is enabled): textarea.disabled = active === 'none'; }; // here we retrieve a (non-live) NodeList of all <input> elements with // the 'type' attribute-value equal to 'radio'; we then use // NodeList.prototype.forEach() to iterate over those elements: document.querySelectorAll('input[type=radio]').forEach( // here we use an Arrow function (because we don't need to use 'this'); // 'input' (the argument) is a reference to the current Node of the // NodeList over which we're iterating: (input) => { // here we bind an event-listener to the current <input> element/Node // and bind the activateElement function (note the deliberate lack of // parentheses) as the event-handler for the 'change' event: input.addEventListener('change', activateElement); });
 /* here we select all <textarea> elements with a data-isactive attribute-value is equal to 'one': */ textarea[data-isactive="one"] { background-color: lime; } /* here we select all <textarea> elements with a data-isactive attribute-value is equal to 'two': */ textarea[data-isactive="two"] { background-color: fuchsia; } /* here we select all <textarea> elements; this selector is less specific than the preceding selectors so this will only apply to those <textarea> elements without a 'data-isactive' attribute, or with an attribute-value which is not equal to either 'one' or 'two': */ textarea { background-color: #fff; }
 <!-- using valid HTML, with the <tr> appropriately wrapped in a <tbody> element, itself within a <table> element: --> <table> <tbody> <tr> <th>class</th> <!-- wrapping the <input> elements in <label> elements, in order that the user sees some instruction/guidance as to what the form control does; and removing the onclick event-handler: --> <td><label>one<input name="class" type="radio" /></label></td> <td><label>two<input name="class" type="radio" /></label></td> <td><label>none<input name="class" type="radio" /></label></td> <td><textarea name="comments"></textarea></td> </tr> </tbody> </table>

JS Fiddle demo . JS小提琴演示

Now, the above function is written specifically to allow for additional rows to be added to the <table> which can call the same function, for example:现在,上面的函数是专门编写的,以允许将其他行添加到可以调用相同函数的<table>中,例如:

 const activateElement = function() { let textarea = this.closest('tr').querySelector('textarea'), cell = this.closest('td'), active = cell.textContent.toLowerCase(); textarea.dataset.isactive = active; textarea.disabled = active === 'none'; }; document.querySelectorAll('input[type=radio]').forEach( (input) => { input.addEventListener('change', activateElement); });
 textarea[data-isactive="one"] { background-color: lime; } textarea[data-isactive="two"] { background-color: fuchsia; } textarea { background-color: #fff; }
 <table> <tbody> <tr> <th>class</th> <td><label>one<input name="class1" type="radio" /></label></td> <td><label>two<input name="class1" type="radio" /></label></td> <td><label>none<input name="class1" type="radio" /></label></td> <td><textarea name="comments"></textarea></td> </tr> <tr> <th>class</th> <td><label>one<input name="class2" type="radio" /></label></td> <td><label>two<input name="class2" type="radio" /></label></td> <td><label>none<input name="class2" type="radio" /></label></td> <td><textarea name="comments"></textarea></td> </tr> <tr> <th>class</th> <td><label>one<input name="class3" type="radio" /></label></td> <td><label>two<input name="class3" type="radio" /></label></td> <td><label>none<input name="class3" type="radio" /></label></td> <td><textarea name="comments"></textarea></td> </tr> <tr> <th>class</th> <td><label>one<input name="class4" type="radio" /></label></td> <td><label>two<input name="class4" type="radio" /></label></td> <td><label>none<input name="class4" type="radio" /></label></td> <td><textarea name="comments"></textarea></td> </tr> </tbody> </table>

JS Fiddle demo . JS小提琴演示

Note, of course, that you still have to adjust the name attribute of the added groups of <input> elements.请注意,当然,您仍然需要调整添加的<input>元素组的name属性。

References:参考:

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

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