주어진 입력과 관련된 html 레이블 찾기


110

html 양식이 있다고 가정 해 봅시다. 각 입력 / 선택 / 텍스트 영역은 해당해야합니다 <label>for그것의 동반자의 id에 속성 세트를. 이 경우 각 입력에는 하나의 레이블 만 있음을 알고 있습니다.

예를 들어 onkeyup 이벤트를 통해 자바 스크립트의 입력 요소가 주어지면 관련 레이블을 찾는 가장 좋은 방법은 무엇입니까?


5
요소에 레이블이 둘 이상있을 수 있습니다. 요소 당 여러 레이블이있는 일부 응용 프로그램 (1 개의 SAP)을 보았습니다.
Motti

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

또는 그냥 node.parentNode.querySelector ( "label [for = '"+ node.id + "']"). innerHTML; lol
Solomon P Byer

답변:


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

4
관계가 입력 요소와 함께 직접 저장되므로 별도의 개체를 유지할 필요가 없기 때문에 더 좋습니다.
Joel Coehoorn

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

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

4
Chrome뿐만 아니라 HTML5 표준 입니다.
Bergi

1
이것은 waaaay 일 것입니다. 감사!
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];

Snarky comment : 예, JQuery로도 할 수 있습니다. :-)


1
좋은. 메서드를 처음 호출 할 때 조회를 작성하도록 조금만 리팩터링하지만 트릭을 수행해야합니다.
Joel Coehoorn

나는 당신이 조회를 한 번만 만들 것이라고 암시했습니다.
Tomalak

작은 오류가 있음을 유의하십시오. 후자는 JS에서 예약어이므로 "for"가 아닌 "htmlFor"속성을 사용하십시오. 나는 라벨 객체를 사용할 때 잊어 버리는 경향이 있습니다 ... :-)
Tomalak

위의 조회 배열없이이 작업을 수행 할 수있는 방법이 있습니다.
FlySwat

한 번만 수행하는 것이 아니라 메서드 내부에서 init 코드를 이동하는 것을 의미했습니다. (
Joel Coehoorn

13

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

이것은 가장 간단하고 간결한 방식으로 질문에 답합니다. 이것은 바닐라 자바 ​​스크립트를 사용하고 모든 메인 스트림 적절한 브라우저에서 작동합니다.


이것은 질문에 대한 답을 제공하지 않습니다. 평판 이 충분 하면 모든 게시물댓글 수 있습니다 . 대신 질문자의 설명이 필요하지 않은 답변을 제공하세요 . - 검토에서
로키

1
이것은 @loki 질문에 대한 답을 가장 확실하게 제공합니다. 더 이상의 설명이 없기 때문에 그것이 잘못되었거나 대답을 시도하지 않았 음을 의미하지는 않습니다.
geisterfurz007

가장 간단하고 유용한 답변! 감사!
iedmrc

8

jquery를 사용하면 다음과 같이 할 수 있습니다.

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

조상이지만 레이블을 놓칠 수 있습니다.
alex

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하고 필요한 모든 항목을 반복합니다.


3

다른 모든 답변은 매우 구식입니다 !!

당신이해야 할 일은 :

input.labels

HTML5는 이미 수년 동안 모든 주요 브라우저에서 지원되었습니다. 처음부터 직접 만들거나 폴리 필해야 할 이유가 전혀 없습니다! 말 그대로 사용 input.labels하면 모든 문제가 해결됩니다.


1
에 따르면 이 페이지 , input.labelsIE 또는 Edge 및 파이어 폭스에서 지원되지는 단지 지원을 추가했습니다.
Antti29

Antti29 @ 당신은 심 (shim)을 사용하여 기능을 추가 할 수 있습니다 github.com/termi/ES5-DOM-SHIM는 당신은 기능을 볼 수 있습니다 여기에 추가되는 : github.com/termi/ES5-DOM-SHIM/blob/...
ADJenks

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

구조화 및 암시 적 반환과 같은 ES6 기능을 사용하여 편리한 단일 라이너로 전환하는 정말 간결한 솔루션은 다음과 같습니다.

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

또는 단순히 NodeList가 아닌 하나의 레이블을 얻으려면 :

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

자바 스크립트가 작동하려면 body 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;
}

저에게는이 한 줄의 코드로 충분했습니다.

el = document.getElementById(id).previousElementSibling;

대부분의 경우 label는 입력에 매우 가깝거나 옆에 있습니다. 즉, 위 함수의 루프는 아주 적은 횟수 만 반복하면됩니다.


0

document.getElementbyID ( 'id')를 사용해 보셨습니까? 여기서 id는 레이블의 ID이거나 어떤 것을 찾고 있는지 모르는 상황입니다.


입력 요소의 ID는 알고 있지만 레이블의 ID는 알고 있지 않습니다.
Joel Coehoorn

입력 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 버전을 사용할 이유가 없습니다. 더 짧거나 더 읽기 쉽고 일반 자바 스크립트가 더 잘 수행 될 것입니다. 하지만 생성 된 후에 사용하는 방법에 대한 jQuery 예제가 있으면 좋습니다.
Joel Coehoorn

분명히 우리 중 많은 사람들에게는이 접근 방식에 대한 기술적 이유가 많지 않지만 적어도 제 경우에는 HR 이유가 있습니다. 디자이너, 통합 자, 심지어 속도를 늦추는 주니어 개발자가 포함 된 팀이 jQuery 사용에 익숙하다고 상상해보십시오. jQuery 패러다임을 유지하면 생산성을 높이고 좌절감을 줄일 수 있습니다.
ObjectType

이것은 jQuery-ified 가 아닙니다 . 왜 for루프가 끝났 each()습니까? htmlFor대신 왜 attr("for")?
알렉스

관점에 따라 다릅니다. 소비는 내부가 아니라 jQuery로 처리되었습니다.
ObjectType

0

나는 이것이 오래되었다는 것을 알고 있지만 몇 가지 해결책에 문제가 있었고 이것을 함께 모았습니다. 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() );
});

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


이것은 실제로 작동하지 않습니다. 부모 요소의 텍스트를 반환하는 것뿐입니다. 때로는 원하는 텍스트가됩니다.
존 Hascall

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

죄송합니다. 이것은 요소 바로 뒤에 오는 레이블에 의존합니다.
Gordon Rouse
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.