سؤال

لنفترض أن لدي نموذج HTML.سيكون لكل إدخال/تحديد/منطقة نصية ما يقابلها <label> مع ال for تم تعيين السمة على معرف رفيقها.في هذه الحالة، أعلم أن كل إدخال سيكون له تسمية واحدة فقط.

بالنظر إلى عنصر إدخال في جافا سكريبت - عبر حدث onkeyup، على سبيل المثال - ما هي أفضل طريقة للعثور على التسمية المرتبطة به؟

هل كانت مفيدة؟

المحلول

أولا، مسح الصفحة للتسميات، وتعيين إشارة إلى التسمية من عنصر النموذج الفعلي:

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

لا حاجة لمجموعة البحث:)

نصائح أخرى

إذا كنت تستخدم مسج يمكنك أن تفعل شيئا من هذا القبيل

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

إذا كنت لا تستخدم مسج سيكون لديك للبحث عن التسمية. هنا هي وظيفة التي تأخذ عنصر كحجة وإرجاع التسمية المرتبطة

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

وهناك خاصية 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;
};

وحتى أسهل إذا كنت تستخدم مسج ...

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

أنا مندهش بعض الشيء لأنه يبدو أن لا أحد يعرف أنك كذلك مسموح به تمامًا لكى يفعل:

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

وفي وقت سابق ...

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

وتعليق المتعرج: نعم، يمكنك أيضا أن تفعل ذلك مع مسج. : -)

ومع مسج هل يمكن أن تفعل شيئا من هذا القبيل

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

وdocument.querySelector ( "تسمية [ل=" + vHtmlInputElement.id + "]")؛

وهذا يجيب على السؤال بطريقة أبسط والأصغر حجما. هذا يستخدم الفانيليا جافا سكريبت ويعمل على جميع المتصفحات الرئيسية تيار المناسبة.

إذا كنت على استعداد لاستخدام querySelector (ووتستطيع، بل وحتى IE9 وأحيانا IE8!)، يصبح طريقة أخرى قابلة للحياة.

إذا حقل النموذج الخاص بك لديه ID، وكنت تستخدم السمة for التسمية، ويصبح هذا بسيط جدا في جافا سكريبت الحديث:

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 وحلقة من خلال الحصول على كل ما تحتاجه.

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

وهذا ما ساعدني للحصول على تسمية عنصر الإدخال باستخدام المعرف الخاص به.

وكان الإجابة من جيس الأكثر قيمة بالنسبة لي، ولكن للأسف تمديد لا تعمل.

وفيما يلي تمديد إعادة كتابة يعمل، فإنه قد تساعد أحدهم:

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

وهو في الواقع أسهل بكثير لإضافة معرف إلى التسمية في النموذج نفسه، على سبيل المثال:

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

وجافا سكريبت لا يجب أن تكون في وظائف الجسم ONLOAD للعمل.

ومجرد التفكير، ويعمل بشكل جميل بالنسبة لي.

وكما تم مينتيونيد بالفعل، و(حاليا) أعلى تصنيف الجواب لا يأخذ بعين الاعتبار إمكانية تضمين مدخلا داخل التسمية.

ومنذ لا أحد قد نشر إجابة مسج خالية، وهنا الألغام:

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 الهوية، وما إلى ذلك)، ولكن لا تتردد في إضافتها.

وقد تحتاج إلى تقليم النصوص التسمية، منذ مسافات زائدة غالبا ما تكون موجودة عند جزءا لا يتجزأ من المدخلات في التسمية.

هل حاولت استخدام document.getElementbyID ( 'الهوية') حيث هو معرف هوية التسمية أو هو الوضع الذي كنت لا تعرف أي واحد كنت تبحث عن

استخدم محدد مسج:

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

لباحثين في المستقبل ... وفيما يلي نسخة مسج-ified الإجابة 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]));   
        }
    }
}

وعن طريق:

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

وأعرف أن هذا هو القديم، ولكن واجهت مشكلة مع بعض الحلول وتجميعها هذا معا. لقد جربت هذا على ويندوز (كروم، فايرفوكس وMSIE) وOS X (كروم وسفاري) ونعتقد أن هذا هو أبسط الحلول. وهي تعمل مع هذه النمط من ثلاثة إرفاق التسمية.

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

وعن طريق مسج:

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

وبلدي JSFiddle: http://jsfiddle.net/pnosko/6PQCw/

ولقد جعلت لحاجتي الخاصة، يمكن أن تكون مفيدة لشخص ما: 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");
            }
        }
    }
});

وأنا مندهش قليلا لا أحد يقترح استخدام الأسلوب العلاقة CSS؟

في ورقة أنماط يمكنك الرجوع تسمية من محدد العنصر:

<style>

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

</style>

وإذا كان مربع يحتوي على معرف 'XXX' ثم التسمية من شأنه أن يمكن العثور عليها من خلال مسج بواسطة:

$('#XXX + label');

ويمكنك أيضا تطبيق .find ( '+ التسمية') لإرجاع التسمية من عنصر مربع مسج، أي فائدة عندما حلقات:

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

جميع الإجابات الأخرى هي لأقصى حد عفا عليها الزمن!!

كل ما عليك القيام به هو:

input.labels

لقد تم دعم HTML5 بواسطة جميع المتصفحات الرئيسية لسنوات عديدة بالفعل.لا يوجد أي سبب على الإطلاق يدفعك إلى القيام بذلك من الصفر بنفسك أو ملئه بالبوليستر!حرفيا مجرد استخدام input.labels ويحل جميع مشاكلك.

وأفضل إجابة يعمل بشكل جيد تماما ولكن في معظم الحالات، هو مبالغة وغير فعالة لتنفيذ حلقات عبر كافة العناصر 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 تكون قريبة جدا أو بجانب المدخلات، وهو ما يعني حلقة في الدالة أعلاه يحتاج فقط لتكرار عدد قليل جدا من المرات.

وحل موجزة حقا باستخدام ES6 يتميز مثل الإتلاف والضمنية يعود إلى تحويلها إلى سهل البطانة واحد سيكون:

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

وأو لمجرد الحصول على تسمية واحدة، وليس NodeList:

const getFirstLabel = ({ labels, id }) => labels && labels[0] || document.querySelector(`label[for=${id}]`)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top