JavaScript onclick Není tak špatný, jak se říká Dovolte mi to dokázat!

Upozornění!

Dokumenty MDN doporučují addEventListener místo onclick následovně.

Říká,

Zní to jako odrazující prohlášení o použití onclick . Nicméně onclick může konkurovat addEventListener z větší části.

Abychom to dokázali, uvažujme následující jednoduchý program.

Existuje dítě button prvek a jeho nadřazený div živel. A existuje funkce s názvem vypočítat použít jako obsluhu události při button klikne.

HTML
<div id="container">

 <button id="btn-add">Add</button>

</div>

onclick Funguje dobře pro následující případy použití

1. Delegování událostí (více prvků – jeden ovladač)

Pomocí delegování události můžeme přidat jednu obslužnou rutinu události pouze pro nadřazený prvek a rozpoznat aktuální podřízený prvek, na kterém došlo k události kliknutí, pomocí event.target.matches() .

let container = document.querySelector('#container');
let addBtn = document.querySelector('#btn-add');

let num1 = 6;
let num2 = 2;
let result = 0;

function calculate(e) {  
    if(e.target && e.target.matches('#btn-add')) {
      result += num1 + num2;
      console.log(`result: ${result}`);
    }    
}

Delegování události – addEventListener

//addEventListener
container.addEventListener('click', calculate);

// output after clicking the button 3 times.
/*
"result: 8"
"result: 16"
"result: 24"
*/

Delegování události – onclick

//onclick
container.onclick = calculate;

// output after clicking the button 3 times.
/*
"result: 8"
"result: 16"
"result: 24"
*/

2. Probublávání a zachycení události

Předpokládám, že nebudu vysvětlovat bublání a zachycování tady. Je však dobré zmínit, že událost bublání je výchozím chováním téměř každého moderního prohlížeče.

addEventListener má možnost použít probublávání událostí nebo zachycení a je celkem jasné, že s onclick taková možnost neexistuje pro fázi zachycení.


let container = document.querySelector('#container');
let addBtn = document.querySelector('#btn-add');

let num1 = 6;
let num2 = 2;
let result = 0;

function calculate(e) {
  result += num1 + num2;
  console.log(`calculated result: ${result}`);
}

Nejprve načteme vypočítaný výsledek pomocí obsluhy události button .

A pak zobrazte výsledek na div jako aktuální výsledek .

Probublávání v tomto případě funguje dobře pro obě onclick a addEventListener .

Bublinkování – addEventListener

// addEventListener - bubbling
// display current result after calculating 

container.addEventListener('click', function() {
  console.log(`current result: ${result}`);
});

addBtn.addEventListener('click', calculate);

// output after clicking the button 3 times.
/*
"calculated result: 8"
"current result: 8"
"calculated result: 16"
"current result: 16"
"calculated result: 24"
"current result: 24"
*/

Probublávání – onclick

// onclick - bubbling
// display current result after calculating 

container.onclick = function() {
  console.log(`current result: ${result}`);
}

addBtn.onclick = calculate;

// output after clicking the button 3 times.
/*
"calculated result: 8"
"current result: 8"
"calculated result: 16"
"current result: 16"
"calculated result: 24"
"current result: 24"
*/

Nyní nejprve zobrazíme výsledek jako předchozí výsledek na div a poté načtěte vypočítaný výsledek pomocí obsluhy události button .

Zde specifikujeme volitelný argument addEventListener což je použijte Capture jako pravda pro nadřazený prvek.

Capture – addEventListener

// addEventListener - capturing 
// display previous result before calculating 

container.addEventListener('click', function() {
  console.log(`previous result: ${result}`);
}, true);

addBtn.addEventListener('click', calculate);

// output after clicking the button 3 times.
/*
"previous result: 0"
"calculated result: 8"
"previous result: 8"
"calculated result: 16"
"previous result: 16"
"calculated result: 24"
*/

Nemůžeme použít zachycení události s onclick . To je však dosažitelné pomocí delegování události.

Zachytit – onclick (pomocí delegování události)

// onclick - capturing 
// display previous result before calculating 

container.onclick = function(e) {
  console.log(`previous result: ${result}`);
  if(e.target && e.target.matches('#btn-add')) {
    calculate();
  }
}

