指定された入力に関連付けられたHTMLラベルを検索します


110

HTMLフォームがあるとします。各input / select / textareaには、対応<label>するfor属性があり、そのコンパニオンのIDに設定されています。この場合、各入力にはラベルが1つしかないことを知っています。

たとえば、onkeyupイベントを介して、JavaScriptの入力要素が与えられた場合、関連付けられたラベルを見つけるための最良の方法は何ですか?


5
要素には複数のラベルがある場合があることに注意してください。要素ごとに複数のラベルを持ついくつかのアプリケーション(SAP for one)を見てきました。
モッティ

2
function getInputLabel(thisElement) { var theAssociatedLabel,elementID; elementID = thisElement.id; theAssociatedLabel = thisElement.parentNode.querySelector("label[for='" + elementID + "']"); console.log('theAssociatedLabel.htmlFor: ' + theAssociatedLabel.htmlFor); theAssociatedLabel.style.backgroundColor = "green";//Set the label background color to green };
アランウェルズ

または単にnode.parentNode.querySelector( "label [for = '" + node.id + "']")。innerHTML; 笑
ソロモンPバイヤー

回答:


87

まず、ページのラベルをスキャンし、実際のフォーム要素からラベルへの参照を割り当てます。

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

ルックアップ配列は必要ありません:)


あなたのexpandoプロパティの使用が私のものとどこが違うか説明できますか?「ルックアップ配列」は使用せず、プロパティを持つオブジェクトを使用します。「element.label」、「element ['label']」、「lookup ['elementId']」の間の構文上の違いのみがあります。舞台裏は同じものです。
Tomalak 2008年

4
これは、別のオブジェクトを保持する必要がないため、より優れています。関係は、入力要素に直接格納されます。
Joel Coehoorn、2008年

3
これはブラウザで処理する必要があります
andho

103

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

33

あるlabels内性HTML5標準入力要素に関連付けられたラベルを指します。

したがって、次のようなものを使用できます(ネイティブ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;
};


1
これは大丈夫です。ありがとう!
maxhm10

23

あなたが完全に許可されていることを誰も知らないようであることに私は少し驚いています:

<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を使用せずにこれを実装することもできます。:-)

6
常に要素にfor属性があると仮定するのではなく、誰かが暗黙的なラベルの関連付けを提示するのを見るのは素晴らしいことlabelです。
Josh Habdas 2014年

14

ついさっき...

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

ぎこちないコメント:はい、JQueryでも実行できます。:-)


1
いいね。これを少しリファクタリングして、メソッドを初めて呼び出したときにルックアップを構築しますが、これでうまくいくはずです。
Joel Coehoorn、2008年

ルックアップは1度だけ作成することを示唆しました。
Tomalak 2008年

小さなエラーがあったことに注意してください。「for」ではなく「htmlFor」プロパティを使用してください。後者はJSの予約語であるためです。ラベルオブジェクトを使用するときは忘れがちです... :-)
Tomalak '12

上記のルックアップ配列なしでこれを行う方法があります。
FlySwat 2008年

initコードをメソッド内に移動することを意味しました
。1

13

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

これは、最も単純で無駄のない方法で質問に答えます。これはバニラJavaScriptを使用し、すべてのメインストリームの適切なブラウザで動作します。


これは質問に対する答えを提供しません。十分な評判得られたら、どの投稿にもコメントできます。代わりに、質問者からの説明を必要としない回答を提供してください。- レビューから
loki 2017

1
これは、質問@lokiへの回答を最も確実に提供します。それ以上の説明がないからといって、それが間違っている、または回答を試みなかったという意味ではありません。
geisterfurz007

最も簡単で便利な答え!ありがとう!
iedmrc


4

querySelectorを使用するつもりである場合(さらにはIE9まで、場合によってはIE8までも使用できます)、別の方法が実行可能になります。

フォームフィールドに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);
});

複数のラベルについて言及している人もいます。それらすべてがfor属性に同じ値を使用する場合は、querySelectorAll代わりにquerySelectorを使用してループし、必要なすべてを取得します。


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

これは、IDを使用して入力要素のラベルを取得するのに役立ちました。


2

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

2

他のすべての答えは非常に古いです!!

あなたがしなければならないすべては:

input.labels

