addEventListener vs onclick


705

Arasındaki fark nedir addEventListenerve onclick?

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

Yukarıdaki kod ayrı bir .js dosyasında birlikte bulunur ve her ikisi de mükemmel çalışır.

Yanıtlar:


959

Her ikisi de doğrudur, ancak hiçbiri kendi başına "en iyi" değildir ve geliştiricinin her iki yaklaşımı kullanmayı seçmesinin bir nedeni olabilir.

Olay Dinleyicileri (addEventListener ve IE'nin attachEvent)

Internet Explorer'ın önceki sürümleri javascript'i hemen hemen her tarayıcıdan farklı olarak uygular. 9'dan küçük sürümlerde, attachEvent[ doc ] yöntemini kullanırsınız, şöyle:

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

Diğer tarayıcıların çoğunda (IE 9 ve üstü dahil) şu şekilde addEventListener[ doc ] kullanırsınız :

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

Bu yaklaşımı kullanarak ( DOM Level 2 olayları ), herhangi bir öğeye teorik olarak sınırsız sayıda olay ekleyebilirsiniz. Tek pratik sınırlama, her tarayıcı için farklı olan istemci tarafı bellek ve diğer performans endişeleridir.

Yukarıdaki örnekler anonim bir fonksiyonun [ doc ] kullanımını temsil etmektedir . Ayrıca bir işlev başvurusu [ doc ] veya bir kapatma [ doc ] kullanarak bir olay dinleyicisi ekleyebilirsiniz :

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

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

Diğer bir önemli özelliği addEventListenerde dinleyicinin köpüren olaylara nasıl tepki vereceğini kontrol eden son parametredir [ doc ]. Kullanım örneklerinin muhtemelen% 95'i için standart olan örneklerde yanlış geçiyorum. İçin eşdeğer bir argüman yokattachEventSatır içi olaylar veya satır içi etkinlikler kullanılırken .

Satır içi etkinlikler (HTML onclick = "" özellik ve element.onclick)

Javascript'i destekleyen tüm tarayıcılarda, doğrudan HTML koduna yani bir olay dinleyicisini satır içine koyabilirsiniz. Muhtemelen bunu gördünüz:

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

Çoğu deneyimli geliştirici bu yöntemi reddetmektedir, ancak işi bitirmektedir; basit ve doğrudan. Burada kapatmaları veya anonim işlevleri kullanamazsınız (işleyicinin kendisi bir tür anonim işlev olsa da) ve kapsam denetiminiz sınırlıdır.

Bahsettiğiniz diğer yöntem:

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

... (HTML yerine bir komut dosyası yazdığınız için) kapsam üzerinde daha fazla denetime sahip olmanız ve anonim işlevler, işlev başvuruları ve / veya kapaklar kullanabilmeniz dışında satır içi javascript'in eşdeğeridir.

Satır içi etkinliklerle ilgili önemli dezavantaj, yukarıda açıklanan olay dinleyicilerinin aksine, yalnızca bir satır içi etkinliğe atanmış olabilmenizdir. Satır içi olaylar, [ doc ] öğesinin bir niteliği / özelliği olarak saklanır , yani üzerine yazılabilir.

<a>Yukarıdaki HTML'deki örneği kullanarak :

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

... öğeyi tıkladığınızda, yalnızca "2 numaralı öğe mi?" ifadesini görürsünüz - onclickmülkün ilk atanmışının üzerine ikinci değer yazdınız ve orijinal satır içi HTML onclicközelliğinin üzerine yazdınız . Buradan kontrol edin: http://jsfiddle.net/jpgah/ .

Genel olarak, satır içi olayları kullanmayın . Bunun için özel kullanım durumları olabilir, ancak bu kullanım örneğine sahip olduğunuzdan% 100 emin değilseniz, satır içi etkinlikleri kullanmazsınız ve kullanmamalısınız.

Modern Javascript (Açısal ve benzeri)

Bu cevap ilk olarak gönderildiğinden, Angular gibi javascript çerçeveleri çok daha popüler hale geldi. Açısal bir şablonda şöyle bir kod göreceksiniz:

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

Bu satır içi bir etkinliğe benziyor, ancak değil. Bu şablon türü, sahne arkasındaki olay dinleyicilerini kullanan daha karmaşık bir koda aktarılacaktır. Buradaki olaylar hakkında yazdığım her şey hala geçerlidir, ancak en az bir katman tarafından nitrit cesurdan çıkarılırsınız. Somunları ve cıvataları anlamalısınız, ancak modern JS çerçeve en iyi uygulamalarınız bu tür bir kodu bir şablonda yazmayı içeriyorsa, bir satır içi etkinlik kullanıyormuş gibi hissetmeyin - değilsiniz.

Hangisi en iyi?

Soru, tarayıcı uyumluluğu ve gerekliliği meselesidir. Bir öğeye birden fazla etkinlik eklemeniz mi gerekiyor? Gelecekte olacak mısın? Oranlar, yapacaksın. attachEvent ve addEventListener gereklidir. Değilse, bir satır içi olay hile yapacak gibi görünebilir, ancak olası görünmese de, en azından tahmin edilebilir bir gelecek için hazırlanmaktan çok daha iyi hizmet ediyorsunuz. JS tabanlı olay dinleyicilerine taşınmanız için bir şans var, bu yüzden oradan başlayabilirsiniz. Satır içi etkinlikleri kullanmayın.

jQuery ve diğer javascript çerçeveleri, genel modellerdeki DOM düzey 2 olaylarının farklı tarayıcı uygulamalarını kapsamaktadır, böylece IE'nin isyancı geçmişi hakkında endişelenmenize gerek kalmadan tarayıcılar arası uyumlu kod yazabilirsiniz. JQuery ile aynı kod, tüm çapraz tarayıcı ve sallanmaya hazır:

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

Yine de bu tek şey için bitip bir çerçeve almayın. Eski tarayıcılarla ilgilenmek için kendi küçük yardımcı programınızı kolayca döndürebilirsiniz:

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!'); }
);

