Как я могу использовать атрибут FOR тега LABEL без атрибута ID в теге INPUT

Есть ли решение проблемы, показанной в приведенном ниже коде? Начните с открытия кода в браузере, чтобы сразу перейти к делу и не просматривать весь этот код, прежде чем понять, что вы ищете.

<html>
 <head>
  <title>Input ID creates problems</title>
  <style type="text/css">
   #prologue, #summary { margin: 5em; }
  </style>
 </head>
 <body>
  <h1>Input ID creates a bug</h1>
  <p id="prologue">
   In this example, I make a list of checkboxes representing things which could appear in a book. If you want some in your book, you check them:
  </p>
  <form>
   <ul>
    <li>
     <input type="checkbox" id="prologue" />
     <label for="prologue">prologue</label>
    </li>
    <li>
     <input type="checkbox" id="chapter" />
     <label for="chapter">chapter</label>
    </li>
    <li>
     <input type="checkbox" id="summary" />
     <label for="summary">summary</label>
    </li>
    <li>
     <input type="checkbox" id="etc" />
     <label for="etc">etc</label>
     <label>
    </li>
   </ul>
  </form>
  <p id="summary">
   For each checkbox, I want to assign an ID so that clicking a label checks the corresponding checkbox. The problems occur when other elements in the page already use those IDs. In this case, a CSS declaration was made to add margins to the two paragraphs which IDs are "prologue" and "summary", but because of the IDs given to the checkboxes, the checkboxes named "prologue" and "summary" are also affected by this declaration. The following links simply call a javascript function which writes out the element whose id is <a href="javascript:alert(document.getElementById('prologue'));">prologue</a> and <a href="javascript:alert(document.getElementById('summary'));">summary</a>, respectively. In the first case (prologue), the script writes out [object HTMLParagraphElement], because the first element found with id "prologue" is a paragraph. But in the second case (summary), the script writes out [object HTMLInputElement] because the first element found with id "summary" is an input. In the case of another script, the consequences of this mix up could have been much more dramatic. Now try clicking on the label prologue in the list above. It does not check the checkbox as clicking on any other label. This is because it finds the paragraph whose ID is also "prologue" and tries to check that instead. By the way, if there were another checkbox whose id was "prologue", then clicking on the label would check the one which appears first in the code.
  </p>
  <p>
   An easy fix for this would be to chose other IDs for the checkboxes, but this doesn't apply if these IDs are given dynamically, by a php script for example.
   Another easy fix for this would be to write labels like this:
   <pre>
    &lt;label&gt;&lt;input type="checkbox" /&gt;prologue&lt;/label&gt;
   </pre>
   and not need to give an ID to the checkboxes. But this only works if the label and checkbox are next to each other.
  </p>
  <p>
   Well, that's the problem. I guess the ideal solution would be to link a label to a checkboxe using another mechanism (not using ID). I think the perfect way to do this would be to match a label to the input element whose NAME (not ID) is the same as the label's FOR attribute. What do you think?
  </p>
 </body>
</html>

person Shawn    schedule 24.04.2010    source источник
comment
Помимо отсутствия четкого вопроса, это дубликат stackoverflow.com/questions/8537621/.   -  person Mark E. Haase    schedule 29.02.2016


Ответы (6)


Лучшее, на мой взгляд, что можно сделать, это переименовать все чекбоксы, добавив какой-нибудь префикс к их идентификаторам, например input

   <ul>
    <li>
     <input type="checkbox" id="input_prologue" />
     <label for="input_prologue">prologue</label>
    </li>
    <li>
     <input type="checkbox" id="input_chapter" />
     <label for="input_chapter">chapter</label>
    </li>
    <li>
     <input type="checkbox" id="input_summary" />
     <label for="input_summary">summary</label>
    </li>
    <li>
     <input type="checkbox" id="input_etc" />
     <label for="input_etc">etc</label>
    </li>
   </ul>

Таким образом, у вас не будет конфликтов с другими идентификаторами на странице, а щелчок по метке будет переключать флажок без какой-либо специальной функции javascript.

person Draco Ater    schedule 24.04.2010

это было решено здесь: https://stackoverflow.com/a/8537641 просто сделайте это так