HTML5は、長年にわたってすべての主要なブラウザーでサポートされています。これを最初から作成するか、ポリフィルする必要がある理由はまったくありません!文字通り使用するだけinput.labelsで、すべての問題が解決します。


1
このページによると、input.labelsはIEまたはEdgeではサポートされておらず、Firefoxはサポートを追加しただけです。
Antti29、2018

Antti29 @あなたはシムを使用して機能を追加することができます:github.com/termi/ES5-DOM-SHIMは:あなたはここに追加された機能を確認できgithub.com/termi/ES5-DOM-SHIM/blob/...
ADJenks

2

構造化や暗黙的なリターンなどのES6機能を使用して、それを便利なワンライナーに変える、本当に簡潔なソリューションは次のとおりです。

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

または、NodeListではなく単に1つのラベルを取得するには:

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

1

実際には、フォーム自体のラベルに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関数に含まれている必要があります。

ただ考えれば、私にとっては美しく機能します。


1

すでに言及されているように、(現在)最高評価の回答では、入力をラベル内に埋め込む可能性は考慮されていません。

誰も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 idがないなど)のチェックは行われませんが、自由に追加してください。

入力がラベルに埋め込まれている場合、末尾のスペースがしばしば存在するため、ラベルテキストをトリミングすることができます。


1

最良の答えは完璧に機能しますが、ほとんどの場合、すべてのlabel要素をループするのはやり過ぎで非効率的です。

要素に対応するを取得するための効率的な関数を次にlabel示し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;
}

私にとっては、次の1行のコードで十分です。

el = document.getElementById(id).previousElementSibling;

ほとんどの場合、はlabel入力に非常に近いか隣にあります。つまり、上記の関数のループは非常に少ない回数だけ繰り返す必要があります。


0

document.getElementbyID( 'id')を使用してみましたか。idはラベルのIDであるか、または探しているものがわからない状況です。


入力要素のIDは知っていますが、ラベルのIDは知りません。
Joel Coehoorn、2008年

input id = 'test'やlabel id = 'lbl_test "など、ラベルに対応するIDを設定できないのですか
Josh Mein


0

将来の検索者向け...以下は、FlySwatの承認済み回答のjQuery化バージョンです。

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

+1ですが、最初のブロックにjQueryバージョンを使用する理由はないということがわかります。これは、短くも読みやすくもないため、プレーンなJavaScriptの方がパフォーマンスがよくなるでしょう。ただし、作成後のjQueryの使用方法については、jQueryの例があると便利です。
Joel Coehoorn、2011

私たちの多くにとって明らかなように、このアプローチには技術的な理由はそれほど多くはなく、少なくとも私の場合はHRが理由です。デザイナー、インテグレーター、さらにはjQueryの使用に慣れ親しんでいるJr開発者を含むチームがあるとします。jQueryパラダイムを維持することで、生産性を維持し、フラストレーションを減らすことができます。
ObjectType 2011

これはjQuery化されたものではありません。なぜforループオーバーeach()?なぜhtmlFor代わりにattr("for")
アレックス

見方次第ではないでしょうか。消費は内部ではなく、jQuery化されました。
ObjectType

0

これは古いことはわかっていますが、いくつかの解決策に問題があり、これをつなぎ合わせました。私はこれをWindows(Chrome、FirefoxおよびMSIE)およびOS X(ChromeおよびSafari)でテストしましたが、これが最も簡単なソリューションであると信じています。ラベルを付けるこれらの3つのスタイルで動作します。

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

私のJSFiddle:http ://jsfiddle.net/pnosko/6PQCw/


これは実際には機能していません-親要素のテキストを返すだけで、たまに必要なテキストになることがあります。
John Hascall 16

0

私は自分自身の必要性のために作りました、誰かのために役立つことができます: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");
            }
        }
    }
});

0

CSSリレーションシップメソッドの使用を提案している人がいないことに少し驚いていますか?

スタイルシートでは、要素セレクターからラベルを参照できます。

<style>

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

</style>

チェックボックスのIDが「XXX」の場合、ラベルはjQueryを介して次のように見つかります。

$('#XXX + label');

.find( '+ label')を適用してjQueryチェックボックス要素からラベルを返すこともできます。つまり、ループするときに役立ちます。

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

おっと、これは要素の直後にあるラベルに依存していることに注意してください。
ゴードンラウズ2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.