Deneyin: http://jsfiddle.net/bmArj/

Tüm bunları göz önünde bulundurarak, baktığınız komut dosyası tarayıcı farklılıklarını başka bir şekilde dikkate almadığı sürece (sorunuzda gösterilmeyen kodda), kullanılan bölüm addEventListener9'dan az IE sürümlerinde çalışmaz.

Dokümantasyon ve İlgili Okuma


14
çarptığım için üzgünüm ama sadece fonksiyonunun kısaltılmış bir versiyonunu vermek istedim (keman: 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 Hayır. İşlevin adı ve içerdiği tüm kod, düz metin olan javascript dosyasında zaten açıklanmıştır. Herkes bir web konsolu açabilir ve herhangi bir javascript'i çalıştırabilir veya değiştirebilir. Javascriptiniz halka maruz kaldığında güvenlik riski olabilecek bir şey içeriyorsa, zaten halka maruz kaldığı için büyük bir sorununuz var demektir.
Chris Baker

4
Bu algoritmayı yoğunlaştırdığımız sürece, sonuna kadar gidebiliriz: function addEvent(e,n,f){return e.attachEvent?e.attachEvent('on'+n,f):e.addEventListener(n,f,!!0)}<< 98 karakterde, bu% 40'tan daha küçük!
Trevor

3
@Trevor Meraktan, neden !! 0? Neden olmasın! 1 ya da sadece 0?
Chris Baker

2
@AdrianMoisa Bu cevap, AngularJS'nin yükselişte yeni bir şey olduğu ve ortak uygulamanın hala "aşamalı iyileştirme" olduğu, yani javascript ile veya javascript olmadan çalışacak bir HTML belgesi yazdığı bir zamanda yazılmıştır. Bu açıdan bakıldığında, javascript'ten bağlayıcı olaylar en iyi yöntem olacaktır. Günümüzde, pek çok insanın ilerici gelişme konusunda çok fazla endişe ettiğini düşünmüyorum, özellikle de Angular gibi şeylerin yaygınlığını düşünmüyorum. Hâlâ satır içi olaylarla ilgili endişe argümanlarının bir kısmı birbirinden ayrılıyor (Açısal kullanmıyor), ama bu maddeden çok daha fazla stil.
Chris Baker

193

Başka bir işleviniz olup olmadığını görebileceğiniz fark:

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

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

İşlev 2, 3 ve 4 çalışıyor, ancak 1 çalışmıyor. Bunun nedeni addEventListener, mevcut olay işleyicilerinin üzerine yazmazken, mevcut olay işleyicilerini onclickgeçersiz kılmasıdıronclick = fn .

Diğer önemli fark, elbette, onclickher zaman işe yarayacaktır, oysa addEventListenerInternet Explorer'da sürüm 9'dan önce çalışmaz . IE <9'da benzer attachEvent( biraz farklı sözdizimi olan) kullanabilirsiniz.


18
Bu çok açık bir açıklama! Doğru noktaya. Yani bir olay için birden fazla işlev gerekiyorsa, ben addEventListener ile sıkışmış ve sadece IE karşılamak için attachEvent için daha fazla kod yazmak zorunda.
William Sham

4
2, 3 ve 4 doz olarak adlandırılmalıdır. 1, 2 tarafından geçersiz kılınır ve hiçbir zaman çağrılmaz.
DragonLord

Gerçekten çok açık ve net bir açıklama. Gerçekten vb işlevlerin doThing_1 'isim daha mantıklı olurdu o kadar Be (IE'deki <9 hitap etmek istiyorsanız, Chris'in cevaba bakınız.)
Frank Conijn

61

Bu cevapta DOM olay işleyicilerini tanımlamanın üç yöntemini anlatacağım.

element.addEventListener()

Kod örneği:

element.addEventListener() birden fazla avantajı vardır:

  • Sınırsız olay işleyicilerini kaydetmenizi ve ile kaldırmanızı sağlar element.removeEventListener().
  • useCaptureOlayı yakalama veya köpürme aşamasında işlemek isteyip istemediğinizi belirten Has parametresi . Bkz . AddEventListener'daki useCapture özniteliği anlaşılamıyor .
  • Hakkında Bakımlar semantik . Temel olarak, olay işleyicilerini kaydettirmeyi daha açık hale getirir. Yeni başlayanlar için, bir işlev çağrısı, bir şeyin gerçekleştiğini açıkça gösterirken , DOM öğesinin bazı özelliklerine olay atamak en azından sezgisel değildir.
  • Belge yapısını (HTML) ve mantığı (JavaScript) ayırmanıza olanak tanır . Minik web uygulamaları yılında önemli değildi, ama bu does herhangi büyük bir projenin nesi. Yapıyı ve mantığı ayıran bir projeyi sürdürmek, yapmayan bir projeden çok daha kolaydır.
  • Doğru olay adlarıyla karışıklığı ortadan kaldırır. Satır içi olay dinleyicileri kullanması veya .oneventDOM öğelerinin özelliklerine olay dinleyicileri ataması nedeniyle , birçok deneyimsiz JavaScript programcısı, etkinlik adının örneğin onclickveya olduğunu düşünür onload. onolduğu değil olay adının bir parçası . Doğru olay adlarıdır clickve loadolay adları bu şekilde aktarılır .addEventListener().
  • Çalışıyor neredeyse tüm tarayıcısı . Hala IE <= 8'i desteklemeniz gerekiyorsa, MDN'den bir çoklu dolgu kullanabilirsiniz .

element.onevent = function() {}(ör onclick. onload)

Kod örneği:

Bu, DOM 0'da olay işleyicilerini kaydetmenin bir yoluydu. Artık önerilmez, çünkü:

  • Yalnızca bir olay işleyici kaydetmenizi sağlar . Ayrıca, atanmış işleyiciyi kaldırmak sezgisel değildir, çünkü bu yöntem kullanılarak atanan olay işleyicisini kaldırmak için oneventözelliği ilk durumuna (yani null) geri döndürmeniz gerekir .
  • Hatalara uygun yanıt vermiyor . Örneğin, yanlışlıkla bir dize atarsanız, window.onloadörneğin:, window.onload = "test";herhangi bir hata atmaz. Kodunuz işe yaramaz ve nedenini bulmak gerçekten zor olur. .addEventListener()ancak, hata verir (en azından Firefox'ta): TypeError: EventTarget.addEventListener öğesinin Argument 2 nesnesi değildir .
  • Olayı yakalama veya köpürme aşamasında işlemek isteyip istemediğinizi seçmenin bir yolunu sağlamaz.

Satır içi olay işleyicileri ( oneventHTML özelliği)

Kod örneği:

Benzer şekilde element.onevent, şimdi önerilmez. Sahip olduğu konuların yanı sıra element.onevent:

  • Bir mi potansiyel güvenlik sorunu XSS çok daha zararlı hale getirir, çünkü. Günümüzde web siteleri, Content-Security-Policysatır içi komut dosyalarını engellemek ve yalnızca güvenilen etki alanlarından dış komut dosyalarına izin vermek için uygun HTTP üstbilgisi göndermelidir . Görmek Nasıl İçerik Güvenlik Politikası çalışır?
  • Does not belge yapısını ve mantığını ayırmak .
  • Sayfanızı bir sunucu tarafı komut dosyasıyla oluşturursanız ve örneğin her biri aynı satır içi olay işleyicisine sahip yüz bağlantı oluşturursanız, kodunuz, olay işleyicisinin yalnızca bir kez tanımlanmasından çok daha uzun olur. Bu, müşterinin daha fazla içerik indirmek zorunda kalacağı ve sonuç olarak web sitenizin daha yavaş olacağı anlamına gelir.

Ayrıca bakınız


22

İken onclicktüm tarayıcılarda eserler, addEventListenerkullandığı Internet Explorer'ın eski sürümlerinde çalışmaz attachEventyerine.

Bunun dezavantajı, onclickyalnızca bir olay işleyici olabileceği, diğer ikisi de kayıtlı tüm geri çağrıları tetikleyeceğidir.


12

Bildiğim kadarıyla, DOM "load" olayı hala çok sınırlı çalışıyor. Araçlarla Yani sadece ateş edeceğiz window object, imagesve <script>örneğin unsurları. Aynı şey doğrudan onloadatama için de geçerlidir . Bu ikisi arasında teknik bir fark yoktur. Muhtemelen.onload = daha iyi bir tarayıcılar arası kullanılabilirliğe sahiptir.

Ancak, load eventa <div>veya <span>öğeye a veya başka bir şey atayamazsınız .


9

Özet:

  1. addEventListenerbirden fazla etkinlik ekleyebilir, bununla birlikte onclickgerçekleştirilemez.
  2. onclickbir HTMLözellik olarak eklenebilirken, bir addEventListeneryalnızca <script>öğeler içine eklenebilir .
  3. addEventListener olay yayılımını durdurabilecek üçüncü bir argüman alabilir.

Her ikisi de olayları işlemek için kullanılabilir. Ancak, addEventListenerher şeyi onclick ve daha fazlasını yapabileceği için tercih edilen seçenek olmalıdır . onclickJavascript ve kötü bir uygulama olan HTML'yi karıştırdığı için satır içi HTML özellikleri olarak kullanmayın . Kodu daha az bakım yapılabilir hale getirir.


Ee öğe hedeflemesi daha çok nasıl yapılır? Demek istediğim, kişisel olarak onclickodadan gülülme korkusu ile inline handlr'leri kullanmayacağım - ancak son yıllarda olaylar çok daha kötü ve daha az bakım yoluyla bağlanıyor. Sınıflar gibi js-link, js-form-validationya da veri özelliklerini data-jspackage="init"daha iyi hiçbir şekilde ... Ve nasıl ofteen aslında do kullanmak olay baloncuklanmasını? Ben şahsen, hedefin öğemle eşleşip eşleşmediğini kontrol etmeden - veya rastgele hatalar nedeniyle çeşitli yerlerde yayılmayı durdurmak zorunda kalmadan bir işleyici yazabilmek isterdim.
Christoffer Bubach

3

Bir ayrıntı henüz kaydedilmedi: Modern masaüstü tarayıcıları, farklı düğme basmalarının varsayılan olarak AddEventListener('click've "tıklamalar" olduğunu düşünüyor onclick.

  • Chrome 42 ve IE11, hem On onclickve AddEventListenersol ve orta tıklama yangın tıklayın.
  • Firefox 38 günü, onclickateşler sadece sol tıklama, ama AddEventListenersol, orta yangınları tıklayın ve sağ tıklama.

Ayrıca, kaydırma imleçleri söz konusu olduğunda , orta tıklama davranışı tarayıcılarda çok tutarsızdır:

  • Firefox'ta, orta tıklama etkinlikleri her zaman tetiklenir.
  • Chrome'da, aracı tıklayıp bir kaydırma imlecini açar veya kapatırsa tetiklenmezler.
  • IE'de kaydırma imleci kapandığında ateş ederler, ancak açıldığında ateş etmezler.

Ayrıca, inputboşlukta ateş etme veya öğe seçildiğinde girme gibi klavye tarafından seçilebilen herhangi bir HTML öğesi için "tıklama" olaylarının da belirtilmesi önemlidir.


2

Javascript her şeyi nesnelerle harmanlama eğilimindedir ve bu kafa karıştırıcı olabilir. Hepsi bir arada JavaScript yoludur.

Aslında onclick bir HTML özelliğidir. Buna karşılık addEventListener, DOM nesnesinde bir HTML öğesini temsil eden bir yöntemdir.

JavaScript nesnelerinde, yöntem yalnızca değer olarak işlevi olan ve bağlı olduğu nesneye karşı çalışan bir özelliktir (örneğin bunu kullanarak).

JavaScript'te DOM tarafından temsil edilen HTML öğesi, özellikleriyle eşleştirilir.

JavaScript'in her şeyi dolaylı bir katman olmadan tek bir kapsayıcıya veya ad alanına dönüştürdüğü için insanların kafası karışır.

Normal bir OO mizanpajında ​​(en azından özelliklerin / yöntemlerin ad alanını birleştiren) aşağıdaki gibi bir şeye sahip olabilirsiniz:

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

Onload için bir alıcı / ayarlayıcı veya öznitelikler için HashMap kullanabileceği gibi varyasyonlar vardır, ancak nihayetinde böyle görünecektir. JavaScript, diğer şeylerin arasında ne olduğunu bilme beklentisiyle bu dolaylı katmanı ortadan kaldırdı. DomElement ile nitelikleri birleştirdi.

En iyi uygulama olarak addEventListener kullanmanız gerekir. Diğer cevaplar, temel programatik farklılıklardan ziyade bu konudaki farklılıklar hakkında konuştuğundan, onu bırakacağım. Temel olarak, ideal bir dünyada gerçekten sadece HTML'den * kullanmanız gerekiyordu, ancak daha ideal bir dünyada HTML'den böyle bir şey yapmamalısınız.

Bugün neden baskın? Yazmak daha hızlı, öğrenmesi daha kolay ve sadece çalışma eğiliminde.

HTML'deki tüm yükleme noktası, ilk etapta addEventListener yöntemine veya işlevselliğine erişim vermektir. JS'de kullanarak, doğrudan uygulayabildiğiniz zaman HTML'den geçersiniz.

Varsayımsal olarak kendi niteliklerinizi oluşturabilirsiniz:

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

JS'nin yaptığı, bundan biraz farklı.

Bunu aşağıdaki gibi bir şeye eşitleyebilirsiniz (oluşturulan her öğe için):

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

Gerçek uygulama ayrıntıları, bazı durumlarda ikisini biraz farklı kılan bir dizi ince varyasyonla muhtemelen farklılık gösterecektir, ancak bunun özü budur.

Varsayılan özelliklerin tümü dizeler olduğu için bir işlevi bir özniteliğe sabitleyebileceğiniz bir uyumluluk hackidir.


2

MDN'ye göre , fark aşağıdaki gibidir:

addEventListener:

EventTarget.addEventListener () yöntemi, belirtilen EventListener uyumlu nesneyi, çağrıldığı EventTarget'ta belirtilen olay türü için olay dinleyicileri listesine ekler. Olay hedefi bir belgedeki bir Öğe, Belgenin kendisi, bir Pencere veya olayları destekleyen herhangi bir nesne (XMLHttpRequest gibi) olabilir.

tıklamada:

Onclick özelliği, geçerli öğedeki click event handler kodunu döndürür. Bir eylemi tetiklemek için click olayını kullanırken, aynı eylemi fare veya dokunmatik ekran kullanmayan kişiler tarafından kullanılmasına izin vermek için aynı eylemi keydown olayına eklemeyi de düşünün. Sözdizimi element.onclick = functionRef; Burada functionRef bir işlevdir - genellikle başka bir yerde bildirilen bir işlevin veya işlev ifadesinin adı. Ayrıntılar için bkz. "JavaScript Kılavuzu: İşlevler".

Ayrıca, aşağıdaki kodlarda gördüğünüz gibi bir sözdizimi farkı vardır:

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);

tıklamada:

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!");
}

1

Tarayıcı desteği konusunda fazla endişelenmiyorsanız, olayın çağırdığı işlevdeki 'bu' referansı yeniden hatırlamanın bir yolu vardır. Normalde, işlev yürütüldüğünde olayı oluşturan öğeye işaret eder, bu da her zaman istediğiniz şey değildir. Zor kısım aynı zamanda, bu örnekte gösterildiği gibi aynı olay dinleyicisini kaldırabilmektir: 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);           
    }
}

