Disons que j'ai un formulaire HTML. Chaque entrée/sélection/zone de texte aura un <label>
correspondant avec l'attribut for
défini sur l'id de son compagnon. Dans ce cas, je sais que chaque entrée n’aura qu’une seule étiquette.
Étant donné un élément d'entrée en javascript - via un événement onkeyup, par exemple - quel est le meilleur moyen de trouver son étiquette associée?
Commencez par rechercher des étiquettes dans la page et attribuez une référence à l'étiquette à partir de l'élément de formulaire actuel:
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];
}
}
Ensuite, vous pouvez simplement aller:
document.getElementById('MyFormElem').label.innerHTML = 'Look ma this works!';
Pas besoin d'un tableau de recherche :)
Si vous utilisez jQuery, vous pouvez faire quelque chose comme ceci
$('label[for="foo"]').hide ();
Si vous n'utilisez pas jQuery, vous devrez rechercher l'étiquette. Voici une fonction qui prend l'élément en argument et retourne l'étiquette associée
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];
}
}
Il existe une propriété labels
dans norme HTML5 qui pointe vers des étiquettes associées à un élément d'entrée.
Vous pouvez donc utiliser quelque chose comme ceci (support de la propriété native labels
mais avec un repli pour récupérer les étiquettes si le navigateur ne la prend pas en charge) ...
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;
};
Encore plus facile si vous utilisez 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;
};
Je suis un peu surpris que personne ne semble savoir que vous êtes parfaitement autorisé à faire:
<label>Put your stuff here: <input value="Stuff"></label>
Ce qui ne sera retenu par aucune des réponses suggérées, mais will identifiera correctement l’entrée.
Voici un code qui prend ce cas en compte:
$.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();
Quelques notes:
aria-labelledby
si vous deviez utiliser cela (laissé comme exercice au lecteur).Plus tôt...
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;
}
}
Plus tard...
var myLabel = lookup[myInput.id];
Commentaire Snarky: Oui, vous pouvez aussi le faire avec JQuery. :-)
avec jQuery vous pourriez faire quelque chose comme
var nameOfLabel = someInput.attr('id');
var label = $("label[for='" + nameOfLabel + "']");
document.querySelector ("label [for =" + vHtmlInputElement.id + "]");
Cela répond à la question de la manière la plus simple et la plus simple ... Cela utilise le javascript Vanilla et fonctionne sur tous les navigateurs appropriés du flux principal.
Si vous êtes prêt à utiliser querySelector (et vous pouvez, même jusqu'à IE9 et parfois IE8!), Une autre méthode devient viable.
Si votre champ de formulaire a un ID et que vous utilisez l'attribut for
du libellé, cela devient assez simple dans JavaScript moderne:
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);
});
Certains ont noté plusieurs étiquettes. s'ils utilisent tous la même valeur pour l'attribut for
, utilisez simplement querySelectorAll
au lieu de querySelector
et effectuez une boucle pour obtenir tout ce dont vous avez besoin.
$("label[for='inputId']").text()
Cela m'a aidé à obtenir l'étiquette d'un élément d'entrée en utilisant son ID.
La réponse de Gijs a été très précieuse pour moi, mais malheureusement l'extension ne fonctionne pas.
Voici une extension réécrite qui fonctionne, elle peut aider quelqu'un:
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);
});
};
Il est en fait beaucoup plus facile d'ajouter un identifiant à l'étiquette dans le formulaire lui-même, par exemple
<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
/>
Ensuite, vous pouvez simplement utiliser quelque chose comme ceci:
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";
}
Le javascript doit être dans une fonction body onload pour fonctionner.
Juste une pensée, fonctionne à merveille pour moi.
Comme il a déjà été mentionné, la réponse (actuellement) la mieux notée ne tient pas compte de la possibilité d’incorporer une entrée dans une étiquette.
Puisque personne n'a posté de réponse sans JQuery, voici le mien:
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-
}
Dans cet exemple, dans un souci de simplicité, la table de recherche est directement indexée par les éléments HTML en entrée. Ceci n’est guère efficace et vous pouvez l’adapter à votre guise.
Vous pouvez utiliser un formulaire comme élément de base ou le document entier si vous souhaitez obtenir des étiquettes pour plusieurs formulaires à la fois.
Aucune vérification n'est effectuée pour le code HTML incorrect (entrées multiples ou manquantes dans les étiquettes, entrée manquante avec l'identifiant htmlFor correspondant, etc.), mais vous pouvez les ajouter.
Vous voudrez peut-être rogner les textes des étiquettes, car les espaces de fin sont souvent présents lorsque l'entrée est incorporée dans l'étiquette.
Utilisez un sélecteur JQuery:
$("label[for="+inputElement.id+"]")
avez-vous essayé d'utiliser document.getElementbyID ('id') où id est l'identifiant du libellé ou la situation dans laquelle vous ne savez pas lequel vous recherchez
Je sais que c'est vieux, mais j'ai eu du mal à trouver des solutions et je l'ai reconstitué. J'ai testé cela sur Windows (Chrome, Firefox et MSIE) et OS X (Chrome et Safari) et je pense que c'est la solution la plus simple. Cela fonctionne avec ces trois styles de fixation d'une étiquette.
<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>
Utilisation de jQuery:
$(".c123").click(function() {
$cb = $(this);
$lb = $(this).parent();
alert( $cb.attr('id') + ' = ' + $lb.text() );
});
Mon JSFiddle: http://jsfiddle.net/pnosko/6PQCw/
La meilleure solution fonctionne parfaitement, mais dans la plupart des cas, il est excessif et inefficace de parcourir tous les éléments label
.
Voici une fonction efficace pour obtenir la variable label
associée à l'élément 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;
}
Pour moi, cette ligne de code était suffisante:
el = document.getElementById(id).previousElementSibling;
Dans la plupart des cas, la variable label
sera très proche ou proche de l'entrée, ce qui signifie que la boucle dans la fonction ci-dessus n'a à itérer qu'un très petit nombre de fois.
Toutes les autres réponses sont extrêmement obsolètes !!
Tout ce que tu dois faire est:
input.labels
HTML5 est supporté par tous les principaux navigateurs depuis de nombreuses années déjà. Il n'y a absolument aucune raison pour que vous deviez le fabriquer vous-même ou le polyfiller! Littéralement, utilisez simplement input.labels
et cela résoudra tous vos problèmes.
J'ai fait pour mon propre besoin, peut être utile pour quelqu'un: 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");
}
}
}
});
Je suis un peu surpris que personne ne suggère d'utiliser la méthode de relation CSS?
dans une feuille de style, vous pouvez référencer une étiquette à partir du sélecteur d'élément:
<style>
//for input element with class 'YYY'
input.YYY + label {}
</style>
si la case à cocher a un identifiant de 'XXX' alors l'étiquette sera trouvée par jQuery par:
$('#XXX + label');
Vous pouvez également appliquer .find ('+ label') pour renvoyer l’étiquette à partir d’un élément de case à cocher jQuery, c’est-à-dire utile lors de la mise en boucle:
$('input[type=checkbox]').each( function(){
$(this).find('+ label');
});
Une solution très concise utilisant des fonctionnalités ES6 telles que la déstructuration et les retours implicites pour en faire un support pratique serait:
const getLabels = ({ labels, id }) => labels || document.querySelectorAll(`label[for=${id}]`)
Ou simplement obtenir un label, pas un NodeList:
const getFirstLabel = ({ labels, id }) => labels && labels[0] || document.querySelector(`label[for=${id}]`)
Pour les futurs chercheurs ... Voici une version jQuery de la réponse acceptée par 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]));
}
}
}
En utilisant:
$("#myFormElemId").data("label").css("border","3px solid red");