简体   繁体   English

查找与给定输入关联的 html label

[英]Find html label associated with a given input

Let's say I have an html form.假设我有一个 html 表格。 Each input/select/textarea will have a corresponding <label> with the for attribute set to the id of it's companion.每个 input/select/textarea 都会有一个对应的<label> ,其中for属性设置为其同伴的 id。 In this case, I know that each input will only have a single label.在这种情况下,我知道每个输入只有一个 label。

Given an input element in javascript — via an onkeyup event, for example — what's the best way to find it's associated label?给定 javascript 中的输入元素——例如,通过 onkeyup 事件——找到它关联的 label 的最佳方法是什么?

If you are using jQuery you can do something like this 如果你使用jQuery,你可以做这样的事情

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

If you aren't using jQuery you'll have to search for the label. 如果您不使用jQuery,则必须搜索标签。 Here is a function that takes the element as an argument and returns the associated label 这是一个将元素作为参数并返回关联标签的函数

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];
   }
}

First, scan the page for labels, and assign a reference to the label from the actual form element: 首先,扫描页面中的标签,并从实际表单元素中分配对标签的引用:

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];         
    }
}

Then, you can simply go: 然后,你可以简单地去:

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

No need for a lookup array :) 不需要查找数组:)

There is a labels property in the HTML5 standard which points to labels which are associated to an input element. HTML5标准中有一个labels属性,它指向与输入元素关联的标签。

So you could use something like this (support for native labels property but with a fallback for retrieving labels in case the browser doesn't support it)... 所以你可以使用这样的东西(支持原生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;
};

Even easier if you're using jQuery... 如果你使用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;
};

I am a bit surprised that nobody seems to know that you're perfectly allowed to do: 我有点惊讶,似乎没有人知道你完全被允许这样做:

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

Which won't get picked up by any of the suggested answers, but will label the input correctly. 哪个不会被任何建议的答案选中,但正确标记输入。

Here's some code that does take this case into account: 以下是一些将此案例考虑在内的代码:

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

Usage: 用法:

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

Some notes: 一些说明:

  • The code was written for clarity, not for performance. 编写代码是为了清晰起见,而不是为了提高性能。 More performant alternatives may be available. 可能有更多高性能的替代品。
  • This code supports getting the labels of multiple items in one go. 此代码支持一次性获取多个项目的标签。 If that's not what you want, adapt as necessary. 如果这不是您想要的,请根据需要进行调整。
  • This still doesn't take care of things like aria-labelledby if you were to use that (left as an exercise to the reader). 如果您使用它(作为练习留给读者),这仍然不会像aria-labelledby那样处理。
  • Using multiple labels is a tricky business when it comes to support in different user agents and assistive technologies, so test well and use at your own risk, etc. etc. 在支持不同的用户代理和辅助技术时,使用多个标签是一项棘手的工作,因此测试良好,使用风险等等。
  • Yes, you could also implement this without using jQuery. 是的,你也可以在不使用jQuery的情况下实现它。 :-) :-)

Earlier... 此前...

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;
    }
}

Later... 后来...

var myLabel = lookup[myInput.id];

Snarky comment: Yes, you can also do it with JQuery. Snarky评论:是的,您也可以使用JQuery。 :-) :-)

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

This answers the question in the simplest and leanest manner. 这以最简单和最简洁的方式回答了这个问题。 This uses vanilla javascript and works on all main-stream proper browsers. 这使用vanilla javascript并适用于所有主流适当的浏览器。

with jquery you could do something like 用jquery你可以做点什么

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

If you're willing to use querySelector (and you can, even down to IE9 and sometimes IE8!), another method becomes viable. 如果你愿意使用querySelector (你甚至可以使用IE9,有时甚至是IE8!),另一种方法就变得可行了。

If your form field has an ID, and you use the label's for attribute, this becomes pretty simple in modern JavaScript: 如果您的表单字段具有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);
});

Some have noted about multiple labels; 有些人注意到多个标签; if they all use the same value for the for attribute, just use querySelectorAll instead of querySelector and loop through to get everything you need. 如果它们都为for属性使用相同的值,只需使用querySelectorAll而不是querySelector并循环获取所需的一切。

Solution One <label> : One <input>解决方案一<label> :一个<input>

Using HTML 5.2 reference Considering the <label> pointing to <input> using for= , the labels element will be a non empty array, and act as a link to the <label> element, accessing all properties of it, including its id= .使用HTML 5.2 参考考虑到<label>使用for=指向<input>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>


Solution Many <label> : One <input>解决方案 许多<label> :一个<input>

With more than one <label> using for= , you can make a loop to show all of them, like this:对于多个使用for= <label> ,您可以制作一个循环来显示所有这些标签,如下所示:

 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>

Answer from Gijs was most valuable for me, but unfortunately the extension does not work. 来自Gijs的回答对我来说最有价值,但不幸的是扩展不起作用。

Here's a rewritten extension that works, it may help someone: 这是一个有效的重写扩展,它可以帮助某人:

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);
    });
};
$("label[for='inputId']").text()

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

It is actually far easier to add an id to the label in the form itself, for example: 实际上,在表单中为标签添加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
/>

Then, you can simply use something like this: 然后,你可以简单地使用这样的东西:

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";
}

The javascript does have to be in a body onload function to work. javascript必须在body onload函数中才能工作。

Just a thought, works beautifully for me. 只是一个想法,对我来说很漂亮。