Yukarıdaki kod Chrome'da iyi çalışıyor ve muhtemelen "bağlama" yı diğer tarayıcılarla uyumlu hale getirme konusunda biraz şim var.


1

Satır içi işleyicileri kullanmak İçerik Güvenliği İlkesi ile uyumsuz olduğundan addEventListeneryaklaşım bu açıdan daha güvenlidir. Tabii ki satır içi işleyicileri ile etkinleştirebilirsiniz, unsafe-inlineancak adından da anlaşılacağı gibi, CSP'nin önlediği tüm JavaScript istismarlarını geri getirdiği için güvenli değildir.


1
Not: Bu güvenlik kısıtlaması yalnızca uzantı geliştirme için geçerlidir ve bağlantılı belgede sunulan güvenlik gerekçeleri büyük ölçüde yalnızca tarayıcı uzantısı geliştirme için geçerlidir. Bununla birlikte, genel olarak web geliştirme için de geçerli olan bağlantılı belgede yapılan bir nokta, içeriği davranıştan ayırmaktır. Bu iyi bir uygulama.
Chris Baker

1

Dinleyiciyi prototip oluşturarak genişletmek de mümkün olmalıdır (eğer bir referansımız varsa ve anonim bir işlevi yoksa) -veya 'onclick' çağrısını bir fonksiyon kütüphanesine çağırın (diğer fonksiyonları çağıran bir fonksiyon)