<label><input type="checkbox">Some text</label>
person user2046841    schedule 06.02.2013
comment
Это работает, только если метка и флажок находятся рядом друг с другом. - person Shawn; 06.02.2013
comment
@Shawn Как и в случае с исходным постом. - person Igor Zevaka; 11.02.2014
comment
Единственное, что я бы рекомендовал, это поместить текст перед входным тегом. В остальном идеально! - person Stan; 20.03.2015
comment
Проблема в том, что вам нужно его стилизовать. В CSS нет родительского селектора. - person Maciej Krawczyk; 08.06.2016
comment
Не общее решение проблемы, как описано в заголовке вопроса. Эта структура с меткой, обертывающей входной тег, просто невозможна для некоторых макетов. - person Triynko; 26.09.2016
comment
Это может быть невозможно в некоторых макетах, но без JS просто невозможно связать метку и ввод. Это одобренное WC3 решение без использования идентификатора для ссылки. И если вы действительно столкнетесь с проблемой стиля или разметки, используйте JS. - person perry; 03.01.2018

РЕДАКТИРОВАТЬ: Оглядываясь назад, мое решение далеко от идеального. Вместо этого я рекомендую вам использовать «неявную ассоциацию меток», как показано в этом ответе: stackoverflow.com/a/8537641/884734

Предлагаемое мною менее идеальное решение приведено ниже:

Эту проблему можно легко решить с помощью небольшого javascript. Просто добавьте следующий код в один из js-файлов вашей страницы, чтобы придать тегам <label> следующее поведение:

При нажатии на метку:

Если на странице есть элемент с id, совпадающим с атрибутом for метки, вернитесь к функциям по умолчанию и сфокусируйте ввод.

Если с использованием id совпадений не найдено, найдите родственного элемента label с class, совпадающим с атрибутом for label, и сосредоточьтесь на нем.

Это означает, что вы можете размещать свои формы следующим образом:

<form>
    <label for="login-validation-form-email">Email Address:</label>
    <input type="text" class="login-validation-form-email" />
</form>

Увы, реальный код:

$(function(){
    $('body').on('click', 'label', function(e){
        var labelFor = $( this ).attr('for');
        if( !document.getElementById(labelFor) ){
            e.preventDefault(); e.stopPropagation();
            var input = $( this ).siblings('.'+labelFor);
            if( input )
                input[0].focus();
        }
    })
});

Примечание. Это может вызвать проблемы при проверке вашего сайта на соответствие спецификации W3C, поскольку атрибут <label> for должен всегда иметь соответствующий элемент на странице с совпадающим идентификатором.

Надеюсь это поможет!

person Eric Seastrand    schedule 10.04.2012
comment
Спасибо тому, кто проголосовал против. Оглядываясь назад, мое решение далеко от идеального. Я рекомендую вместо этого использовать неявную ассоциацию меток, как показано в этом ответе: stackoverflow.com/a/8537641/884734 - person Eric Seastrand; 01.06.2016
comment
Это не только вызывает проблемы с валидаторами соответствия W3C, но и не работает для вспомогательных технологий, таких как, например, программы для чтения с экрана. Им нужна неявная ассоциация меток, как вы написали в своем комментарии. - person Volker E.; 08.11.2018

Проще говоря, идентификатор должен использоваться только один раз на странице, поэтому нет, они не будут разрабатывать обходной путь для нескольких идентификаторов на одной странице, которые не должны существовать.

Чтобы ответить на остальную часть вопроса: нет, атрибут ID — это единственное, на что будет смотреть атрибут метки «для». Вы всегда можете использовать событие JavaScript onclick, чтобы получить ввод по имени и изменить его, хотя это кажется слишком сложным, когда вы можете просто исправить проблему с идентификатором, что имело бы гораздо больше смысла.

person animuson    schedule 24.04.2010
comment
+1 за решение двух задач одним камнем. Некоторые бессмысленные сведения: атрибут for имеет тип данных IDREF, который ищет значение типа ID, которое должно быть уникальным. Это устаревшие типы данных, доступные для схемы XML, поэтому я полагаю, что это означает, что они являются резидентными типами данных SGML. - person ; 24.04.2010
comment
Проблема возникает, когда идентификаторы для входов создаются динамически. Я не могу знать, какими они будут, когда выбираю идентификаторы для других элементов на странице, поэтому я не могу гарантировать, что у них не будет дубликатов. И, как вы говорите, решение javascript слишком сложное (а у некоторых людей нет javascript). - person Shawn; 30.04.2010
comment
Сгенерируйте GUID для идентификаторов. - person Triynko; 15.09.2016

Возможно, простым простым решением будет использование uniqueid() php или другой альтернативной функции языка программирования.

person FantomX1    schedule 08.11.2017

В отличие от принятого ответа, я согласен с решением, предложенным FantomX1, сгенерировать случайный идентификатор для каждого флажка и использовать этот идентификатор для метки, связанной с флажком. Но я бы сгенерировал случайный идентификатор, используя uuid (см. Создать GUID/UUID в JavaScript?)

person yancheelo    schedule 08.03.2020