Найти метку html, связанную с данным вводом - PullRequest
94 голосов
/ 13 ноября 2008

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

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

Ответы [ 21 ]

97 голосов
/ 13 ноября 2008

Если вы используете 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];
   }
}
75 голосов
/ 13 ноября 2008

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

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

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

23 голосов
/ 25 февраля 2013

В стандарте 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;
};
21 голосов
/ 18 января 2012

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

<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. : -)
14 голосов
/ 13 ноября 2008

Раньше ...

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

8 голосов
/ 13 ноября 2008

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

var nameOfLabel = someInput.attr('id');
var label = $("label[for='" + nameOfLabel + "']");
6 голосов
/ 20 июля 2017

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

Это отвечает на вопрос самым простым и скромным образом. Он использует ванильный JavaScript и работает во всех основных браузерах основного потока.

4 голосов
/ 11 августа 2015

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

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

2 голосов
/ 05 сентября 2011
$("label[for='inputId']").text()

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

2 голосов
/ 24 октября 2012

Ответ от 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);
    });
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...