sevmek

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

Bu, onclick çağrısını asla chenge etmemiz gerektiği anlamına gelir, sadece istediğimiz şeyi yapmak için myFunctionList () işlevini değiştiririz, ancak bu, köpürme / yakalama aşamalarının kontrolü olmadan bizi terk eder, bu nedenle yeni tarayıcılar için kaçınılmalıdır.

Birisinin bu konuyu gelecekte bulması durumunda ...


1

element.onclick = function () {/ * şeyler yap * /}

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

Görünüşe göre aynı şeyi yapıyorlar: click olayını dinleyin ve bir geri arama işlevi yürütün. Bununla birlikte, eşdeğer değildirler. İkisi arasında seçim yapmanız gerekirse, bu hangisinin sizin için en iyi olduğunu bulmanıza yardımcı olabilir.

Temel fark, onclick öğesinin sadece bir özellik olması ve tüm nesne özellikleri gibi, birden fazla kez yazarsanız, üzerine yazılır . Bunun yerine addEventListener () ile , bir olay işleyicisini öğeye bağlayabiliriz ve üzerine yazdığımız özelliklerden endişe duymadan, ihtiyaç duyduğumuz her an onu çağırabiliriz. Örnek burada gösterilmektedir,

Deneyin: https://jsfiddle.net/fjets5z4/5/

