Domanda

Diciamo che ho un modulo html. Ogni input / select / textarea avrà un <label> corrispondente con l'attributo for impostato sull'id del suo compagno. In questo caso, so che ogni input avrà una sola etichetta.

Dato un elemento di input in javascript & # 8212; tramite un evento onkeyup, ad esempio & # 8212; qual è il modo migliore per trovare l'etichetta associata?

È stato utile?

Soluzione

Per prima cosa, scansiona la pagina alla ricerca di etichette e assegna un riferimento all'etichetta dall'elemento modulo effettivo:

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

Quindi, puoi semplicemente andare:

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

Non è necessario un array di ricerca :)

Altri suggerimenti

Se stai usando jQuery puoi fare qualcosa del genere

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

Se non stai usando jQuery dovrai cercare l'etichetta. Ecco una funzione che accetta l'elemento come argomento e restituisce l'etichetta associata

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

Esiste una proprietà labels nella standard HTML5 che punta alle etichette associate a un elemento di input.

Quindi potresti usare qualcosa del genere (supporto per la proprietà <=> nativa ma con un fallback per il recupero delle etichette nel caso in cui il browser non la supporti) ...

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

Ancora più semplice se stai usando 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;
};

Sono un po 'sorpreso che nessuno sembri sapere che sei perfettamente autorizzato a fare:

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

Che non verrà raccolto da nessuna delle risposte suggerite, ma etichetterà l'input correttamente.

Ecco del codice che tiene conto di questo caso:

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

Utilizzo:

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

Alcune note:

  • Il codice è stato scritto per chiarezza, non per prestazioni. Potrebbero essere disponibili alternative più performanti.
  • Questo codice supporta l'ottenimento delle etichette di più elementi in una volta sola. Se non è quello che vuoi, adattati se necessario.
  • Questo non si occupa ancora di cose come aria-labelledby se dovessi usarlo (lasciato come esercizio al lettore).
  • L'uso di più etichette è un'attività complessa quando si tratta di supporto in diversi agenti utente e tecnologie assistive, quindi testare bene e utilizzare a proprio rischio, ecc. ecc.
  • Sì, puoi anche implementarlo senza usare jQuery. : -)

In precedenza ...

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

Più tardi ...

var myLabel = lookup[myInput.id];

Commento Snarky: Sì, puoi farlo anche con JQuery. : -)

con jquery potresti fare qualcosa del genere

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

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

Questo risponde alla domanda nel modo più semplice e snello. Questo utilizza javascript alla vaniglia e funziona su tutti i browser propri del flusso principale.

Se sei disposto a utilizzare querySelector (e puoi, anche fino a IE9 e talvolta IE8!), Un altro metodo diventa praticabile.

Se il tuo campo modulo ha un ID e usi l'attributo for dell'etichetta, questo diventa abbastanza semplice nel moderno 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);
});

Alcuni hanno notato di più etichette; se usano tutti lo stesso valore per l'attributo querySelectorAll, basta usare querySelector invece di <=> e scorrere per ottenere tutto ciò di cui hai bisogno.

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

Questo mi ha aiutato a ottenere l'etichetta di un elemento di input usando il suo ID.

La risposta di Gijs è stata preziosa per me, ma sfortunatamente l'estensione non funziona.

Ecco un'estensione riscritta che funziona, potrebbe aiutare qualcuno:

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

In realtà è molto più semplice aggiungere un ID all'etichetta nel modulo stesso, ad esempio:

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

Quindi, puoi semplicemente usare qualcosa del genere:

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

Il javascript deve essere in una funzione di caricamento del corpo per funzionare.

Solo un pensiero, funziona magnificamente per me.

Come già accennato, la risposta (attualmente) più votata non tiene conto della possibilità di incorporare un input all'interno di un'etichetta.

Poiché nessuno ha pubblicato una risposta senza JQuery, ecco la mia:

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 questo esempio, per semplicità, la tabella di ricerca viene indicizzata direttamente dagli elementi HTML di input. Questo è poco efficiente e puoi adattarlo come preferisci.

È possibile utilizzare un modulo come elemento di base o l'intero documento se si desidera ottenere etichette per più moduli contemporaneamente.

Non viene effettuato alcun controllo per HTML errato (input multipli o mancanti all'interno delle etichette, input mancante con html corrispondente per ID, ecc.), ma sentitevi liberi di aggiungerli.

Potresti voler tagliare i testi delle etichette, poiché gli spazi finali sono spesso presenti quando l'input è incorporato nell'etichetta.

hai provato a usare document.getElementbyID ('id') dove id è l'id dell'etichetta o la situazione che non conosci quale stai cercando

Usa un selettore JQuery:

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

Per i futuri ricercatori ... Quella che segue è una versione jQuery della risposta accettata da 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]));   
        }
    }
}

Utilizzo:

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

So che è vecchio, ma ho avuto problemi con alcune soluzioni e l'ho messo insieme. Ho provato questo su Windows (Chrome, Firefox e MSIE) e OS X (Chrome e Safari) e credo che questa sia la soluzione più semplice. Funziona con questi tre stili di attaccamento di un'etichetta.

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

Uso di jQuery:

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

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

Ho fatto per le mie necessità, può essere utile per qualcuno: 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");
            }
        }
    }
});

Sono un po 'sorpreso che nessuno stia suggerendo di usare il metodo di relazione CSS?

in un foglio di stile puoi fare riferimento a un'etichetta dal selettore di elementi:

<style>

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

</style>

se la casella di controllo ha un ID "XXX" quindi l'etichetta verrà trovata tramite jQuery da:

$('#XXX + label');

Puoi anche applicare .find ('+ etichetta') per restituire l'etichetta da un elemento della casella di controllo jQuery, vale a dire utile quando esegui il ciclo:

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

Tutte le altre risposte sono estremamente obsolete !!

Tutto quello che devi fare è:

input.labels

HTML5 è supportato da tutti i principali browser già da molti anni. Non c'è assolutamente alcun motivo per cui dovresti farlo da solo o riempirlo da solo! Utilizza letteralmente input.labels e risolve tutti i tuoi problemi.

La risposta migliore funziona perfettamente, ma nella maggior parte dei casi è eccessivo e inefficiente scorrere tutti gli label elementi.

Ecco una funzione efficace per ottenere input che si accompagna all'elemento <=>:

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

Per me, questa riga di codice era sufficiente:

el = document.getElementById(id).previousElementSibling;

Nella maggior parte dei casi, <=> sarà molto vicino o vicino all'input, il che significa che il loop nella funzione sopra deve solo iterare un numero molto piccolo di volte.

Una soluzione davvero concisa che utilizza funzionalità ES6 come la destrutturazione e i rendimenti impliciti per trasformarla in una pratica fodera sarebbe:

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

O semplicemente per ottenere un'etichetta, non un NodeList:

const getFirstLabel = ({ labels, id }) => labels && labels[0] || document.querySelector(`label[for=${id}]`)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top