Как я могу использовать атрибут FOR тега LABEL без атрибута ID в теге INPUT - PullRequest
60 голосов
/ 24 апреля 2010

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

<code><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;
   
и не нужно давать ID для флажков. Но это работает, только если метка и флажок находятся рядом друг с другом.

Ну, это проблема. Я думаю, что идеальным решением было бы связать метку с флажком, используя другой механизм (не используя ID). Я думаю, что лучший способ сделать это - сопоставить метку с элементом ввода, имя которого (а не идентификатор) совпадает с атрибутом метки FOR. Как вы думаете?

Ответы [ 5 ]

121 голосов
/ 06 февраля 2013

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

<label><input type="checkbox">Some text</label>
14 голосов
/ 24 апреля 2010

Лучшее, на мой взгляд, то, что вы можете сделать, это переименовать все флажки, добавив некоторый префикс к их идентификаторам, например 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.

6 голосов
/ 10 апреля 2012

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

Мое предлагаемое, не идеальное решение ниже:

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

При нажатии на ярлык:

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

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

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

<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 всегда имеет соответствующий элемент на странице с соответствующим идентификатором.

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

3 голосов
/ 24 апреля 2010

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

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

1 голос
/ 08 ноября 2017

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

...