İlk etapta onclick kullanmaya devam etmeye cazip geldim, çünkü daha kısa ve daha basit görünüyor… ve aslında öyle. Ama artık kullanmanızı önermiyorum. Tıpkı satır içi JavaScript kullanmak gibidir. Günümüzde satır içi JavaScript gibi bir şey kullanmak son derece cesaret kırılmıştır (satır içi CSS de önerilmez, ancak bu başka bir konudur).

Ancak, addEventListener () işlevi, standart olmasına rağmen, eski tarayıcılarda (sürüm 9'un altındaki Internet Explorer) çalışmaz ve bu da büyük bir farktır. Bu eski tarayıcıları desteklemeniz gerekiyorsa, tıklamanız gerekir. Ancak jQuery (veya alternatiflerinden birini) de kullanabilirsiniz: temel olarak çalışmanızı basitleştirir ve tarayıcılar arasındaki farkları azaltır, bu nedenle size çok zaman kazandırabilir.

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")
})

0

addEventListener birden çok işleyici ayarlamanızı sağlar, ancak IE8 veya daha düşük sürümlerde desteklenmez.

IE var attachEvent, ama tam olarak aynı değil.


0

Tarafından referans verilen bağlam 'this'JavasSript içindeki anahtar kelime farklı.

aşağıdaki koda bakın:

