125

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

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

4

21 回答 21

109

如果你使用 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];
   }
}
于 2008-11-12T22:12:12.763 回答
96

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

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!';

不需要查找数组:)

于 2008-11-12T22:24:05.750 回答
41

HTML5 标准中有一个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;
};
于 2013-02-25T06:16:12.090 回答
24

我有点惊讶,似乎没有人知道你完全可以这样做:

<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 的情况下实现这一点。:-)
于 2012-01-18T15:46:43.000 回答
22

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

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

于 2017-07-20T07:16:32.273 回答
15

早些时候...

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 来做。:-)

于 2008-11-12T22:10:19.520 回答
9

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

你所要做的就是:

input.labels

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

于 2017-11-14T02:24:07.897 回答
8

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

var nameOfLabel = someInput.attr('id');
var label = $("label[for='" + nameOfLabel + "']");
于 2008-11-12T22:15:04.550 回答
4

如果您愿意使用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并循环获取所需的一切。

于 2015-08-11T12:25:45.763 回答
2
$("label[for='inputId']").text()

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

于 2011-09-05T06:24:58.960 回答
2

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);
    });
};
于 2012-10-24T10:48:37.477 回答
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}]`)
于 2018-05-03T00:20:39.270 回答
2

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

使用HTML 5.2 参考 考虑到using的<label>指向,labels元素将是一个非空数组,并充当元素的链接,访问它的所有属性,包括它的.<input>for=<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>


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

使用多个<label>usingfor=时,您可以创建一个循环来显示所有这些,如下所示:

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>

于 2021-08-12T21:34:10.440 回答
1

实际上,在表单本身的标签中添加 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 函数中才能工作。

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

于 2013-11-26T18:29:34.783 回答
1

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

由于没有人发布无 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 的输入等),但可以随意添加它们。

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

于 2013-12-17T11:23:11.020 回答
1

最佳答案工作得很好,但在大多数情况下,循环遍历所有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将非常接近或靠近输入,这意味着上述函数中的循环只需要迭代非常少的次数。

于 2018-07-14T01:43:27.287 回答
0

使用 JQuery 选择器:

$("label[for="+inputElement.id+"]")
于 2011-04-12T20:11:35.277 回答
0

对于未来的搜索者......以下是 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");
于 2011-08-19T12:56:08.700 回答
0

我知道这已经过时了,但是我在一些解决方案上遇到了麻烦,并将其拼凑在一起。我已经在 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/

于 2014-05-21T18:07:29.867 回答
0

我为自己的需要而做的,可能对某人有用: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");
            }
        }
    }
});
于 2014-11-26T22:53:07.417 回答
0

我有点惊讶没有人建议使用 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');
});
于 2017-01-20T05:47:23.967 回答