Wiem, że to zła praktyka. Jeśli to możliwe, nie pisz takiego kodu.
Oczywiście zawsze znajdziemy się w sytuacjach, w których sprytny fragment wbudowanego kodu JavaScript może szybko rozwiązać problem.
Podążam za tym pytaniem, aby w pełni zrozumieć, co się dzieje (i potencjalne pułapki), gdy napisane jest coś takiego:
<a href="#" onclick="alert('Hi')">Click Me</a>
O ile wiem, funkcjonalnie jest to to samo, co
<script type="text/javascript">
$(function(){ // I use jQuery in this example
document.getElementById('click_me').onclick =
function () { alert('Hi'); };
});
</script>
<a href="#" id="click_me">Click Me</a>
Ekstrapolując z tego, wydaje się, że ciąg przypisany do atrybutu onclick
jest wstawiany w anonimowej funkcji, która jest przypisana do modułu obsługi kliknięcia elementu. Czy tak jest w rzeczywistości?
Ponieważ zaczynam robić takie rzeczy:
<a href="#" onclick="$(this).next().fadeIn(); return false;">Display my next sibling</a> <!-- Return false in handler so as not to scroll to top of page! -->
Co działa. Ale nie wiem, ile to hack. Wygląda podejrzanie, ponieważ nie ma żadnej funkcji, która jest zwracana!
Możesz zapytać, dlaczego to robisz, Steve? Inline JS to zła praktyka!
Cóż, jeśli mam być całkiem szczery, mam dość edytowania trzech różnych sekcji kodu tylko po to, aby zmodyfikować jedną sekcję strony, zwłaszcza gdy tylko prototypuję coś, aby zobaczyć, czy w ogóle zadziała. Jest to o wiele łatwiejsze, a czasem nawet ma sens, aby kod konkretnie powiązany z tym elementem HTML był zdefiniowany bezpośrednio w elemencie: Kiedy 2 minuty później zdecyduję, że to był okropny, okropny pomysł, mogę niszczyć cały div (lub cokolwiek innego ) i nie mam wielu tajemniczych okruchów JS i CSS w reszcie strony, spowalniających renderowanie nawet nieznacznie. Jest to podobne do koncepcji lokalizacji odniesienia, ale zamiast braków w pamięci podręcznej patrzymy na błędy i nadmiar kodu.
źródło
#click_me
zdarzenia DOMready lub umieścić skrypt za węzłem.document.getElementById("click_me").onclick;
. Albo powiadom go. Zobaczysz, że jest to funkcja.Odpowiedzi:
Masz prawie poprawne, ale nie uwzględniłeś
this
wartości dostarczonej do kodu wbudowanego.<a href="#" onclick="alert(this)">Click Me</a>
jest właściwie bliżej:
<a href="#" id="click_me">Click Me</a> <script type="text/javascript"> document.getElementById('click_me').addEventListener("click", function(event) { (function(event) { alert(this); }).call(document.getElementById('click_me'), event); }); </script>
Wbudowane programy obsługi zdarzeń ustawione
this
na wartość docelową zdarzenia. Możesz także użyć funkcji anonimowej w skrypcie wbudowanym<a href="#" onclick="(function(){alert(this);})()">Click Me</a>
źródło
event
za pomocą inlineonclick='myFunction(event)'
?Co robi przeglądarka, gdy masz
<a onclick="alert('Hi');" ... >
to ustawienie rzeczywistej wartości „onclick” na coś podobnego do:
new Function("event", "alert('Hi');");
Oznacza to, że tworzy funkcję, która oczekuje parametru „zdarzenia”. (Cóż, IE tego nie robi; bardziej przypomina zwykłą, prostą funkcję anonimową).
źródło
event
do pobrania zdarzenia (i jego elementu źródłowego za pośrednictwemevent.target
) z mojego wbudowanego fragmentu kodu JS! Fajne.event
parametru, ale jeśli użyjeszevent
wewnątrz tej anonimowej funkcji, IE zrozumie ją jako rzeczywisty obiekt zdarzenia. Ponieważ funkcja anonimowa jest ustawiona jako właściwośćwindow
obiektu w IE, zobaczy to jakowindow.event
.Wydaje się, że wokół atrybutów obsługi zdarzeń rzuca się dużo złych praktyk . Zła praktyka to nieznajomość i nieznajomość dostępnych funkcji tam, gdzie jest to najbardziej odpowiednie. Atrybuty zdarzeń są w pełni udokumentowanymi standardami W3C i nie ma w nich nic złego. Nie różni się to niczym od umieszczania stylów wbudowanych, co jest również udokumentowane w W3C i może być przydatne w czasach. Niezależnie od tego, czy umieścisz go w znacznikach skryptu, czy nie, będzie to interpretowane w ten sam sposób.
https://www.w3.org/TR/html5/webappapis.html#event-handler-idl-attributes
źródło
bad practice/spaghettification
dla jednych,good practice/structure
dla innych jest.Najlepszym sposobem odpowiedzi na pytanie jest zobaczenie go w akcji.
<a id="test" onclick="alert('test')"> test </a>
W js
var test = document.getElementById('test'); console.log( test.onclick );
Jak widać w
console
, jeśli używasz chrome, wyświetla anonimową funkcję z przekazanym obiektem zdarzenia, chociaż w IE jest to trochę inne.function onclick(event) { alert('test') }
Zgadzam się z niektórymi twoimi uwagami na temat wbudowanych programów obsługi zdarzeń. Tak, są łatwe do napisania, ale nie zgadzam się z twoim punktem widzenia konieczności zmiany kodu w wielu miejscach, jeśli dobrze ustrukturyzujesz kod, nie powinieneś tego robić.
źródło
<button onclick="login()"> test login </button>
jest idealne do prototypowania. Chcesz przetestować coś, co wymaga interakcji użytkownika w tej chwili, i tak i tak zamierzasz usunąć to później. Po co pisać dodatkowy kod w każdym miejscu?Jest to anonimowa funkcja, która została dołączona do zdarzenia kliknięcia obiektu.
Dlaczego doi ..... Ach nieważne, jak wspomniałeś, jest to naprawdę powszechnie przyjęta zła praktyka :)
źródło
Spróbuj tego w konsoli:
var div = document.createElement('div'); div.setAttribute('onclick', 'alert(event)'); div.onclick
W Chrome pokazuje to:
function onclick(event) { alert(event) }
... i niestandardowa
name
właściwośćdiv.onclick
is"onclick"
.Zatem to, czy jest to anonimowe, zależy od definicji pojęcia „anonimowy”. Porównaj z czymś w rodzaju
var foo = new Function()
, gdziefoo.name
jest pustym łańcuchem, afoo.toString()
wygeneruje coś podobnegofunction anonymous() { }
źródło