<!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>

Yaptığı şey gerçekten basit. düğmesine tıkladığınızda, düğme otomatik olarak devre dışı bırakılır.

İlk olarak olayları bu şekilde button.onclick = function(), bağlamaya çalıştığınızda, onclick olayı düğmesine tıklanarak tetiklenir, ancak button.onclick ve onclick olay işleyicisi arasında açık bir bağ olmadığı için düğme devre dışı bırakılmaz. 'this'Nesnede hata ayıklama yaparsanız, nesneye atıfta bulunduğunu görebilirsiniz 'window'.

İkinci olarak, yorum yapar btnSubmit.onclick = disable();ve yorum kaldırırsanız //btnSubmit.addEventListener('click', disable, false);, düğmenin devre dışı bırakıldığını görebilirsiniz çünkü bu şekilde button.onclick olayı ve onclick olay işleyicisi arasında açık bir bağ vardır. Devre dışı bırakma işlevinde hata ayıklarsanız 'this', button controlyerine değil ifadesini görebilirsiniz window.

Bu JavaScript hakkında sevmediğim bir tutarsızlık. Btw, jQuery ( $('#btnSubmit').on('click', disable);) kullanıyorsanız, açık bağlama kullanır.


8
Yazmanız gerekiyor btnSubmit.onclick = disable;(işlevi ata, çağır değil). Sonra her iki durumda thisda düğme öğesine atıfta bulunulur.
Paşa

