Найти html-метку, связанную с данным вводом

Скажем, у меня есть html-форма. Каждый элемент input/select/textarea будет иметь соответствующий <label> с атрибутом for, установленным на идентификатор этого компаньона. В этом случае я знаю, что каждый вход будет иметь только одну метку.

Учитывая входной элемент в javascript — через событие onkeyup, например — что лучший способ найти его связанную метку?

Ответ 1

Сначала сканируйте страницу для меток и назначьте ссылку на метку из фактического элемента формы:

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

Нет необходимости в массиве поиска:)

Ответ 2

Если вы используете 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];
   }
}

Ответ 3

Я немного удивлен, что никто, кажется, не знает, что вы отлично разрешили делать:

<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.: -)

Ответ 4

В стандарте 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;

};

Ответ 5

Ранее...

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

Комментарий Snarky: Да, вы также можете сделать это с помощью JQuery.: -)

Ответ 6

с jquery вы можете сделать что-то вроде

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

Ответ 7

$("label[for='inputId']").text()

Это помогло мне получить метку элемента ввода, используя его идентификатор.

Ответ 8

Ответ от 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);
    });
};

Ответ 9

Если вы готовы использовать querySelector (и вы можете, даже до IE9, а иногда и IE8!), другой метод становится жизнеспособными.

Если ваше поле формы имеет идентификатор, и вы используете атрибут label 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 и прокрутите, чтобы получить все, что вам нужно.

Ответ 10

Вы пытались использовать document.getElementbyID('id'), где id - это идентификатор метки, или это ситуация, о которой вы не знаете, какой из них вы ищете

Ответ 11

На самом деле гораздо проще добавить 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 действительно должен находиться в функции onload для работы.

Просто мысль, прекрасно работает для меня.

Ответ 12

Как уже упоминалось, (в настоящее время) рейтинг-рейтинг не учитывает возможность встраивания ввода внутри метки.

Поскольку никто не отправил 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 и т.д.), но не стесняйтесь их добавлять.

Возможно, вы захотите обрезать тексты меток, так как в этом случае элементы ввода всегда помещаются в трейлинг-пространства.

Ответ 13

Используйте селектор JQuery:

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

Ответ 14

Для будущих поисковиков... Ниже приведена jQuery-ified версия принятого ответа FlySwat:

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

Ответ 15

Я знаю, что это старо, но у меня возникли проблемы с некоторыми решениями и собрал это вместе. Я тестировал это на 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() );
});

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

Ответ 16

Я сделал для себя, может быть полезен для кого-то: 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");
            }
        }
    }
});

Ответ 17

Я немного удивлен, что никто не предлагает использовать метод отношений CSS?

в таблице стилей вы можете ссылаться на метку из селектора элементов:

<style>

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

</style>

если флажок имеет идентификатор 'XXX' то метка будет найдена через jQuery:

$('#XXX + label');

Вы также можете применить .find('+ label'), чтобы вернуть метку из элемента флажка jQuery, т.е. полезно при циклировании:

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

Ответ 18

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

Ответ 19

Все остальные ответы чрезвычайно устарели!!

Все, что вам нужно сделать, это:

input.labels

HTML5 поддерживался всеми основными браузерами уже много лет. Нет абсолютно никакой причины, по которой вам придется делать это с нуля самостоятельно или polyfill! Буквально используйте input.labels, и он решает все ваши проблемы.