As it has been already mentionned, the (currently) top-rated answer does not take into account the possibility to embed an input inside a label. 正如已经提到的那样,(当前)最受好评的答案没有考虑在标签内嵌入输入的可能性。

Since nobody has posted a JQuery-free answer, here is mine : 由于没有人发布免费的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-
}

In this example, for the sake of simplicity, the lookup table is directly indexed by the input HTML elements. 在此示例中,为简单起见,查找表由输入HTML元素直接索引。 This is hardly efficient and you can adapt it however you like. 这几乎没有效率,你可以根据自己的喜好进行调整。

You can use a form as base element, or the whole document if you want to get labels for multiple forms at once. 如果要一次获取多个表单的标签,可以使用表单作为基本元素,也可以使用整个文档。

No checks are made for incorrect HTML (multiple or missing inputs inside labels, missing input with corresponding htmlFor id, etc), but feel free to add them. 不对不正确的HTML(标签内多个或缺少输入,缺少相应的htmlFor id的输入等)进行检查,但可以随意添加它们。

You might want to trim the label texts, since trailing spaces are often present when the input is embedded in the label. 您可能希望修剪标签文本,因为当输入嵌入标签时通常会出现尾随空格。

I know this is old, but I had trouble with some solutions and pieced this together. 我知道这已经过时了,但是我遇到了一些解决方案的麻烦并将它拼凑在一起。 I have tested this on Windows (Chrome, Firefox and MSIE) and OS X (Chrome and Safari) and believe this is the simplest solution. 我在Windows(Chrome,Firefox和MSIE)和OS X(Chrome和Safari)上测试了这一点,并相信这是最简单的解决方案。 It works with these three style of attaching a label. 它适用于这三种附加标签的风格。

<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>

Using jQuery: 使用jQuery:

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

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

I have made for my own need, can be useful for somebody: JSFIDDLE 我已经满足了自己的需求,对某些人有用: 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");
            }
        }
    }
});

你尝试过使用document.getElementbyID('id'),其中id是标签的id,或者是你不知道你要找哪一个的情况

I am bit surprised no one is suggesting to use the CSS relationship method? 我有点惊讶没有人建议使用CSS关系方法?

in a style sheet you can reference a label from the element selector: 在样式表中,您可以从元素选择器引用标签:

<style>

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

</style>

if the checkbox has an id of 'XXX' then the label would be found through jQuery by: 如果复选框的id为'XXX',则可以通过jQuery找到标签:

$('#XXX + label');

You can also apply .find('+ label') to return the label from a jQuery checkbox element, ie useful when looping: 您还可以应用.find('+ label')从jQuery复选框元素返回标签,即在循环时有用:

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

All the other answers are extremely outdated!! 所有其他答案都非常过时!!

All you have to do is: 你所要做的就是:

input.labels

HTML5 has been supported by all of the major browsers for many years already. 多年来,HTML5一直受到所有主流浏览器的支持。 There is absolutely no reason that you should have to make this from scratch on your own or polyfill it! 绝对没有理由你必须自己从头开始做这个或者填充它! Literally just use input.labels and it solves all of your problems. 从字面上看,只需使用input.labels解决所有问题。

A really concise solution using ES6 features like destructuring and implicit returns to turn it into a handy one liner would be: 一个非常简洁的解决方案,使用ES6功能,如解构和隐式返回,将其变成一个方便的一个班轮将是:

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

Or to simply get one label, not a NodeList: 或者只是获取一个标签,而不是NodeList:

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

The best answer works perfectly fine but in most cases, it is overkill and inefficient to loop through all the label elements. 最好的答案非常好,但在大多数情况下,循环遍历所有label元素是过度的和低效的。

Here is an efficent function to get the label that goes with the input element: 这是一个有效的函数来获取与input元素一起使用的label

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;
}

For me, this one line of code was sufficient: 对我来说,这一行代码就足够了:

el = document.getElementById(id).previousElementSibling;

In most cases, the label will be very close or next to the input, which means the loop in the above function only needs to iterate a very small number of times. 在大多数情况下, label将非常靠近或靠近输入,这意味着上述函数中的循环只需要迭代很少次。

使用JQuery选择器:

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

For future searchers... The following is a jQuery-ified version of FlySwat's accepted answer: 对于未来的搜索者......以下是FlySwat接受的jQuery-ified版本:

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]));   
        }
    }
}

Using: 使用:

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

If you use the for attribute, you can use querySelector(...) to get如果使用for属性,则可以使用querySelector(...)来获取
the associated label.关联的 label。

HTML/JavaScript HTML/JavaScript

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <label for="myCheckbox">Log Report to Console?</label>
    <input name="myCheckbox" type="checkbox" oninput="doSomething(event)" />

    <script type="text/javascript">
        function doSomething(e) {
            const query = `label[for="${e.target.name}"]`; // This is string interpolation NOT JQuery
            const label = document.querySelector(query);
        }
    </script>
</body>
</html>

Plain JavaScript普通 JavaScript

function doSomething(e) {

    // const query = `label[for="${e.target.name}"]`; // This is string interpolation NOT JQuery
    // Maybe it is safer to use ".getAttribute"
    const query = `label[for="${e.target.getAttribute("name")}"]`;
    const label = document.querySelector(query);

    // Do what you want with the label here...
    debugger; // You're welcome
    console.log(label);
}

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

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