Gibt es eine Lösung für das im folgenden Code dargestellte Problem? Öffnen Sie zunächst den Code in einem Browser, um direkt zum Punkt zu gelangen, und müssen Sie nicht den gesamten Code durchsehen, bevor Sie wissen, wonach Sie suchen.
<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>
<label><input type="checkbox" />prologue</label>
</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>
Antworten:
Meiner Meinung nach können Sie am besten alle Kontrollkästchen umbenennen, indem Sie beispielsweise ihren IDs ein Präfix hinzufügen
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>
Auf diese Weise treten keine Konflikte mit anderen IDs auf einer Seite auf. Durch Klicken auf die Beschriftung wird das Kontrollkästchen ohne spezielle Javascript-Funktion umgeschaltet.
quelle
Es wurde hier behoben: https://stackoverflow.com/a/8537641 Mach es einfach so
<label><input type="checkbox">Some text</label>
quelle
EDIT: Rückblickend ist meine Lösung alles andere als ideal. Ich empfehle, stattdessen die "implizite Label-Zuordnung" zu nutzen, wie in dieser Antwort gezeigt: stackoverflow.com/a/8537641/884734
Meine vorgeschlagene, nicht ideale Lösung ist unten:
Dieses Problem kann leicht mit ein wenig Javascript gelöst werden. Wirf einfach den folgenden Code in eine der js-Dateien deiner Seite, um sie zu geben
<label>
Tags das folgende Verhalten :Wenn auf ein Etikett geklickt wird:
Wenn sich auf der Seite ein Element befindet, das mit
id
den Beschriftungen übereinstimmtfor
Attribut , kehren Sie zur Standardfunktionalität zurück und fokussieren Sie diese Eingabe.Wenn mit keine Übereinstimmung gefunden wurde
id
, suchen Sie nach einem Geschwister des Attributslabel
mitclass
demlabel
desfor
Attributs und fokussieren Sie es.Dies bedeutet, dass Sie Ihre Formulare folgendermaßen gestalten können:
<form> <label for="login-validation-form-email">Email Address:</label> <input type="text" class="login-validation-form-email" /> </form>
Leider der eigentliche Code:
$(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(); } }) });
Hinweis: Dies kann zu Problemen bei der Überprüfung Ihrer Site
<label>
for
anhand der W3C-Spezifikation führen, da das Attribut immer ein entsprechendes Element auf der Seite mit einer übereinstimmenden ID enthalten soll.Hoffe das hilft!
quelle
Einfach ausgedrückt, eine ID sollte nur einmal auf einer Seite verwendet werden. Nein, sie würden keine Problemumgehung für mehrere IDs auf einer einzelnen Seite entwerfen, die nicht vorhanden sein sollen.
Um den Rest der Frage zu beantworten: Nein, das ID-Attribut ist das einzige, was das 'for'-Attribut eines Labels betrachtet. Sie können jederzeit ein JavaScript-Ereignis onclick verwenden, um die Eingabe nach Namen abzurufen und zu ändern. Dies erscheint jedoch zu kompliziert, wenn Sie nur Ihr ID-Problem beheben können, was viel sinnvoller wäre.
quelle
Vielleicht wäre eine einfache und unkomplizierte Lösung die Verwendung von uniqueid () php oder einer anderen alternativen Programmiersprachenfunktion.
quelle
Im Gegensatz zur akzeptierten Antwort stimme ich der von FantomX1 vorgeschlagenen Lösung zu, generiere eine zufällige ID für jedes Kontrollkästchen und verwende diese ID für die dem Kontrollkästchen zugeordnete Bezeichnung. Aber ich würde die zufällige ID mit einer UUID generieren (siehe GUID / UUID in JavaScript erstellen? )
quelle