【问题标题】:Find html label associated with a given input查找与给定输入关联的 html 标签
【发布时间】:2010-09-22 01:56:10
【问题描述】:

假设我有一个 html 表单。每个 input/select/textarea 都会有一个对应的 <label> 并将 for 属性设置为它的同伴的 id。在这种情况下,我知道每个输入将只有一个标签。

给定一个 javascript 中的输入元素——例如通过 onkeyup 事件——找到它的关联标签的最佳方法是什么?

【问题讨论】:

  • 请注意,一个元素可能有多个标签,我见过一些应用程序(SAP 为一个)每个元素有多个标签。
  • function getInputLabel(thisElement) { var theAssociatedLabel,elementID; elementID = thisElement.id; theAssociatedLabel = thisElement.parentNode.querySelector("label[for='" + elementID + "']"); console.log('theAssociatedLabel.htmlFor: ' + theAssociatedLabel.htmlFor); theAssociatedLabel.style.backgroundColor = "green";//Set the label background color to green };
  • 或者只是 node.parentNode.querySelector("label[for='" + node.id + "']").innerHTML;大声笑

标签: javascript html label


【解决方案1】:

解决方案一<label>:一<input>

使用HTML 5.2 reference 考虑到使用for= 指向<input><label>labels 元素将是一个非空数组,并充当到<label> 元素的链接,访问它的所有属性,包括它的id=

function myFunction() {
  document.getElementById("p1").innerHTML = "The first label associated with input: <b>" + document.getElementById("input4").labels[0].id + "</b>";

}
<form>
  <label id="theLabel" for="input4">my id is "theLabel"</label>
  <input name="name1" id="input4" value="my id is input4">
  <br>
</form>

<p>Click the "click me" button to see the label properties</p>

<button onclick="myFunction()">click me</button>


<p id="p1"></p>

解决方案很多&lt;label&gt;:一个&lt;input&gt;

如果有多个&lt;label&gt; 使用for=,您可以创建一个循环来显示所有这些,如下所示:

function myFunction2() {

var x = document.getElementById("input7").labels;
let text = "";
for (let i = 0; i < x.length; i++) {
  text += x[i].id + "<br>";
}
document.getElementById("p7").innerHTML = text;
}
<b>Three labels for one input</b><br>
<br>
<form>
  <label id="theLabel2" for="input7">my id is "theLabel2</label><br>
  <label id="theLabel3" for="input7">my id is "theLabel3</label><br>
  <label id="theLabel4" for="input7">my id is "theLabel4</label><br>
  <input name="name1" id="input7" value="my id is input7">
  <br>
</form>

<p>Click the "click me" button to see the label properties</p>
<button onclick="myFunction2()">click me2</button>

<p id="p7"></p>

【讨论】:

    【解决方案2】:

    使用 ES6 特性(如解构和隐式返回)将其变成方便的单行列的真正简洁的解决方案是:

    const getLabels = ({ labels, id }) => labels || document.querySelectorAll(`label[for=${id}]`)
    

    或者简单地获取一个标签,而不是一个 NodeList:

    const getFirstLabel = ({ labels, id }) => labels && labels[0] || document.querySelector(`label[for=${id}]`)
    

    【讨论】:

      【解决方案3】:

      HTML5 standard 中有一个 labels 属性,它指向与输入元素关联的标签。

      所以你可以使用这样的东西(支持原生 labels 属性,但在浏览器不支持的情况下检索标签)...

      var getLabelsForInputElement = function(element) {
          var labels = [];
          var id = element.id;
      
          if (element.labels) {
              return element.labels;
          }
      
          id && Array.prototype.push
              .apply(labels, document.querySelector("label[for='" + id + "']"));
      
          while (element = element.parentNode) {
              if (element.tagName.toLowerCase() == "label") {
                  labels.push(element);
              }  
          }
      
          return labels;
      };
      
      // ES6
      var getLabelsForInputElement = (element) => {
          let labels;
          let id = element.id;
      
          if (element.labels) {
              return element.labels;
          }
      
          if (id) {
              labels = Array.from(document.querySelector(`label[for='${id}']`)));
          }
      
          while (element = element.parentNode) {
              if (element.tagName.toLowerCase() == "label") {
                  labels.push(element);
              }  
          }
      
          return labels;
      };
      

      如果你使用 jQuery,那就更简单了...

      var getLabelsForInputElement = function(element) {
          var labels = $();
          var id = element.id;
      
          if (element.labels) {
              return element.labels;
          }
      
          id && (labels = $("label[for='" + id  + "']")));
      
          labels = labels.add($(element).parents("label"));
      
          return labels;
      };
      

      【讨论】:

      【解决方案4】:

      最佳答案非常有效,但在大多数情况下,循环遍历所有 label 元素是多余且效率低下的。

      这是一个获取label 的有效函数,它与input 元素一起使用:

      function getLabelForInput(id)
      {
          var el = document.getElementById(id);
          if (!el)
              return null;
          var elPrev = el.previousElementSibling;
          var elNext = el.nextElementSibling;
          while (elPrev || elNext)
          {
              if (elPrev)
              {
                  if (elPrev.htmlFor === id)
                      return elPrev;
                  elPrev = elPrev.previousElementSibling;
              }
              if (elNext)
              {
                  if (elNext.htmlFor === id)
                      return elNext;
                  elNext = elNext.nextElementSibling;
              }
          }
          return null;
      }
      

      对我来说,这一行代码就足够了:

      el = document.getElementById(id).previousElementSibling;
      

      在大多数情况下,label 会非常靠近或靠近输入,这意味着上述函数中的循环只需要迭代非常少的次数。

      【讨论】:

        【解决方案5】:

        document.querySelector("label[for=" + vHtmlInputElement.id + "]");

        这以最简单和最精简的方式回答了这个问题。 这使用 vanilla javascript 并适用于所有主流适当的浏览器。

        【讨论】:

        【解决方案6】:

        所有其他答案都非常过时了!!

        你所要做的就是:

        input.labels
        

        HTML5 已被所有主要浏览器支持多年。绝对没有理由您必须自己从头开始制作它或填充它!从字面上看,只需使用 input.labels 即可解决您的所有问题。

        【讨论】:

        【解决方案7】:

        我有点奇怪没有人建议使用 CSS 关系方法?

        在样式表中,您可以从元素选择器中引用标签:

        <style>
        
        //for input element with class 'YYY'
        input.YYY + label {}
        
        </style>
        

        如果复选框的 id 为“XXX” 那么标签将通过 jQuery 找到:

        $('#XXX + label');
        

        您还可以应用 .find('+ label') 从 jQuery 复选框元素返回标签,即在循环时很有用:

        $('input[type=checkbox]').each( function(){
           $(this).find('+ label');
        });
        

        【讨论】:

        • 糟糕,我应该注意,这依赖于紧跟在元素之后的标签。
        【解决方案8】:

        如果您愿意使用querySelector(您可以使用,甚至可以使用 IE9,有时甚至可以使用 IE8!),另一种方法变得可行。

        如果您的表单字段有一个 ID,并且您使用标签的 for 属性,这在现代 JavaScript 中变得非常简单:

        var form = document.querySelector('.sample-form');
        var formFields = form.querySelectorAll('.form-field');
        
        [].forEach.call(formFields, function (formField) {
            var inputId = formField.id;
            var label = form.querySelector('label[for=' + inputId + ']');
            console.log(label.textContent);
        });
        

        有些人注意到多个标签;如果它们都对for 属性使用相同的值,只需使用querySelectorAll 而不是querySelector 并循环获取所需的一切。

        【讨论】:

          【解决方案9】:

          我是根据自己的需要制作的,可能对某人有用:JSFIDDLE

          $("input").each(function () {
              if ($.trim($(this).prev('label').text()) != "") {
                  console.log("\nprev>children:");
                  console.log($.trim($(this).prev('label').text()));
              } else {
                  if ($.trim($(this).parent('label').text()) != "") {
                      console.log("\nparent>children:");
                      console.log($.trim($(this).parent('label').text()));
                  } else {
                      if ($.trim($(this).parent().prev('label').text()) != "") {
                          console.log("\nparent>prev>children:");
                          console.log($.trim($(this).parent().prev('label').text()));
                      } else {
                          console.log("NOTFOUND! So set your own condition now");
                      }
                  }
              }
          });
          

          【讨论】:

            【解决方案10】:

            我知道这已经过时了,但我在一些解决方案上遇到了麻烦,于是拼凑起来。我已经在 Windows(Chrome、Firefox 和 MSIE)和 OS X(Chrome 和 Safari)上对此进行了测试,并相信这是最简单的解决方案。它适用于这三种附加标签的方式。

            <label><input type="checkbox" class="c123" id="cb1" name="item1">item1</label>
            
            <input type="checkbox" class="c123" id="cb2" name="item2">item2</input>
            
            <input type="checkbox" class="c123" id="cb3" name="item3"><label for="cb3">item3</label>
            

            使用 jQuery:

            $(".c123").click(function() {
                $cb = $(this);
                $lb = $(this).parent();
                alert( $cb.attr('id') + ' = ' + $lb.text() );
            });
            

            我的 JSFiddle:http://jsfiddle.net/pnosko/6PQCw/

            【讨论】:

            • 这实际上不起作用——它只是返回父元素的文本,有时恰好是你想要的文本。
            【解决方案11】:

            正如已经提到的,(当前)评价最高的答案没有考虑在标签中嵌入输入的可能性。

            由于没有人发布无 JQuery 的答案,这是我的:

            var labels = form.getElementsByTagName ('label');
            var input_label = {};
            for (var i = 0 ; i != labels.length ; i++)
            {
                var label = labels[i];
                var input = label.htmlFor
                          ? document.getElementById(label.htmlFor)
                          : label.getElementsByTagName('input')[0];
                input_label[input.outerHTML] = 
                    (label.innerText || label.textContent); // innerText for IE8-
            }
            

            在此示例中,为简单起见,查找表直接由输入的 HTML 元素索引。这几乎没有效率,你可以随心所欲地调整它。

            如果您想一次获取多个表单的标签,您可以使用一个表单作为基本元素,或者整个文档。

            不检查不正确的 HTML(标签内有多个或缺少输入,缺少相应 htmlFor id 的输入等),但请随意添加它们。

            您可能想要修剪标签文本,因为当输入嵌入标签时,通常会出现尾随空格。

            【讨论】:

              【解决方案12】:

              在表单本身的标签中添加一个id实际上要容易得多,例如:

              <label for="firstName" id="firstNameLabel">FirstName:</label>
              
              <input type="text" id="firstName" name="firstName" class="input_Field" 
                     pattern="^[a-zA-Z\s\-]{2,25}$" maxlength="25"
                     title="Alphabetic, Space, Dash Only, 2-25 Characters Long" 
                     autocomplete="on" required
              />
              

              然后,你可以简单地使用这样的东西:

              if (myvariableforpagelang == 'es') {
                 // set field label to spanish
                 document.getElementById("firstNameLabel").innerHTML = "Primer Nombre:";
                 // set field tooltip (title to spanish
                 document.getElementById("firstName").title = "Alfabética, espacio, guión Sólo, 2-25 caracteres de longitud";
              }
              

              javascript 必须在 body onload 函数中才能工作。

              只是一个想法,对我来说效果很好。

              【讨论】:

                【解决方案13】:

                之前...

                var labels = document.getElementsByTagName("LABEL"),
                    lookup = {},
                    i, label;
                
                for (i = 0; i < labels.length; i++) {
                    label = labels[i];
                    if (document.getElementById(label.htmlFor)) {
                        lookup[label.htmlFor] = label;
                    }
                }
                

                稍后...

                var myLabel = lookup[myInput.id];
                

                尖刻评论:是的,你也可以用 JQuery 来做。 :-)

                【讨论】:

                • 不错。我会稍微重构一下,以便它在我第一次调用该方法时构建查找,但它应该可以解决问题。
                • 我暗示您将只构建一次查找。
                • 请注意其中有一个小错误:使用“htmlFor”属性,而不是“for”,因为后者是JS中的保留字。我倾向于忘记使用标签对象时... :-)
                • 我有办法做到这一点,而无需上面的查找数组。
                • 我的意思是在方法中移动初始化代码,而不是只做一次:(
                【解决方案14】:

                使用 jquery 你可以做类似的事情

                var nameOfLabel = someInput.attr('id');
                var label = $("label[for='" + nameOfLabel + "']");
                

                【讨论】:

                • 虽然是祖先,但可能会错过标签。
                【解决方案15】:

                如果你使用 jQuery,你可以这样做

                $('label[for="foo"]').hide ();
                

                如果您不使用 jQuery,则必须搜索标签。这是一个将元素作为参数并返回关联标签的函数

                function findLableForControl(el) {
                   var idVal = el.id;
                   labels = document.getElementsByTagName('label');
                   for( var i = 0; i < labels.length; i++ ) {
                      if (labels[i].htmlFor == idVal)
                           return labels[i];
                   }
                }
                

                【讨论】:

                  【解决方案16】:

                  Gijs 的回答对我来说最有价值,但不幸的是,该扩展程序不起作用。

                  这是一个有效的重写扩展,它可能对某人有所帮助:

                  jQuery.fn.getLabels = function () {
                      return this.map(function () {
                          var parentLabels = $(this).parents('label').get();
                          var associatedLabels = this.id ? associatedLabels = $("label[for='" + this.id + "']").get() : [];
                          return parentLabels.concat(associatedLabels);
                      });
                  };
                  

                  【讨论】:

                    【解决方案17】:

                    我有点惊讶,似乎没人知道你是 perfectly allowed 做的:

                    <label>Put your stuff here: <input value="Stuff"></label>
                    

                    任何建议的答案都不会选择,但正确标记输入。

                    下面是一些考虑到这种情况的代码:

                    $.fn.getLabels = function() {
                        return this.map(function() {
                            var labels = $(this).parents('label');
                            if (this.id) {
                                labels.add('label[for="' + this.id + '"]');
                            }
                            return labels.get();
                        });
                    };
                    

                    用法:

                    $('#myfancyinput').getLabels();
                    

                    一些注意事项:

                    • 编写代码是为了清晰,而不是为了性能。可能会提供性能更高的替代方案。
                    • 此代码支持一次获取多个项目的标签。如果这不是您想要的,请根据需要进行调整。
                    • 如果您要使用 aria-labelledby 之类的东西,它仍然无法处理(留给读者作为练习)。
                    • 在支持不同的用户代理和辅助技术时,使用多个标签是一项棘手的工作,因此请做好测试并自行承担风险等。
                    • 是的,您也可以在不使用 jQuery 的情况下实现这一点。 :-)

                    【讨论】:

                    • 很高兴看到有人提出隐式标签关联,而不是假设label 元素上总会有一个for 属性。
                    【解决方案18】:
                    $("label[for='inputId']").text()
                    

                    这帮助我使用其 ID 获取输入元素的标签。

                    【讨论】:

                      【解决方案19】:

                      对于未来的搜索者...以下是 FlySwat 已接受答案的 jQuery 化版本:

                      var labels = $("label");
                      for (var i = 0; i < labels.length; i++) {
                          var fieldId = labels[i].htmlFor;
                          if (fieldId != "") {
                              var elem = $("#" + fieldId);
                              if (elem.length != 0) {
                                  elem.data("label", $(labels[i]));   
                              }
                          }
                      }
                      

                      使用:

                      $("#myFormElemId").data("label").css("border","3px solid red");
                      

                      【讨论】:

                      • +1,但据我所知,没有理由在第一个块中使用 jQuery 版本:它不会更短或更易读,而且纯 javascript 可能会表现得更好。不过,如果有一个关于如何使用它的 jQuery 示例,那就太好了。
                      • 显然,对我们中的许多人来说,这种方法并没有太多技术原因,而是至少在我的情况下是人力资源的原因。想象一下,您有一个团队,其中包括设计师、集成商,甚至是您已经习惯使用 jQuery 的初级开发人员。保持 jQuery 范式可以帮助提高生产力并减少挫败感。
                      • 这不是很jQuery-ified。为什么for 循环超过each()?为什么是htmlFor 而不是attr("for")
                      • 取决于视角,我猜。消费是 jQuery 化的,而不是内部的。
                      【解决方案20】:

                      使用 JQuery 选择器:

                      $("label[for="+inputElement.id+"]")
                      

                      【讨论】:

                        【解决方案21】:

                        首先,扫描页面中的标签,并从实际的表单元素中分配对标签的引用:

                        var labels = document.getElementsByTagName('LABEL');
                        for (var i = 0; i < labels.length; i++) {
                            if (labels[i].htmlFor != '') {
                                 var elem = document.getElementById(labels[i].htmlFor);
                                 if (elem)
                                    elem.label = labels[i];         
                            }
                        }
                        

                        然后,你可以简单地去:

                        document.getElementById('MyFormElem').label.innerHTML = 'Look ma this works!';
                        

                        不需要查找数组:)

                        【讨论】:

                        • 您能解释一下您对 expando 属性的使用与我的不同之处吗?我不使用任何“查找数组”,我使用具有属性的对象。 “element.label”、“element['label']”或“lookup['elementId']”之间只有句法上的区别。在幕后他们是相同的东西
                        • 这更好,因为我不必在周围保​​留单独的对象-关系直接与输入元素一起存储。
                        • 这应该由浏览器处理
                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2021-11-15
                        • 2019-04-30
                        • 2023-03-10
                        • 2015-01-24
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多