-1

onclick temel olarak, öğe tıklandığında özel olarak bir işlev gerçekleştiren bir addEventListener'dır. Bu nedenle, hesap makinesi düğmesi gibi basit işlemler yapan bir düğmeniz olduğunda kullanışlıdır. addEventlistener, DOM veya tüm içerik yüklendiğinde, window.onload'a benzer ancak daha fazla kontrole sahip bir işlem gerçekleştirmek gibi birçok şey için kullanılabilir.

Not, aslında satır içi ile birden fazla olay kullanabilirsiniz, ya da en azından onclick kullanarak her işlevi, bir noktalı virgül ile ayırarak, gibi ....

Daha sonra potansiyel olarak sorun yaşayabileceğiniz ve dağınık imo olacağı için satır içi bir işlev yazmam. Sadece komut dosyanızda zaten yapılmış işlevleri çağırmak için kullanın.

Hangisini kullandığınızı istediğinize bağlı olacaktır. karmaşık işlemler için addEventListener ve basit için tıklayın. Bazı projelerin öğelere belirli bir tane eklemediğini gördüm ve bunun yerine bir musluğun bir düğmeye basıp basmadığını belirleyen ve basılana bağlı olarak belirli görevleri gerçekleştiren daha global bir olay listeleyicisi uygulayacağımı gördüm. Potansiyel olarak düşündüğüm sorunlara yol açabilecek Imo ve küçük olsa da, muhtemelen o olay dinleyicisi her tıklamayı ele alması gerekiyorsa bir kaynak kaybı

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.