W poniższym przykładzie kliknięcie etykiety powoduje zmianę stanu danych wejściowych.
document.querySelector("label").addEventListener("click", function() {
console.log("clicked label");
});
label {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
<input type="checkbox" id="1">
<label for="1">Label</label>
W Chrome, gdy przesuwasz kursor między zdarzeniami mousedown
i mouseup
, dane wejściowe są nadal wyzwalane, podczas gdy w Firefox pole wyboru nie zmienia stanu.
Czy istnieje sposób, aby to naprawić? (bez użycia detektorów zdarzeń JavaScript)
Wersja Firefox: 69.0.3 (64-bit)
Pełny zestaw działań podczas korzystania z chrome.
- Naciśnij przycisk na etykiecie
- Przesuń kursor wokół (nawet poza etykietę), wciąż trzymając przycisk
- Wróć kursor z powrotem do etykiety
- Zwolnij przycisk
javascript
html
css
label
nick zoum
źródło
źródło
1px
przerwie interakcję.Odpowiedzi:
Wprowadzenie
Chociaż wyraźnie stwierdziłem w pytaniu, że odpowiedź nie powinna obejmować JavaScript, wszystkie odpowiedzi działały z JavaScript.
Ponieważ wydaje się, że jest to błąd przeglądarki Firefox, a większość odpowiedzi przesłanych w tym momencie wymagałaby również zmiany reszty mojego kodu, postanowiłem utworzyć skrypt, który można uruchomić raz, poradzi sobie ze wszystkimi etykietami niezależnie od tego, kiedy są dodawane do domeny i będą miały najmniejszy wpływ na moje inne skrypty.
Rozwiązanie - przykład
Wyjaśnienie
onLabelClick
Funkcja
onLabelClick
musi być wywoływana za każdym razem, gdy kliknięta zostanie etykieta, sprawdzi, czy etykieta ma odpowiedni element wejściowy. Jeśli tak, to będzie go wyzwolić, usunąćfor
atrybut etykiety tak, że przeglądarki nie ma błędu nie będzie re-trigger go, a następnie użyćsetTimeout
w0ms
celu dodaniafor
plecy atrybutu raz impreza przepuszcza się w górę. Oznacza to,event.preventDefault
że nie trzeba dzwonić, dlatego żadne inne działania / zdarzenia nie zostaną anulowane. Również jeśli muszę zastąpić tę funkcję, muszę tylko dodać detektor zdarzeń, który wywołujeEvent#preventDefault
lub usuwafor
atrybut.manageLabel
Funkcja
manageLabel
akceptuje etykietę sprawdza, czy został już dodany detektor zdarzeń, aby uniknąć ponownego dodania go, dodaje detektor, jeśli nie został jeszcze dodany, i dodaje go do listy etykiet, którymi zarządzano.onLoad
Funkcja
onLoad
musi zostać wywołana, gdy strona zostanie załadowana, abymanageLabel
można było wywołać funkcję dla wszystkich etykiet w DOM w tym momencie. Funkcja używa także MutationObserver do przechwytywania dodawanych etykiet po uruchomieniu obciążenia (i uruchomieniu skryptu).Powyższy kod został zoptymalizowany przez Martina Barkera .
źródło
HTMLLabelElement
czekiem zamiast HTMLElement i sprawdzeniem, czy tagName to etykietaWiem, że nie chciałeś nasłuchiwać zdarzeń JS, ale myślę, że chcesz zidentyfikować ruch, który nie polega na tym, że używa mousedown zamiast klikania (mousedown, a następnie upuszczanie myszy).
Chociaż jest to znany błąd w przeglądarce Firefox, można go obejść za pomocą zdarzenia mousedown
Musiałem zmienić Twój identyfikator, aby był prawidłowy. Identyfikator musi zaczynać się od znaku
źródło
querySelectorAll
) podczas ładowania strony, a następnie za każdym razem, gdy etykieta zostanie dodana do domeny. Może to również zepsuć wszystkie detektory zdarzeń myszy dodane do etykiet lub domeny w ogóle, gdy używasz,Event#preventDefault
aby uniknąć podwójnego klikania w przeglądarkach, które nie mają tego błędu. Wreszcie, użycieclick
zdarzenia byłoby lepsze, ponieważ miałoby to tę samą interakcję, co zamierzone działanie. Poza tym to najlepsza jak dotąd odpowiedź.preventDefault()
problem, więc działa, sprawdzając, czy przeglądarka go zmieniła, jeśli nie zmieni, po 150 ms wystarczająco szybko, aby użytkownik nie zauważył, i wystarczająco wolno, aby przeglądarka działała intime, jeśli zrobi to, co powinien. czy to jest lepsze?Nie. To wygląda jak błąd Firefoksa, a nie problem z twoim kodem. Nie wierzę, że istnieje takie obejście css dla tego zachowania.
Możesz być w stanie zgłosić to Mozilli i naprawić problem, ale nie polegałbym na tym. https://bugzilla.mozilla.org/home
Dla potencjalnego obejścia zasugerowałem zamiast tego wywołanie zdarzenia po najechaniu myszką.
źródło
Bez javascript, po kliknięciu etykiety, której wartość „for” jest taka sama jak wartość „id” wejściowego, dane wejściowe są klikane, ale nie jest to spójne wśród przeglądarek.
Jeśli przeglądarka postępuje zgodnie z powyższym, to zdarzenie kliknięcia w javascript anuluje efekt, co w efekcie nie robi nic.
Rozwiązanie
Aby zachować spójność między przeglądarkami, możesz zastosować inną strategię: Onload dynamicznie zmienia wszystkie atrybuty „for” dla „data-for”, więc unieważnia oryginalny efekt przeglądarki. Następnie możesz zastosować zdarzenie kliknięcia do każdej etykiety.
źródło
document.attachEvent("onreadystatechange",
Jestem po prostu zintegrowany, jak to się stało, a niedocument.addEventListener("DOMContentLoaded",
?Dołączenie zdarzenia do dokumentu i ukierunkowanie na wymagany element powinno rozwiązać ten problem.
$ (Dokument) .on („kliknięcie”, „.item”, funkcja (zdarzenie) {});
Od czytania tego tematu w przeszłości, Firefox rozumie twoje działanie jako próbę przeciągnięcia elementu, ponieważ wybór użytkownika nie ma, po prostu uniemożliwia zachowanie domyślne.
Opiera się to na dość ograniczonej wiedzy, ale wydaje się, że jest to znany błąd / dziwactwo i jest kilka artykułów na ten temat.
źródło
without using JavaScript event listeners
.