addEventListener vs onclick

704

Jaka jest różnica między addEventListeneri onclick?

var h = document.getElementById("a");
h.onclick = dothing1;
h.addEventListener("click", dothing2);

Powyższy kod znajduje się razem w osobnym pliku .js i oba działają doskonale.

William Sham
źródło

Odpowiedzi:

955

Oba są poprawne, ale żadne z nich nie jest „najlepsze” per se, i może istnieć powód, dla którego deweloper zdecydował się na oba podejścia.

Detektory zdarzeń (addEventListener i IE's attachEvent)

Wcześniejsze wersje Internet Explorera implementują javascript inaczej niż prawie każda inna przeglądarka. W wersjach mniejszych niż 9 używasz metody attachEvent[ doc ], jak poniżej:

element.attachEvent('onclick', function() { /* do stuff here*/ });

W większości innych przeglądarek (w tym IE 9 i nowszych) używasz addEventListener[ doc ], jak poniżej:

element.addEventListener('click', function() { /* do stuff here*/ }, false);

Korzystając z tego podejścia ( zdarzenia DOM Level 2 ), możesz dołączyć teoretycznie nieograniczoną liczbę zdarzeń do dowolnego pojedynczego elementu. Jedynym praktycznym ograniczeniem jest pamięć po stronie klienta i inne problemy z wydajnością, które są różne dla każdej przeglądarki.

Powyższe przykłady przedstawiają użycie anonimowej funkcji [ doc ]. Możesz także dodać detektor zdarzeń, korzystając z odwołania do funkcji [ doc ] lub zamknięcia [ doc ]:

var myFunctionReference = function() { /* do stuff here*/ }

element.attachEvent('onclick', myFunctionReference);
element.addEventListener('click', myFunctionReference , false);

Inną ważną cechą addEventListenerjest parametr końcowy, który kontroluje sposób, w jaki słuchacz reaguje na propagację zdarzeń [ doc ]. W przykładach podawałem fałsz, co jest standardem w prawdopodobnie 95% przypadków użycia. Nie ma równoważnego argumentu attachEventani dla zdarzeń wbudowanych.

Zdarzenia wbudowane (właściwość HTML onclick = "" i element.onclick)

We wszystkich przeglądarkach obsługujących javascript można wstawić detektor zdarzeń bezpośrednio, co oznacza bezpośrednio w kodzie HTML. Prawdopodobnie widziałeś to:

<a id="testing" href="#" onclick="alert('did stuff inline');">Click me</a>

Najbardziej doświadczeni programiści unikają tej metody, ale wykonuje zadanie; to jest proste i bezpośrednie. Nie możesz tutaj używać zamknięć ani anonimowych funkcji (chociaż sam program obsługi jest swego rodzaju anonimową funkcją), a twoja kontrola zakresu jest ograniczona.

Druga metoda, o której wspominasz:

element.onclick = function () { /*do stuff here */ };

... jest odpowiednikiem wbudowanego javascript, z tym wyjątkiem, że masz większą kontrolę nad zakresem (ponieważ piszesz skrypt zamiast HTML) i możesz używać anonimowych funkcji, odwołań do funkcji i / lub zamknięć.

Istotną wadą zdarzeń wbudowanych jest to, że w przeciwieństwie do detektorów zdarzeń opisanych powyżej, można przypisać tylko jedno zdarzenie wbudowane. Zdarzenia wbudowane są przechowywane jako atrybut / właściwość elementu [ doc ], co oznacza, że ​​można je zastąpić.

Korzystając z przykładu <a>z powyższego kodu HTML:

var element = document.getElementById('testing');
element.onclick = function () { alert('did stuff #1'); };
element.onclick = function () { alert('did stuff #2'); };

... kiedy kliknąłeś element, zobaczysz tylko „Zrobiłem rzeczy # 2” - nadpisałeś pierwszą przypisaną onclickwłaściwość drugą wartością, a także nadpisałeś oryginalną wbudowaną onclickwłaściwość HTML . Sprawdź to tutaj: http://jsfiddle.net/jpgah/ .

Mówiąc ogólnie, nie używaj zdarzeń wbudowanych . Mogą istnieć konkretne przypadki użycia, ale jeśli nie jesteś w 100% pewien, że masz taki przypadek użycia, nie używasz i nie powinieneś używać zdarzeń wbudowanych.

Nowoczesne Javascript (Angular i tym podobne)

Od czasu opublikowania tej odpowiedzi frameworki javascript, takie jak Angular, stały się znacznie bardziej popularne. Kod taki zobaczysz w szablonie Angular:

<button (click)="doSomething()">Do Something</button>

To wygląda jak zdarzenie wbudowane, ale tak nie jest. Ten typ szablonu zostanie przełożony na bardziej złożony kod, który korzysta z detektorów zdarzeń za sceną. Wszystko, co tu napisałem o wydarzeniach, nadal obowiązuje, ale jesteś usunięty z drobiazgów przez co najmniej jedną warstwę. Powinieneś rozumieć rzeczy, ale jeśli najlepsze praktyki nowoczesnego frameworka JS obejmują pisanie tego rodzaju kodu w szablonie, nie myśl, że używasz zdarzenia wbudowanego - nie jesteś.

Który jest najlepszy?

Pytanie dotyczy kompatybilności i konieczności przeglądarki. Czy chcesz dołączyć więcej niż jedno zdarzenie do elementu? Czy będziesz w przyszłości? Szanse są, będziesz. Konieczne są attachEvent i addEventListener. Jeśli nie, zdarzenie wbudowane może wydawać się, że zrobi to samo, ale lepiej jest przygotować się na przyszłość, która - choć może wydawać się mało prawdopodobna - jest przynajmniej przewidywalna. Istnieje szansa, że ​​będziesz musiał przejść do nasłuchiwania zdarzeń opartych na JS, więc możesz po prostu zacząć od tego. Nie używaj wbudowanych zdarzeń.

jQuery i inne frameworki javascript hermetyzują różne implementacje przeglądarki poziomu DOM 2 zdarzeń w modelach ogólnych, dzięki czemu możesz pisać kod zgodny z różnymi przeglądarkami bez martwienia się o historię IE jako buntownika. Ten sam kod z jQuery, wszystkie przeglądarki i gotowe do działania:

$(element).on('click', function () { /* do stuff */ });

Jednak nie zabraknie i zdobędziesz ramy tylko dla tej jednej rzeczy. Możesz łatwo uruchomić własne małe narzędzie do obsługi starszych przeglądarek:

function addEvent(element, evnt, funct){
  if (element.attachEvent)
   return element.attachEvent('on'+evnt, funct);
  else
   return element.addEventListener(evnt, funct, false);
}

// example
addEvent(
    document.getElementById('myElement'),
    'click',
    function () { alert('hi!'); }
);

Wypróbuj: http://jsfiddle.net/bmArj/

Biorąc to wszystko pod uwagę, chyba że skrypt, na który patrzysz, wziąłby pod uwagę różnice w przeglądarce w inny sposób (w kodzie nie pokazanym w pytaniu), użycie części addEventListenernie działałoby w wersjach IE mniejszych niż 9.

Dokumentacja i powiązane czytanie

Chris Baker
źródło
14
przepraszam, że wpadłem, ale chciałem podać skondensowaną wersję twojej funkcji (skrzypce: jsfiddle.net/bmArj/153 ) -function addEvent(element, myEvent, fnc) { return ((element.attachEvent) ? element.attachEvent('on' + myEvent, fnc) : element.addEventListener(myEvent, fnc, false)); }
Deryck
10
@Gaurav_soni Nie. Nazwa funkcji i cały zawarty w niej kod są już ujawnione w pliku javascript, który jest w postaci zwykłego tekstu. Każdy może otworzyć konsolę internetową i wykonać dowolny skrypt javascript lub nim manipulować. Jeśli twój skrypt javascript zawiera coś, co może stanowić zagrożenie bezpieczeństwa, jeśli zostanie udostępniony publicznie, masz poważny problem, ponieważ jest już udostępniony publicznie.
Chris Baker
4
Tak długo, jak kondensujemy ten algorytm, równie dobrze możemy przejść cały proces: function addEvent(e,n,f){return e.attachEvent?e.attachEvent('on'+n,f):e.addEventListener(n,f,!!0)}<< Przy 98 znakach ten jest o ponad 40% mniejszy!
Trevor,
3
@ Trevor Z ciekawości, dlaczego !! 0? Dlaczego nie! 1 lub tylko 0?
Chris Baker
2
@AdrianMoisa Ta odpowiedź została napisana w czasach, gdy AngularJS był czymś nowym, a powszechną praktyką było wciąż „stopniowe ulepszanie” - to znaczy pisanie dokumentu HTML w sposób, który działałby z javascript lub bez niego. W tej perspektywie najlepszą praktyką byłyby wiążące zdarzenia z javascript. W dzisiejszych czasach nie sądzę, aby wiele osób martwiło się zbytnio postępowym ulepszaniem, szczególnie nie biorąc pod uwagę rozpowszechnienia takich rzeczy, jak Angular. Nadal istnieje pewna separacja wątpliwości dotyczących zdarzeń wbudowanych (nie przy użyciu Angulara), ale to więcej stylu niż treści.
Chris Baker
193

Różnica, którą można zobaczyć, gdybyś miał jeszcze kilka funkcji:

var h = document.getElementById('a');
h.onclick = doThing_1;
h.onclick = doThing_2;

h.addEventListener('click', doThing_3);
h.addEventListener('click', doThing_4);

Funkcje 2, 3 i 4 działają, ale 1 nie. Wynika to z faktu, addEventListenerże nie zastępuje istniejących procedur obsługi zdarzeń, a onclickzastępuje wszelkie istniejące onclick = fnprocedury obsługi zdarzeń.

Inną znaczącą różnicą jest to, że onclickzawsze będzie działać, podczas addEventListenergdy nie działa w Internet Explorerze przed wersją 9. Możesz użyć analogicznej attachEvent(która ma nieco inną składnię) w IE <9.

samotny dzień
źródło
18
To bardzo jasne wytłumaczenie! Prosto w sedno. Więc jeśli potrzebuję wielu funkcji dla jednego zdarzenia, utknąłem w addEventListener i muszę napisać więcej kodu dla attachEvent tylko po to, aby dostosować IE.
William Sham
4
2, 3 i 4 należy nazwać dosomething. 1 zostaje zastąpione przez 2 i nigdy nie jest wywoływane.
DragonLord
Rzeczywiście, bardzo jasne i rzeczowe wyjaśnienie. Niech tak naprawdę byłoby sensowniej nazwać funkcje „doThing_1” itp. (Jeśli nadal chcesz obsłużyć IE <9, zobacz odpowiedź Chrisa.)
Frank Conijn
61

W tej odpowiedzi opiszę trzy metody definiowania programów obsługi zdarzeń DOM.

element.addEventListener()

Przykład kodu:

element.addEventListener() ma wiele zalet:

  • Umożliwia rejestrowanie nieograniczonej liczby programów obsługi zdarzeń i usuwanie ich za pomocą element.removeEventListener().
  • Ma useCaptureparametr, który wskazuje, czy chcesz obsłużyć zdarzenie w fazie przechwytywania czy propagacji . Zobacz: Nie można zrozumieć atrybutu useCapture w addEventListener .
  • Dba o semantykę . Zasadniczo upraszcza rejestrowanie procedur obsługi zdarzeń. Dla początkującego wywołanie funkcji pokazuje, że coś się dzieje , podczas gdy przypisywanie zdarzenia do jakiejś właściwości elementu DOM nie jest co najmniej intuicyjne.
  • Pozwala oddzielić strukturę dokumentu (HTML) i logikę (JavaScript) . W małych aplikacjach internetowych może nie wydawać się to mieć znaczenia, ale ma to znaczenie przy każdym większym projekcie. O wiele łatwiej jest utrzymać projekt oddzielający strukturę i logikę niż projekt, który tego nie robi.
  • Eliminuje pomyłki z prawidłowymi nazwami zdarzeń. Ze względu na użycie wbudowanych detektorów zdarzeń lub przypisanie detektorów zdarzeń do .oneventwłaściwości elementów DOM, wielu niedoświadczonych programistów JavaScript uważa, że ​​nazwa zdarzenia to na przykład onclicklub onload. onto nie jest częścią nazwy zdarzenia . Prawidłowymi nazwami zdarzeń są clicki load, i tak przekazywane są nazwy zdarzeń .addEventListener().
  • Działa w prawie wszystkich przeglądarkach . Jeśli nadal musisz obsługiwać IE <= 8, możesz użyć wypełnienia z MDN .

element.onevent = function() {}(na przykład onclick, onload)

Przykład kodu:

Był to sposób na zarejestrowanie procedur obsługi zdarzeń w DOM 0. Jest to teraz odradzane, ponieważ:

  • Umożliwia zarejestrowanie tylko jednego modułu obsługi zdarzeń. Również usunięcie przypisanego modułu obsługi nie jest intuicyjne, ponieważ aby usunąć moduł obsługi zdarzeń przypisany za pomocą tej metody, należy przywrócić oneventwłaściwość do stanu początkowego (tj null.).
  • Nie reaguje odpowiednio na błędy . Na przykład, jeśli przez pomyłkę przypiszesz ciąg znaków window.onload, na przykład window.onload = "test";:, nie spowoduje to żadnych błędów. Twój kod nie działałby i naprawdę trudno byłoby dowiedzieć się, dlaczego. .addEventListener()wyrzuciłby jednak błąd (przynajmniej w Firefox): TypeError: Argument 2 EventTarget.addEventListener nie jest obiektem .
  • Nie zapewnia sposobu wyboru, czy chcesz obsłużyć zdarzenie w fazie przechwytywania lub propagacji.

Wbudowane moduły obsługi zdarzeń ( oneventatrybut HTML)

Przykład kodu:

Podobnie element.oneventjak teraz, jest to odradzane. Oprócz problemów element.onevent, które:

  • Jest potencjalnym problemem bezpieczeństwa , ponieważ powoduje, że XSS jest znacznie bardziej szkodliwy. W dzisiejszych czasach strony internetowe powinny wysyłać odpowiedni Content-Security-Policynagłówek HTTP, aby blokować wbudowane skrypty i zezwalać na skrypty zewnętrzne tylko z zaufanych domen. Zobacz, jak działa Polityka bezpieczeństwa treści?
  • Nie rozdziela struktury i logiki dokumentu .
  • Jeśli wygenerujesz swoją stronę za pomocą skryptu po stronie serwera, i na przykład wygenerujesz sto linków, z których każdy ma tę samą wbudowaną procedurę obsługi zdarzeń, kod będzie znacznie dłuższy niż w przypadku zdefiniowania procedury obsługi zdarzeń tylko raz. Oznacza to, że klient będzie musiał pobrać więcej treści, w wyniku czego Twoja strona będzie wolniejsza.

Zobacz też

Michał Perłakowski
źródło
22

Chociaż onclickdziała we wszystkich przeglądarkach, addEventListenernie działa w starszych wersjach programu Internet Explorer, którego używa attachEventzamiast tego.

Minusem onclickjest to, że może istnieć tylko jeden moduł obsługi zdarzeń, a pozostałe dwa będą wyzwalać wszystkie zarejestrowane wywołania zwrotne.

Magnar
źródło
12

O ile mi wiadomo, zdarzenie „load” DOM nadal działa tylko w bardzo ograniczonym zakresie. Oznacza to, że będzie to tylko na ogień window object, imagesa <script>elementy instancji. To samo dotyczy bezpośredniego onloadzadania. Nie ma technicznej różnicy między tymi dwoma. Prawdopodobnie .onload =ma lepszą dostępność w różnych przeglądarkach.

Jednak nie można przypisać load eventdo <div>lub <span>elementu lub etażerka.

jAndy
źródło
9

Podsumowanie:

  1. addEventListenermożna dodawać wiele zdarzeń, przy onclickczym nie można tego zrobić.
  2. onclickmożna dodać jako HTMLatrybut, podczas gdy addEventListenermożna dodać tylko w <script>elementach.
  3. addEventListener może przyjąć trzeci argument, który może zatrzymać propagację zdarzenia.

Oba mogą być używane do obsługi zdarzeń. Jednak addEventListenerpowinien być preferowanym wyborem, ponieważ może zrobić wszystko, co onclick robi i więcej. Nie używaj wbudowanych onclickjako atrybutów HTML, ponieważ mieszają one javascript i HTML, co jest złą praktyką. To sprawia, że ​​kod jest mniej konserwowalny.

Willem van der Veen
źródło
A w jaki sposób najczęściej wykonuje się celowanie z użyciem elementu? To znaczy, nie będę osobiście korzystać z onclickprzewodników w obawie przed wyśmiewaniem się z pokoju - ale zwykle wydarzenia w ostatnich latach są znacznie gorsze i mniej konserwatywne. Klasy podoba js-link, js-form-validationczy dane z atrybutów data-jspackage="init"nie jest w żaden sposób lepiej ... A jak ofteen czy rzeczywiście użyć pęcherzyków wydarzenie? Ja osobiście chciałbym móc napisać moduł obsługi bez sprawdzania, czy cel jest w rzeczywistości zgodny z moim elementem - lub konieczności zatrzymania propagacji w kilku miejscach z powodu przypadkowych błędów.
Christoffer Bubach,
3

Jeszcze jeden szczegół nie został zauważony: współczesne przeglądarki komputerowe uważają różne naciśnięcia przycisków za „kliknięcia” AddEventListener('click'i onclickdomyślnie.

  • W Chrome 42 i IE11, kliknij onclicki AddEventListenerstrzelaj lewym i środkowym kliknięciem.
  • W przeglądarce Firefox 38 onclickdziała tylko przy kliknięciu lewym przyciskiem, ale AddEventListenerkliknięcie przy lewym, środkowym i prawym kliknięciu.

Ponadto zachowanie kliknięcia środkowym przyciskiem jest bardzo niespójne w różnych przeglądarkach, gdy są włączone kursory przewijania:

  • W przeglądarce Firefox zdarzenia środkowego kliknięcia są zawsze uruchamiane.
  • W Chrome nie będą uruchamiane, jeśli kliknięcie środkowego przycisku otworzy lub zamknie kursor przewijania.
  • W IE są one uruchamiane po zamknięciu kursora przewijania, ale nie podczas otwierania.

Warto również zauważyć, że zdarzenia „kliknięcia” dla dowolnego elementu HTML wybieranego za pomocą klawiatury, takiego jak inputrównież strzelanie w spację lub wejście po wybraniu tego elementu.

gość
źródło
2

JavaScript zwykle łączy wszystko w obiekty, co może powodować zamieszanie. Wszystko w jednym to sposób JavaScript.

Zasadniczo onclick jest atrybutem HTML. Natomiast addEventListener to metoda na obiekcie DOM reprezentująca element HTML.

W obiektach JavaScript metoda jest jedynie właściwością, która ma funkcję jako wartość i działa przeciwko obiektowi, do którego jest dołączona (na przykład za pomocą tej metody).

W JavaScript jako element HTML reprezentowany przez DOM będzie miał przypisane atrybuty do jego właściwości.

Tutaj ludzie się mylą, ponieważ JavaScript łączy wszystko w jeden kontener lub przestrzeń nazw bez warstwy pośredniej.

W normalnym układzie OO (który przynajmniej łączy przestrzeń nazw właściwości / metod) możesz mieć coś takiego:

domElement.addEventListener // Object(Method)
domElement.attributes.onload // Object(Property(Object(Property(String))))

Istnieją różne warianty, w których można użyć gettera / settera dla onload lub HashMap dla atrybutów, ale ostatecznie tak to by wyglądało. JavaScript wyeliminował tę warstwę pośrednictwa, spodziewając się wiedzieć, co jest między innymi. Połączył domElement i atrybuty razem.

Z wyjątkiem kompatybilności powinieneś jako najlepszą praktykę użyć addEventListener. Gdy inne odpowiedzi mówią o różnicach w tym względzie, a nie o podstawowych różnicach programowych, zapomnę o tym. Zasadniczo w idealnym świecie, którego naprawdę chcesz używać tylko z * HTML, ale w jeszcze bardziej idealnym świecie nie powinieneś robić czegoś takiego z HTML.

Dlaczego dziś dominuje? Szybsze pisanie, łatwiejsze do nauczenia i zwykle działa.

Głównym celem onload w HTML jest przede wszystkim zapewnienie dostępu do metody lub funkcjonalności addEventListener. Używając go w JS, przechodzisz przez HTML, kiedy możesz zastosować go bezpośrednio.

Hipotetycznie możesz tworzyć własne atrybuty:

$('[myclick]').each(function(i, v) {
     v.addEventListener('click', function() {
         eval(v.myclick); // eval($(v).attr('myclick'));
     });
});

To, co robi JS, jest nieco inne.

Możesz to zrównać z czymś takim (dla każdego utworzonego elementu):

element.addEventListener('click', function() {
    switch(typeof element.onclick) {
          case 'string':eval(element.onclick);break;
          case 'function':element.onclick();break;
     }
});

Rzeczywiste szczegóły implementacji prawdopodobnie będą się różnić w zależności od szeregu subtelnych odmian, które w niektórych przypadkach będą nieco inne, ale to sedno.

Prawdopodobnie jest to hack kompatybilności, w którym można przypiąć funkcję do atrybutu on, ponieważ domyślnie wszystkie atrybuty są łańcuchami.

jgmjgm
źródło
2

Według MDN różnica jest następująca:

addEventListener:

Metoda EventTarget.addEventListener () dodaje określony obiekt zgodny z EventListener do listy detektorów zdarzeń dla określonego typu zdarzenia w EventTarget, na którym jest wywoływany. Obiektem docelowym zdarzenia może być element w dokumencie, sam dokument, okno lub dowolny inny obiekt obsługujący zdarzenia (na przykład XMLHttpRequest).

na kliknięcie:

Właściwość onclick zwraca kod obsługi zdarzenia kliknięcia dla bieżącego elementu. Korzystając ze zdarzenia kliknięcia do wyzwalania akcji, należy również rozważyć dodanie tej samej akcji do zdarzenia Keydown, aby umożliwić korzystanie z tej samej akcji przez osoby, które nie używają myszy ani ekranu dotykowego. Składnia element.onclick = functionRef; gdzie functionRef jest funkcją - często jest to nazwa funkcji zadeklarowanej gdzie indziej lub wyrażenie funkcji. Szczegółowe informacje można znaleźć w „Przewodniku JavaScript: funkcje”.

Istnieje również różnica w składni, jak widać w poniższych kodach:

addEventListener:

// Function to change the content of t2
function modifyText() {
  var t2 = document.getElementById("t2");
  if (t2.firstChild.nodeValue == "three") {
    t2.firstChild.nodeValue = "two";
  } else {
    t2.firstChild.nodeValue = "three";
  }
}

// add event listener to table
var el = document.getElementById("outside");
el.addEventListener("click", modifyText, false);

na kliknięcie:

function initElement() {
    var p = document.getElementById("foo");
    // NOTE: showAlert(); or showAlert(param); will NOT work here.
    // Must be a reference to a function name, not a function call.
    p.onclick = showAlert;
};

function showAlert(event) {
    alert("onclick Event detected!");
}
Alireza
źródło
1

Jeśli nie martwisz się zbytnio obsługą przeglądarki, istnieje sposób na ponowne powiązanie odwołania „this” w funkcji wywoływanej przez zdarzenie. Zwykle wskazuje element, który wygenerował zdarzenie, gdy funkcja jest wykonywana, co nie zawsze jest tym, czego chcesz. Problem polega na tym, aby jednocześnie móc usunąć ten sam detektor zdarzeń, jak pokazano w tym przykładzie: http://jsfiddle.net/roenbaeck/vBYu3/

/*
    Testing that the function returned from bind is rereferenceable, 
    such that it can be added and removed as an event listener.
*/
function MyImportantCalloutToYou(message, otherMessage) {
    // the following is necessary as calling bind again does 
    // not return the same function, so instead we replace the 
    // original function with the one bound to this instance
    this.swap = this.swap.bind(this); 
    this.element = document.createElement('div');
    this.element.addEventListener('click', this.swap, false);
    document.body.appendChild(this.element);
}
MyImportantCalloutToYou.prototype = {
    element: null,
    swap: function() {
        // now this function can be properly removed 
        this.element.removeEventListener('click', this.swap, false);           
    }
}

Powyższy kod działa dobrze w przeglądarce Chrome i prawdopodobnie istnieje pewien błąd w dostosowywaniu „wiązania” do innych przeglądarek.

Lars Rönnbäck
źródło
1

Korzystanie z wewnętrznych procedur obsługi jest niezgodne z Polityką bezpieczeństwa treści, więc addEventListenerpodejście jest bardziej bezpieczne z tego punktu widzenia. Oczywiście możesz włączyć wbudowane moduły obsługi, unsafe-inlineale, jak sama nazwa wskazuje, nie jest to bezpieczne, ponieważ przywraca całe hordy exploitów JavaScript, których CSP zapobiega.

kravietz
źródło
1
Uwaga: to ograniczenie bezpieczeństwa dotyczy tylko opracowywania rozszerzeń, a uzasadnienia bezpieczeństwa przedstawione w połączonym dokumencie dotyczą głównie opracowywania rozszerzeń przeglądarki. Jedną z kwestii wskazanych w połączonym dokumencie, która dotyczy również ogólnie tworzenia stron internetowych, jest oddzielenie treści od zachowania. To dobra praktyka we wszystkich dziedzinach.
Chris Baker
1

Powinno być także możliwe rozszerzenie nasłuchiwania przez prototypowanie go (jeśli mamy do niego odwołanie i nie jest to anonimowa funkcja) lub wywołanie wywołania „onclick” do biblioteki funkcji (funkcja wywołująca inne funkcje)

lubić

    elm.onclick = myFunctionList
    function myFunctionList(){
      myFunc1();
      myFunc2();
    }

oznacza to, że nigdy nie musimy przerywać wywołania onclick, po prostu zmieniamy funkcję myFunctionList (), aby robić to, co chcemy, ale to pozostawia nam kontrolę nad fazami propagacji / wychwytywania, więc należy tego unikać w nowszych przeglądarkach.

na wypadek, gdyby ktoś znalazł ten wątek w przyszłości ...

patrik
źródło
1

element.onclick = function () {/ * do stuff * /}

element.addEventListener ('click', function () {/ * do stuff * /}, false);

Najwyraźniej robią to samo: nasłuchują zdarzenia kliknięcia i wykonują funkcję zwrotną. Niemniej jednak nie są równoważne. Jeśli kiedykolwiek będziesz musiał wybrać jedną z tych dwóch opcji, może to pomóc w ustaleniu, który z nich jest dla Ciebie najlepszy.

Główna różnica polega na tym, że onclick jest tylko właściwością i podobnie jak wszystkie właściwości obiektu, jeśli napiszesz więcej niż jeden raz, zostanie on nadpisany . Zamiast tego za pomocą addEventListener () możemy po prostu powiązać moduł obsługi zdarzeń z elementem i wywołać go za każdym razem, gdy jest to potrzebne, bez obawy o nadpisanie właściwości. Przykład pokazano tutaj,

Spróbuj: https://jsfiddle.net/fjets5z4/5/

Przede wszystkim kusiło mnie, aby nadal używać onclick, ponieważ jest on krótszy i wygląda na prostszy… a tak naprawdę jest. Ale nie polecam już go używać. To tak jak przy użyciu wbudowanego JavaScript. Używanie czegoś takiego - to wbudowany JavaScript - jest obecnie bardzo odradzane (wbudowany CSS jest również odradzany, ale to inny temat).

Jednak funkcja addEventListener (), mimo że jest standardem, po prostu nie działa w starych przeglądarkach (Internet Explorer poniżej wersji 9), a to kolejna duża różnica. Jeśli potrzebujesz obsługi tych starożytnych przeglądarek, powinieneś podążać drogą kliknięcia. Ale możesz także użyć jQuery (lub jednej z jego alternatyw): w zasadzie upraszcza twoją pracę i zmniejsza różnice między przeglądarkami, dzięki czemu możesz zaoszczędzić dużo czasu.

var clickEvent = document.getElementByID("onclick-eg");
var EventListener = document.getElementByID("addEventListener-eg");

clickEvent.onclick = function(){
    window.alert("1 is not called")
}
clickEvent.onclick = function(){
    window.alert("2 is not called")
}

EventListener.addEventListener("click",function(){
    window.alert("1 is called")
})
EventListener.addEventListener("click",function(){
    window.alert("2 is also called")
})
Arham Chowdhury
źródło
0

addEventListener pozwala ustawić wiele programów obsługi, ale nie jest obsługiwany w IE8 lub starszej wersji.

IE ma attachEvent, ale nie jest dokładnie tak samo.

użytkownik113716
źródło
0

Kontekst, do którego odwołuje się 'this'słowo kluczowe w JavSript, jest inny.

spójrz na następujący kod:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>

</head>
<body>
    <input id="btnSubmit" type="button" value="Submit" />
    <script>
        function disable() {
            this.disabled = true;
        }
        var btnSubmit = document.getElementById('btnSubmit');
        btnSubmit.onclick = disable();
        //btnSubmit.addEventListener('click', disable, false);
    </script>
</body>
</html>

To, co robi, jest naprawdę proste. po kliknięciu przycisku przycisk zostanie automatycznie wyłączony.

Najpierw, gdy spróbujesz podłączyć zdarzenia w ten sposób, button.onclick = function(), zdarzenie onclick zostanie uruchomione przez kliknięcie przycisku, jednak przycisk nie zostanie wyłączony, ponieważ nie ma wyraźnego powiązania między button.onclick a modułem obsługi zdarzeń onclick. Jeśli debugujesz, zobaczysz 'this'obiekt, możesz zobaczyć, że odnosi się on do 'window'obiektu.

Po drugie, jeśli komentujesz btnSubmit.onclick = disable();i odkomentujesz //btnSubmit.addEventListener('click', disable, false);, możesz zobaczyć, że przycisk jest wyłączony, ponieważ w ten sposób istnieje wyraźne powiązanie między zdarzeniem button.onclick a modułem obsługi zdarzeń onclick. Jeśli debugujesz w celu wyłączenia funkcji, zobaczysz, że 'this'odnosi się button controlraczej do niżwindow .

Jest to coś, co nie podoba mi się w JavaScript, co jest niespójnością. Btw, jeśli używasz jQuery ( $('#btnSubmit').on('click', disable);), używa jawnego wiązania.

Larry
źródło
8
Musisz napisać btnSubmit.onclick = disable;(przypisać funkcję, a nie wywoływać). W obu przypadkach thisbędzie się odnosić do elementu przycisku.
Pasha
-1

onclick to w zasadzie addEventListener, który w szczególności wykonuje funkcję po kliknięciu elementu. Przydatne, gdy masz przycisk, który wykonuje proste operacje, takie jak przycisk kalkulatora. addEventlistener może być używany do wielu rzeczy, takich jak wykonywanie operacji po załadowaniu DOM lub całej zawartości, podobnie jak window.onload, ale z większą kontrolą.

Uwaga: Możesz użyć więcej niż jednego zdarzenia z wbudowanym lub przynajmniej za pomocą onclick, oddzielając każdą funkcję średnikiem, tak jak to ...

Nie napisałbym funkcji z wbudowanym, ponieważ potencjalnie możesz mieć później problemy i byłoby to niechlujne imo. Wystarczy użyć go do wywołania funkcji już wykonanych w pliku skryptu.

Który z nich użyjesz, zależy od tego, czego chcesz. addEventListener do złożonych operacji i onclick dla prostych. Widziałem, że niektóre projekty nie dołączały określonego elementu do elementów i zamiast tego wdrażałyby bardziej globalny program do listy zdarzeń, który określałby, czy stuknięcie w przycisk i wykonuje określone zadania w zależności od tego, co zostało naciśnięte. Imo, które mogłoby potencjalnie prowadzić do problemów, które - jak sądzę - byłyby marnotrawstwem zasobów, gdyby ten słuchacz zdarzeń musiał obsługiwać każde kliknięcie

ThatOneNoob
źródło