// output after clicking the button 3 times.
/*
"previous result: 0"
"calculated result: 8"
"previous result: 8"
"calculated result: 16"
"previous result: 16"
"calculated result: 24"
*/

3. Odeberte posluchače událostí

Zde přidáme num1 + num2 na result pouze jednou a přestat poslouchat událost po prvním kliknutí.

Existuje metoda nazvaná removeEventListener , který přijímá stejné argumenty jako addEventListener dříve. Odebere dříve přidaný posluchač událostí od živlu.

let container = document.querySelector('#container');
let addBtn = document.querySelector('#btn-add');

let num1 = 6;
let num2 = 2;
let result = 0;

function calculate(e) {
  result += num1 + num2;
  console.log(`element: button - result: ${result}`);
}

addEventListener – před odebráním posluchače

container.addEventListener('click', function(e) {
  console.log(`element: div - result: ${result}`);
});
addBtn.addEventListener('click', calculate);

// output after clicking the button 3 times.
/*
"element: button - result: 8"
"element: div - result: 8"
"element: button - result: 16"
"element: div - result: 16"
"element: button - result: 24"
"element: div - result: 24"
*/

addEventListener – po odebrání posluchače

container.addEventListener('click', function(e) {
  addBtn.removeEventListener('click', calculate);
  console.log(`element: div - result: ${result}`);
});
addBtn.addEventListener('click', calculate);

// output after clicking the button 3 times.
/*
"element: button - result: 8"
"element: div - result: 8"
"element: div - result: 8"
"element: div - result: 8"
*/

Neexistuje žádný zřejmý způsob, jak odstranit onclick událost, ale pokud uděláme onclick atribut jako null bude dělat svou práci, jak jsme předpokládali.

onclick – před odebráním posluchače

container.onclick = function(e) {
  console.log(`element: div - result: ${result}`);
}
addBtn.onclick = calculate;

// output after clicking the button 3 times.
/*
"element: button - result: 8"
"element: div - result: 8"
"element: button - result: 16"
"element: div - result: 16"
"element: button - result: 24"
"element: div - result: 24"
*/

onclick – po odebrání posluchače

container.onclick = function(e) {
  addBtn.onclick = null;
  console.log(`element: div - result: ${result}`);
}
addBtn.onclick = calculate;

// output after clicking the button 3 times.
/*
"element: button - result: 8"
"element: div - result: 8"
"element: div - result: 8"
"element: div - result: 8"
*/

Žádné jiné možnosti než addEventListener

1. Přepsání události (Jeden prvek – více obslužných programů)

addEventListener funguje dobře s následujícími dvěma ovladači.

  • První obsluha – vypočítat :vypočítá výsledek.
  • Druhý obslužný program – showResult :zobrazí výsledek.

Pokud použijeme onclick v tomto případě druhý handler přepíše první, takže nikdy nedostaneme vypočítaný výsledek.

let container = document.querySelector('#container');
let addBtn = document.querySelector('#btn-add');

let num1 = 6;
let num2 = 2;
let result = 0;

function calculate(e) {
  if(e.target) {
    result += num1 + num2;
  }
}

function showResult(e) {
  if(e.target) {
    console.log(`result: ${result}`); 
  }
}

Pomocí addEventListener
// addEventListener

addBtn.addEventListener('click', calculate);
addBtn.addEventListener('click', showResult); 

// output after clicking the button 3 times.
/*
"result: 8"
"result: 16"
"result: 24"
*/

Pomocí onclick
// onclick

addBtn.onclick = calculate;
addBtn.onclick = showResult; 

// output after clicking the button 3 times.
/*
"result: 0"
"result: 0"
"result: 0"
*/

Pojďme to shrnout

Nyní můžete vidět onclick umí téměř vše kromě registrace více obslužných rutin do jednoho prvku. Je však dobré zmínit, že před výběrem toho správného pro vaše konkrétní potřeby je třeba zvážit mnoho věcí. Tento příspěvek je zde jen proto, aby dokázal, že stále existují případy, kdy můžeme použít onclick .

Image Credit:Artem Bryzgalov na Unsplash