2010-04-24 261 views
47

下面的代碼說明了問題的解決方案嗎?首先在瀏覽器中打開代碼以便直觀地看到問題,而不必在知道要查找的內容之前查看所有代碼。如何使用INPUT標籤上沒有ID屬性的LABEL標籤的FOR屬性

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

除了沒有明確的問題,這是http://stackoverflow.com/questions/8537621/possible-to-associate-label-with-checkbox-without-using-for-id的重複。 – 2016-02-29 04:02:24

回答

13

最好的,在我看來,你可以做什麼,就是要重命名所有的複選框,通過添加一些前綴,它們的ID例如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> 

這樣,你不會有任何衝突頁面上的其他ID以及單擊該標籤將切換複選框而不使用任何特殊的JavaScript功能。

2

簡單地說,一個ID只應該是一個頁面上使用一次,所以沒有他們不會設計了多個ID的一個解決方法這是不應該出現在一個頁面上。

要回答問題的其餘部分:否,ID屬性是標籤的'for'屬性將查看的唯一內容。您可以隨時使用JavaScript onclick事件通過名稱獲取輸入內容並對其進行更改,但如果您可以修復您的ID問題,這看起來過於複雜,這會使情況更加明顯。

+0

+1,一石二攻。一些沒有意義的FYI:for屬性是數據類型IDREF,它看起來類型ID的值,它必須是唯一的。這些是XML Schema可用的遺留數據類型,所以我想這意味着它們是SGML的常駐數據類型。 – 2010-04-24 06:01:14

+9

當輸入的ID是動態創建時發生問題。當我爲頁面上的其他元素選擇ID時,我不知道它們會是什麼,所以我不能確保它們不會有重複。正如你所說,JavaScript解決方案過於複雜(有些人沒有JavaScript)。 – Shawn 2010-04-29 23:11:52

+0

爲這些ID生成GUID。 – Triynko 2016-09-15 13:07:31

6

編輯:回想起來,我的解決方案是遠非理想。我建議你,而不是利用「隱式標籤協會」,如圖這樣的回答:stackoverflow.com/a/8537641/884734

我的建議,低於理想的解決方案是如下:

這個問題可以通過一些JavaScript迎刃而解。只要將下面的代碼到網頁的js文件的一個給<label>標籤以下行爲:

當點擊標籤:

如果有id匹配標籤的for屬性頁面上的元素,恢復默認功能並關注該輸入。

如果使用id沒有發現匹配,尋找label的用class匹配labelfor屬性的兄弟姐妹,並將重點。

這意味着,你可以制定出你這樣的形式:

<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屬性應該始終在頁面上具有匹配ID的對應元素。

希望這會有所幫助!

+0

感謝誰downvoted。回想起來,我的解決方案並不理想。我建議您改用這個答案中顯示的「隱式標籤關聯」:http://stackoverflow.com/a/8537641/884734 – Eric 2016-06-01 13:04:34

100

它已經在這裏解決: https://stackoverflow.com/a/8537641 只是做了這樣的

<label><input type="checkbox">Some text</label> 
+8

這隻有在標籤和複選框相鄰時纔有效。 – Shawn 2013-02-06 15:52:24

+7

@Shawn原來的帖子是這種情況。 – 2014-02-11 06:07:01

+0

我推薦的唯一的東西是把文本放在輸入標籤之前。否則,完美! – Stan 2015-03-20 18:30:50

0

也許容易簡單的解決方案將使用UNIQUEID()PHP或其他編程語言的替代功能。