如何使用jQuery切换所有子元素的只读属性?

3

描述

我有一个表单,其中有一个按钮,当点击该按钮时,我想切换字段集的所有子元素的readonly属性。

HTML代码:

<form>
    <fieldset id="F1">
        <textarea id="T1" rows="5" cols="50" readonly required></textarea><br>
        <textarea id="T2" rows="5" cols="50" readonly required></textarea><br>
        <textarea id="T3" rows="5" cols="50" readonly required></textarea><br>
    </fieldset>
    <button type="button" id="button" onclick="togglerequire('#F1')">
        Click Me
        </button>
</form>

jQuery:

function togglerequire(id){
    $(id).children().each(function(){
        var re = $(this).prop('required');
        $(this).prop('required', !re);
    });
}

回到问题:

我可以通过id对单个元素进行操作,但是一旦我尝试在由父id定义的子元素上执行切换操作,它就停止工作了,我无法弄清楚原因。


您想同时切换只读属性和必填属性,还是只切换其中一个? - David Thomas
但是如果我能弄清楚其中一个,我就认为我能够同时做到两个。 - Petay87
你可以这么做,但是有一种更简单的替代方案;我的答案可能更容易使用。 - David Thomas
5个回答

2
您需要将函数更新为以下内容:
function togglerequire(id){
    $(id).children("textarea").each(function(){
        var re = $(this).prop('readonly'); 
        $(this).prop('readonly', !re);
    });
}

请注意,您切换了错误的属性。此外,最好我们可以提供特定的选择器,如文本区域或类等。

实际上,想法是设置这两个属性,但我似乎提到了错误的一个。如果有不同的子元素,它会如何工作? - Petay87
2
然后你可以尝试以下代码 **children("textarea, input")**。 - Nikhil Aggarwal

1
由于您正在使用 jquery,因此您可以查找一个元素并获取其所有具有 readonly 属性的子元素,然后像以下代码片段一样调用 .toggle

