jQuery.click () vs onClick


558

Mam ogromną aplikację jQuery i używam dwóch poniższych metod dla zdarzeń kliknięcia.

Pierwsza metoda

HTML

<div id="myDiv">Some Content</div>

jQuery

$('#myDiv').click(function(){
    //Some code
});

Druga metoda

HTML

<div id="myDiv" onClick="divFunction()">Some Content</div>

Wywołanie funkcji JavaScript

function divFunction(){
    //Some code
}

W mojej aplikacji używam pierwszej lub drugiej metody. Który jest lepszy? Lepsza wydajność? A standard?


9
Możesz dowiedzieć się o różnych sposobach dołączania programów obsługi zdarzeń i ich zaletach / wadach: quirksmode.org/js/introevents.html . jQuery to po prostu ładne opakowanie do zaawansowanej rejestracji zdarzeń.
Felix Kling

12
Pamiętaj, aby umieścić funkcję kliknięcia w $ (dokument) .ready (funkcja ().
joan16v,

Odpowiedzi:


559

Używanie $('#myDiv').click(function(){jest lepsze, ponieważ jest zgodne ze standardowym modelem rejestracji zdarzeń. (jQuery używa wewnętrznieaddEventListener i attachEvent).

Zasadniczo rejestrowanie wydarzenia w nowoczesny sposób jest dyskretnym sposobem obsługi zdarzeń. Aby zarejestrować więcej niż jeden detektor zdarzeń dla celu, możesz wywołać addEventListener()ten sam cel.

var myEl = document.getElementById('myelement');

myEl.addEventListener('click', function() {
    alert('Hello world');
}, false);

myEl.addEventListener('click', function() {
    alert('Hello world again!!!');
}, false);

http://jsfiddle.net/aj55x/1/

Dlaczego warto korzystać z addEventListener? (Z MDN)

addEventListener to sposób na zarejestrowanie detektora zdarzeń zgodnie z DOM W3C. Jego zalety są następujące:

  • Umożliwia dodanie więcej niż jednego modułu obsługi zdarzenia. Jest to szczególnie przydatne w przypadku bibliotek DHTML lub rozszerzeń Mozilli, które muszą dobrze działać, nawet jeśli używane są inne biblioteki / rozszerzenia.
  • Daje to dokładniejszą kontrolę fazy, gdy słuchacz zostaje aktywowany (przechwytywanie vs. bulgotanie)
  • Działa na każdym elemencie DOM, nie tylko elementach HTML.

Więcej informacji na temat rejestracji nowoczesnych wydarzeń -> http://www.quirksmode.org/js/events_advanced.html

Inne metody, takie jak ustawianie atrybutów HTML , przykład:

<button onclick="alert('Hello world!')">

Lub właściwości elementu DOM , przykład:

myEl.onclick = function(event){alert('Hello world');}; 

są stare i można je łatwo napisać.

Należy unikać atrybutu HTML, ponieważ sprawia, że ​​znaczniki są większe i mniej czytelne. Obawy dotyczące treści / struktury i zachowania nie są dobrze rozdzielone, co utrudnia znalezienie błędu.

Problem z metodą właściwości elementu DOM polega na tym, że tylko jedna procedura obsługi zdarzeń może być powiązana z elementem na zdarzenie.

Więcej informacji na temat obsługi tradycyjnych wydarzeń -> http://www.quirksmode.org/js/events_tradmod.html

Dokumentacja MDN: https://developer.mozilla.org/en-US/docs/DOM/event


13
Załóżmy, że najpierw uruchamiasz $('#myDiv').click(function(){kod, a następnie generujesz dynamicznie 20 wierszy HTML z JavaScript, a każdy wiersz ma przycisk, który po kliknięciu JavaScript jest wymagany do wykonania tej samej funkcji. Jeśli zrobisz to najpierw, to nie będzie działać, ponieważ program obsługi zdarzeń został dodany przed wygenerowaniem HTML. Wydaje się, że łatwiej jest po prostu wrzucić onclick="functionName()"do dynamicznie generowanego kodu HTML, a następnie przycisk działa od razu. A może znasz bardziej eleganckie rozwiązanie tej sytuacji?
zuallauz

17
@zuallauz dla tego przypadku jQuery oferuje .delegate()funkcję. Dołącza wydarzenie do dowolnego elementu, który pojawi się w przyszłości na stronie.
Zefiryn

17
@SimonRobb .livejest przestarzałe. Użyj .delegatedla starszych wersji lub użyj .ondla nowszych wersji jQuery.
Selvakumar Arumugam

4
@Vega, dobre punkty. Co z czytelnością? Teraz musisz przeszukać wszystkie odnośne pliki JS na stronie, aby zobaczyć wszystkie procedury obsługi kliknięć elementu według identyfikatora elementu zamiast szukać nazwy funkcji. Jakie jest twoje zdanie na ten temat?
supertonsky,

6
Zgadzam się z @supertonsky. MOCNO nie zgadzam się, że $ ('# myDiv'). Click (function () {jest lepszy. W dużej aplikacji javascript powiązanie ze zdarzeniem staje się ogromnie trudne do znalezienia wszystkich referencji wiążących ten cel. Czy jest to wiązanie w klasie , id, dziecko odwołuje się do tagu html? A co się stanie, jeśli zmiany css i nazwy klas będą musiały zostać zmienione? Z mojego doświadczenia w pracy z innymi kodami robi się bardzo brzydko bardzo szybko.
Jon

65

Aby uzyskać lepszą wydajność, użyj natywnego JavaScript. Aby przyspieszyć programowanie, użyj jQuery. Sprawdź porównanie wydajności w jQuery vs wydajność elementu natywnego .

Zrobiłem test w Firefox 16.0 32-bit na Windows Server 2008 R2 / 7 64-bit

$('span'); // 6,604 operations per second
document.getElementsByTagName('span'); // 10,331,708 operations/sec

W przypadku zdarzeń kliknięcia sprawdź zdarzenia Przeglądarka natywna vs wyzwalacz jquery lub jQuery vs Powiązanie zdarzenia Native Click .

Testowanie w Chrome 22.0.1229.79 32-bit na Windows Server 2008 R2 / 7 64-bit

$('#jquery a').click(window.testClickListener); // 2,957 operations/second

[].forEach.call( document.querySelectorAll('#native a'), function(el) {
    el.addEventListener('click', window.testClickListener, false);
}); // 18,196 operations/second

9
jQuery powinien być w stanie działać w wielu różnych środowiskach, co czyni go bardziej robotem i łatwiej jest pisać, utrzymywać, ale jeśli prędkość jest najważniejsza, to jQuery nie jest odpowiedzią
Coops

Bądź ostrożny przy korzystaniu z forEach, ponieważ nie wszystkie są kompatybilne z przeglądarką, myślę, że nie dla IE. Może przyda się polypełniacz.
khaled_webdev

39

Z tego, co rozumiem, twoje pytanie tak naprawdę nie dotyczy tego, czy użyć jQuery, czy nie. Raczej: czy lepiej jest łączyć zdarzenia bezpośrednio w HTML lub przez detektory zdarzeń?

Wiązanie wbudowane jest przestarzałe. Ponadto w ten sposób możesz powiązać tylko jedną funkcję z określonym zdarzeniem.

Dlatego zalecam używanie detektorów zdarzeń. W ten sposób będziesz mógł powiązać wiele funkcji z jednym zdarzeniem i, w razie potrzeby, usunąć powiązanie później. Rozważ ten czysty kod JavaScript:

querySelector('#myDiv').addEventListener('click', function () {
    // Some code...
});

Działa to w większości nowoczesnych przeglądarek.

Jeśli jednak już włączasz jQuery do swojego projektu - po prostu użyj jQuery: .onlub .clickfunkcji.


Możliwe jest zarejestrowanie wielu funkcji za pomocą wbudowanego kodu HTML, takiego jak <div onclick = "handler1 (); handler2 (); handler3 ();"> </div>
Kira

2
W ten sposób nadal rejestrujesz tylko jedno „wyrażenie”. Na przykład, jeśli handler1zgłosi błąd handler2i handler3nigdy nie zostanie wywołany. Co więcej, nie możesz dynamicznie dodawać i usuwać niektórych funkcji z odbiornika. I wreszcie handler1, handler2i handler3muszą być zadeklarowane w globalnym zasięgu, który jest zapachem.
Michał Miszczyszyn

Korzystanie try..catchz funkcji wewnątrz nie będzie działać, gdy jest handler2niezdefiniowane. FYI wbudowany JavaScript oczywiście nie działa, gdy JS jest wyłączony w przeglądarce użytkownika, proszę nie wprowadzać w błąd innych.
Michał Miszczyszyn

Wspomniałem, że nie jestem pewien wyłączonego JavaScript. Nie wprowadzam w błąd innych ani oszukańczych
Kira

W takim przypadku możesz wypróbować następującą <div onclick = "function () {try {handler1 (); handler2 (); handler3 ();} catch {}}"> </div>
Kira

15

Możesz je połączyć, użyć jQuery, aby powiązać funkcję z kliknięciem

<div id="myDiv">Some Content</div>

$('#myDiv').click(divFunction);

function divFunction(){
 //some code
}

14

$('#myDiv').clickjest lepszy, ponieważ oddziela kod JavaScript od HTML . Należy starać się, aby zachowanie i struktura strony były inne . To bardzo pomaga.


2
Ta odpowiedź ma sens, ponieważ ludzie, którzy projektują i piszą pliki js, w większości przypadków są inni. I dziwnie jest głosować za tym po prawie 4 latach od opublikowania tego !!
Nauka

14

Idź do tego, ponieważ zapewni to zarówno standard, jak i wydajność.

 $('#myDiv').click(function(){
      //Some code
 });

Drugą metodą jest prosty kod JavaScript i jest on szybszy niż jQuery. Ale tutaj wydajność będzie w przybliżeniu taka sama.


11

IMHO, onclick jest preferowaną metodą zamiast .click tylko wtedy, gdy spełnione są następujące warunki:

  • na stronie jest wiele elementów
  • tylko jedno zdarzenie musi zostać zarejestrowane dla zdarzenia kliknięcia
  • Martwisz się wydajnością telefonu / żywotnością baterii

Sformułowałem tę opinię, ponieważ silniki JavaScript na urządzeniach mobilnych są 4 do 7 razy wolniejsze niż ich odpowiedniki na komputery stacjonarne tej samej generacji. Nienawidzę tego, gdy odwiedzam witrynę na moim urządzeniu mobilnym i przewijam roztrzęsiony, ponieważ jQuery wiąże wszystkie zdarzenia kosztem doświadczenia użytkownika i żywotności baterii. Kolejny niedawny czynnik wspierający, chociaż powinno to dotyczyć tylko agencji rządowych;), mieliśmy okno pop-up IE7 z oknem komunikatu informującym, że proces JavaScript zajmuje dużo czasu ... poczekaj lub anuluj proces. Stało się tak za każdym razem, gdy za pośrednictwem jQuery było wiele elementów do połączenia.


10

Różnica w pracach. Jeśli użyjesz click (), możesz dodać kilka funkcji, ale jeśli użyjesz atrybutu, zostanie wykonana tylko jedna funkcja - ostatnia.

PRÓBNY

HTML

<span id="JQueryClick">Click #JQuery</span> </br>
<span id="JQueryAttrClick">Click #Attr</span> </br>

JavaScript

$('#JQueryClick').click(function(){alert('1')})
$('#JQueryClick').click(function(){alert('2')})

$('#JQueryAttrClick').attr('onClick'," alert('1')" ) //This doesn't work
$('#JQueryAttrClick').attr('onClick'," alert('2')" )

Jeśli mówimy o wydajności, w każdym przypadku bezpośrednie użycie jest zawsze szybsze, ale przy użyciu atrybutu można przypisać tylko jedną funkcję.


Możemy wykonać więcej niż jedną funkcję za pomocą atrybutu takiego jak $ ('# JQueryAttrClick'). Attr ('onClick', "alert ('2'); alert ('3'); alert ('4')”)
Kira

8

Kluczem jest tutaj rozdzielenie obaw, a zatem wiązanie zdarzeń jest ogólnie przyjętą metodą. Jest to w zasadzie to, co powiedziało wiele istniejących odpowiedzi.

Jednak nie wyrzucać ideę znaczników deklaratywnej zbyt szybko. Ma swoje miejsce, a dzięki ramom takim jak Angularjs jest centralnym punktem.

Trzeba zrozumieć, że całość <div id="myDiv" onClick="divFunction()">Some Content</div>została tak bardzo zawstydzona, ponieważ została nadużyta przez niektórych programistów. Więc osiągnął punkt świętokradzkich proporcji, podobnie jak tables. Niektórzy programiści faktycznie unikają tablesdanych tabelarycznych. To idealny przykład ludzi działających bez zrozumienia.

Chociaż podoba mi się pomysł, aby moje zachowanie było oddzielone od moich poglądów. Nie widzę problemu ze znacznikami deklarującymi, co robi (nie jak to robi, to jest zachowanie). Może mieć postać rzeczywistego atrybutu onClick lub atrybutu niestandardowego, podobnie jak komponenty javascript do bootstrapsa.

W ten sposób, patrząc tylko na znaczniki, możesz zobaczyć, co się dzieje, zamiast próbować odwrócić wyszukiwanie powiązań zdarzeń javascript.

Tak więc, jako trzecia alternatywa dla powyższego, użycie atrybutów danych do deklaratywnego ogłoszenia zachowania w obrębie znaczników. Zachowanie jest niewidoczne, ale na pierwszy rzut oka widać, co się dzieje.

Przykład ładowania początkowego:

<button type="button" class="btn btn-lg btn-danger" data-toggle="popover" title="Popover title" data-content="And here's some amazing content. It's very engaging. Right?">Click to toggle popover</button>

Źródło: http://getbootstrap.com/javascript/#popovers

Uwaga Główną wadą drugiego przykładu jest zanieczyszczenie globalnej przestrzeni nazw. Można to obejść, stosując trzecią alternatywę powyżej lub szkielety takie jak Angular i ich atrybuty ng-click z automatycznym zasięgiem.


4

Żadne z nich nie jest lepsze , ponieważ można je wykorzystywać do różnych celów. onClick(powinno być onclick) działa bardzo nieznacznie lepiej, ale bardzo wątpię, czy zauważysz różnicę.

Warto zauważyć, że robią różne rzeczy: .clickmogą być powiązane z dowolną kolekcją jQuery, podczas gdy onclickmuszą być używane w połączeniu z elementami, z którymi chcesz się związać. Możesz także powiązać tylko jedno zdarzenie z użyciem onclick, a jednocześnie .clickmożesz kontynuować wiązanie zdarzeń.

Moim zdaniem byłbym konsekwentny w tej kwestii i po prostu używałbym .clickwszędzie i trzymał cały mój kod JavaScript razem i oddzielony od HTML.

Nie używać onclick. Nie ma żadnego powodu, aby z niego korzystać, chyba że wiesz, co robisz i prawdopodobnie nie wiesz.


2
Nawet jeśli „lepszy” nie jest wyraźnie zdefiniowany, prawie nigdy nie jest dobrym pomysłem umieszczanie procedur obsługi zdarzeń bezpośrednio w znacznikach
Jay

@Jayraj, kiedy w mojej odpowiedzi powiedziałem, że to dobry pomysł?
Tabletki przeciwwybuchowe

3
Mówiąc .clicknie było lepsze niż onclick(„Żadne z nich nie jest lepsze ”) sugerowano, że onclickjest to prawie lub tak samo dobry sposób na pisanie kodu, podczas gdy w rzeczywistości .clickjest to lepsza praktyka o milę. Przepraszam, ale IMHO powinieneś przeformułować swoją odpowiedź
Jay

2
@ExplosionPills Chciałbym usunąć część odpowiedzi, która mówi, że żadna nie jest lepsza. Akapit na końcu brzmi jak sprzeczność.
Juan Mendes,

4
<whatever onclick="doStuff();" onmouseover="in()" onmouseout="out()" />

zdarzenia onclick, onmouseover, onmouseout itp. są w rzeczywistości niekorzystne dla wydajności ( głównie w Internet Explorerze , idź). Jeśli kodujesz za pomocą programu Visual Studio , po uruchomieniu strony z nimi każda z nich utworzy oddzielny blok SCRIPT zajmujący pamięć, a tym samym spowalniający wydajność.

Nie wspominając, że powinieneś mieć oddzielne obawy : JavaScript i układy powinny być oddzielone!

Zawsze lepiej jest tworzyć evenHandler dla każdego z tych zdarzeń, jedno zdarzenie może przechwycić setki / tysiące elementów, zamiast tworzyć tysiące osobnych bloków skryptów dla każdego!

(Ponadto wszystko, co wszyscy mówią).


3

Jednym z głównych pomysłów jQuery jest oddzielenie JavaScript od nieprzyjemnego kodu HTML . Pierwszą metodą jest droga.


3

Przez większość czasu natywne metody JavaScript są lepszym wyborem niż jQuery, gdy jedynym kryterium jest wydajność, ale jQuery korzysta z JavaScript i ułatwia programowanie. Możesz użyć jQuery, ponieważ nie obniża to zbytnio wydajności. W twoim konkretnym przypadku różnica w wydajności jest niezauważalna.


2

Pierwszą metodą użycia onclicknie jest jQuery, ale po prostu JavaScript, więc nie dostajesz narzutów związanych z jQuery. Sposób jQuery można rozszerzyć za pomocą selektorów, jeśli trzeba go dodać do innych elementów bez dodawania modułu obsługi zdarzeń do każdego elementu, ale tak jak teraz, jest tylko pytanie, czy należy użyć jQuery, czy nie.

Osobiście, ponieważ używasz jQuery, trzymałbym się go, ponieważ jest spójny i oddziela znaczniki od skryptu.


1
Przykład jQuery jest praktycznie taki sam document.querySelector('#something').addEventListener(...lub podobny w zwykłym Javascript, więc nie o to chodzi. Podobnie możesz przechwytywać bąbelkowe zdarzenia z węzłów potomnych w JavaScript, nie tylko za pomocą skrótów jQuery. Sednem sprawy jest to, że zdarzenia te powinny znajdować się w kontrolerze (plik definicji zachowania javascript), a nie w widoku (rozproszone tu i tam w html, wymagające funkcji zmiennych globalnych lub jeszcze gorzej, kodu wbudowanego.)
NoBugs

2

Pierwszą metodą jest preferowanie. Wykorzystuje zaawansowane modele rejestracji zdarzeń , co oznacza, że ​​możesz dołączyć wiele procedur obsługi do tego samego elementu. Możesz łatwo uzyskać dostęp do obiektu zdarzenia, a moduł obsługi może żyć w zakresie dowolnej funkcji. Ponadto jest dynamiczny, tzn. Można go wywołać w dowolnym momencie i jest szczególnie odpowiedni dla dynamicznie generowanych elementów. Nieważne, czy używasz jQuery, innej biblioteki czy metod natywnych.

Druga metoda, wykorzystująca atrybuty wbudowane, wymaga wielu globalnych funkcji (co prowadzi do zanieczyszczenia przestrzeni nazw) i łączy zawartość / strukturę (HTML) z zachowaniem (JavaScript). Nie używaj tego.

Na twoje pytanie dotyczące wydajności lub standardów nie można łatwo odpowiedzieć. Te dwie metody są zupełnie inne i robią różne rzeczy. Pierwszy jest potężniejszy, a drugi pogardzany (uważany za zły styl).


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.