使用JavaScript切换禁用属性

3
我有一个表单,里面有两个单选按钮和一个文本域。初始情况下,文本域是禁用的。当用户选择“自定义消息”单选按钮时,禁用属性将被移除,文本区变为可编辑状态。
现在,如果用户选择“虚假消息”单选按钮,则文本区应再次禁用。
到目前为止,我有以下代码:

document.getElementById('customMessageRadioButton').addEventListener('change', function() {
  if (document.getElementById('customMessageRadioButton').checked) {
    document.getElementById('customMessageTextArea').removeAttribute("disabled");
    document.getElementById('customMessageTextArea').focus();
  }

  if (!document.getElementById('customMessageRadioButton').checked) {
    document.getElementById('customMessageTextArea').setAttribute("disabled", "true");
  }
});
<input name="group1" id="dummy" type="radio" />Dummy Message
<input name="group1" id="customMessageRadioButton" type="radio" />Custom Message
<textarea disabled id="customMessageTextArea"></textarea>

我在这里面临的问题是,在我先选择“自定义消息”单选按钮,然后回去选择“虚拟消息”单选按钮时,文本区域没有被禁用。
这是我的 JS Bin P.S. 我不能使用jQuery。必须仅使用原始Javascript。

可能是与 JavaScript 删除 HTML 输入的“disabled”属性 重复。 - Francesco
当复选框失去其“checked”状态时,不会触发更改事件。 - Patrick Evans
@PatrickEvans 在我的代码片段中似乎已经触发了。 - Barmar
@Barmar,我刚测试过,不会出现这种情况。在勾选自定义复选框后返回虚拟文本框仍然保持启用状态。 - Patrick Evans
3个回答

8

根据您的要求更新了代码,为了让代码更简单,我使用了一个标记来切换文本区域的状态。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
  
  <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
  
</head>
<body>
  
    <input name="group1" id="dummy" type="radio" onclick="toggleRadio(false)"/>Dummy Message
    <input name="group1" id="customMessageRadioButton" onclick="toggleRadio(true)" type="radio" />Custom Message
    <textarea disabled id="customMessageTextArea"></textarea>

  <script>
    
    function toggleRadio(flag){
      if(!flag) {
        document.getElementById('customMessageTextArea').setAttribute("disabled", "true");
      } else {
        document.getElementById('customMessageTextArea').removeAttribute("disabled");
        document.getElementById('customMessageTextArea').focus();
      }
      
    }

  </script>
</body>
</html>

这里是更新过的 jsbin: http://jsbin.com/gadupoheke/1/edit?html,console,output

3

解决方案


如果您不想阅读全部内容,请查看控制部分。


布局


如果使用多个表单控件...

  • ...将所有内容包裹在<form>标签中,并给其一个#id。

  • ...将表单控件分组并将它们包裹在<fieldset>标签中。

  • ...给<fieldset>和表单控件添加#id。


访问


要完全控制一个<form>...

  • ...reference <form> tag with Document Object .forms property

    • Dot notation and #id of form

      var formObj = document.forms.**FormID** 
      
    • Or bracket notation and index of zero for first form

      var formObj = document.forms[0]
      

  • Next, collect all of the <form> tag's form controls using the .elements property:

        var fields = formObj.elements 
    

  • Having done that, you may use HTMLFormControlsCollection to reference any form control like a HTMLCollection by referencing the elements property and #id of the form control:

        var set = fields.**fieldsetID**
    
        var sel = fields.**selectID**
    
        var btn3 = fields[2] // third form control
    

控制


元素的属性最初是通过在HTML中硬编码来设置的:

<fieldset disabled>

或者通过JS方法进行编程,例如setAttribute()

fieldsetObj.setAttribute('disabled', true)

一旦属性被建立,如果你想要改变它,应该将其作为一个属性引用:

fieldsetObj.disabled = false;

事件处理


通过向 <form> 标签注册事件来实现 委托事件(点击此处了解详情)
 formObj.addEventListener('change', function)

最适用的事件包括:

change, input, click, focus, blur, submit, reset

当所有事件都委托给<form>标签时,Event Object属性Event.currentTarget将始终引用它。实际点击、更改、接收用户输入、获得焦点等的元素是事件的来源,可以作为Event.target进行引用。

一旦事件发生,事件链将进入捕获阶段

 e.currentTarget ===> e.target 

 <form> ============> <input>

然后是目标阶段

 e.target changed

 <input checked>

最后是 冒泡阶段,任何其他元素在此之后将通过事件触发,如果按照其自身的默认行为进行排列,则会被注册或安排进行(例如,如果x是这样的,则y是那样的):

 e.target =============> e.currentTarget

 <input checked> ======> <form>

标签


许多(但并非全部)表单控件具有特殊行为,以便更轻松地操作<form>及其表单控件:

  • <fieldset>:将[disabled]属性应用于它和所有嵌套的表单控件也将被启用/禁用。

  • <input type="radio">:将[name]属性应用于一组[单选框],当[checked]时它们将是互斥的(即只能选择一个)

  • 具有[name]属性的表单控件在<form>提交时将其value发送到服务器。

  • <label>:应用[for]属性并将其值设置为另一个表单控件的#id,将同步所述<label>和表单控件。如果发生单击事件,则相关联的表单控件也会像被单击一样行为。

上述继承特性并非全部用于演示,但提到它们是因为如果需要,可能会用到。


演示

细节在演示中有注释


// Reference the form tag
var main = document.forms.main;

// Collect all of #main form controls
var m = main.elements;

// Reference the radio group
var g0 = m.grp0;

// Register change event on #main
main.addEventListener('change', action);

// Define callback passing the Event Object
function action(e) {

  // if the changed element's [name] is "grp0"...
  if (e.target.name === "grp0") {

    // ...if "grp0" value is "on"...
    if (g0.value === 'on') {

      //...find the #set0 and enable it
      m.set0.disabled = false;
    } else {

      //...otherwise disable #set0
      m.set0.disabled = true;
    }

    //...otherwise if it isn't then ignore it.
  } else {
    return false;
  }
}

/* for future exansion of form#main add if else  condition between
|| if and else conditions
*/
<form id='main'>
  <fieldset id='ctrl'>
    <label>Group 1&nbsp;On&nbsp;
    <input name="grp0" value="on" type="radio" checked/>
    &nbsp;Off&nbsp;
    <input name="grp0" value="off" type="radio" />
  </label>
  </fieldset>
  <fieldset id='set0'>
    <legend>Group 1</legend>
    <textarea id="txt"></textarea>
  </fieldset>
</form>


0
const focusHandler = (e, status) => {
    if(status) {
      e?.target?.classList?.remove("text-grey");
      e?.target?.classList?.add("text-black");
    }else{
      e?.target?.classList?.remove("text-black");
      e?.target?.classList?.add("text-grey");
    }
  }

<Input className="text-grey" onChange={(e) => handleInputValue(e, "firstName")} onBlur={(e) => focusHandler(e, false)} onFocus={(e) => focusHandler(e, true)} placeholder="Enter your first name" />

你可以使用上面的代码来处理颜色代码的切换。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接