$('#button').click(function(){
   $('#F1').children('[readonly]').toggle();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<fieldset id="F1">
    <textarea id="T1" rows="5" cols="50" readonly required></textarea><br>
    <textarea id="T2" rows="5" cols="50" readonly required></textarea><br>
    <textarea id="T3" rows="5" cols="50" readonly required></textarea><br>
</fieldset>
<button type="button" id="button">Click Me</button>

同样的情况也适用于必填或只读和必填的情况,例如:
$('#F1').children('[required]').toggle();// Correct
$('#F1').children('[readonly]').toggle();// Correct
$('#F1').children('[readonly][required]').toggle();// Correct

$('#F1').children('readonly').toggle();// incorrect

注意:如果您尝试获取没有[]的子元素来进行readonly操作,例如$('#F1').children('readonly').toggle();,则不会切换。您需要在readonlyrequired或两者周围放置[]
更新1:
如您所需,以下代码片段将使所有具有required属性的子元素在click event中变为readonly

$('#button').click(function(){
   $('#F1').children('[required]').prop('readonly', true);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<fieldset id="F1">
    <textarea id="T1" rows="5" cols="50"  required></textarea><br>
    <textarea id="T2" rows="5" cols="50"  required></textarea><br>
    <textarea id="T3" rows="5" cols="50"  required></textarea><br>
</fieldset>
<button type="button" id="button">Click Me</button>


你的代码片段无法工作,它似乎隐藏了文本区域并未将其定义为只读。 - Petay87
@Petay87 正在切换文本区域。您可以尝试使用必填和只读两种选项。 - Afnan Ahmad
我不想让它切换文本区域的可见性,问题是如何将它们设置为只读。 - Petay87
抱歉,您的问题标题是如何切换,但您没有提到您想要使它们只读。由于您已经提到了它们是只读的。 - Afnan Ahmad

1

虽然您已经接受了一个答案,但如果意图是防止用户与处于:disabled/readonly状态的<textarea>元素进行交互,那么更容易的方法是避免迭代这些子元素,而是将disabled属性分配给父级<fieldset>

// named function to call:
function toggleActiveStatus() {

  // I'm using native DOM approaches here simply because
  // they're 'cheaper' (premature optimisation, however)
  // than invoking jQuery unnecessarily.

  // here we use let statement to assign the element found
  // by 'document.querySelector()' (which returns the first
  // element matching the supplied CSS selector, or null if
  // there is no matching element) to the 'parent' variable:
  let parent = document.querySelector(

    // here we retrieve the CSS selector held in the
    // <button> element's 'data-affects' custom
    // (and valid) data-* attribute:
    this.dataset.affects
  ),

    // here we find the current state of the
    // element, returned as a Boolean true
    // if the <fieldset> is disabled or
    // false if the <fieldset> is not
    // disabled:
    currentState = parent.disabled;

  // here we simply set the disabled property
  // of the <fieldset> to the inverse of its
  // current state:
  parent.disabled = !currentState;

}

// binding the named function (note the deliberate
// lack of parentheses) using jQuery, rather than
// in-line event-handlers, to avoid the use of
// difficult-to-maintain JavaScript, and switching
// to the 'unobtrusive' JavaScript approach:
$('#button').on('click', toggleActiveStatus);

function toggleActiveStatus() {
  let parent = document.querySelector(this.dataset.affects),
    currentState = parent.disabled;

  parent.disabled = !currentState;

}

$('#button').on('click', toggleActiveStatus);
body {
  margin-bottom: 5em;
}

textarea {
  display: block;
}

button {
  text-transform: sentence;
}

#F1:disabled+button::before {
  content: "enable";
}

#F1:not(:disabled)+button::before {
  content: "disable";
}

#F1+button::after {
  content: ' textarea elements';
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
  <fieldset id="F1">
    <textarea id="T1" rows="5" cols="50" readonly required></textarea>
    <textarea id="T2" rows="5" cols="50" readonly required></textarea>
    <textarea id="T3" rows="5" cols="50" readonly required></textarea>
  </fieldset>
  <button type="button" id="button" data-affects="#F1"></button>
</form>

此外,由于使用jQuery对于这种方法并不必要,以下展示了一种纯JavaScript方法,使用本地的DOM API。
function toggleActiveStatus() {
  let parent = document.querySelector(this.dataset.affects),
    currentState = parent.disabled;

  parent.disabled = !currentState;

}

// here we use document.querySelector(), as above, to find
// the first element matching the supplied CSS selector:
document.querySelector('#button')

  // and then use EventTarget.addEventListener() to bind
  // the named function (again: note the deliberate lack
  // of parentheses) as the event-handler for the 'click'
  // event:
  .addEventListener('click', toggleActiveStatus);

function toggleActiveStatus() {
  let parent = document.querySelector(this.dataset.affects),
    currentState = parent.disabled;

  parent.disabled = !currentState;

}

document.querySelector('#button').addEventListener('click', toggleActiveStatus);
body {
  margin-bottom: 5em;
}

textarea {
  display: block;
}

button {
  text-transform: sentence;
}

#F1:disabled+button::before {
  content: "enable";
}

#F1:not(:disabled)+button::before {
  content: "disable";
}

#F1+button::after {
  content: ' textarea elements';
}
<form>
  <fieldset id="F1">
    <textarea id="T1" rows="5" cols="50" readonly required></textarea>
    <textarea id="T2" rows="5" cols="50" readonly required></textarea>
    <textarea id="T3" rows="5" cols="50" readonly required></textarea>
  </fieldset>
  <button type="button" id="button" data-affects="#F1"></button>
</form>

参考文献:


0

试试这个:

function toggleAttributesOn(selector, elementSelector, attribute) {
   var container = document.querySelector(selector);
   if(!!container && !!attribute) {
     var elements = [].slice.call(container.querySelectorAll(elementSelector));
     elements.forEach(function(element) {
       if(['readonly', 'required'].indexOf(attribute) > -1) {
         element.getAttribute(attribute) !== null? element.removeAttribute(attribute): element.setAttribute(attribute, true); 
       }
       else {
         element.setAttribute(attribute, !element.getAttribute(attribute));
       }
     });
   }
}



// demo code
function togglerequire(selector) {
   toggleAttributesOn(selector, 'textarea', 'readonly');
}
<form>
    <fieldset id="F1">
        <textarea id="T1" rows="5" cols="50" readonly required></textarea><br>
        <textarea id="T2" rows="5" cols="50" readonly required></textarea><br>
        <textarea id="T3" rows="5" cols="50" readonly required></textarea><br>
    </fieldset>
    <button type="button" id="button" onclick="togglerequire('#F1')">
        Click Me
        </button>
</form>


0

这应该可以解决问题。 获取此 div 中的所有输入并将它们标记为禁用。

$("#divID:input").attr("disabled", true);


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