Jak dynamicky přidat HTML prvku obsluhu události
15. března 2007
O autorovi
Jan Aubrecht
.NET vývojář a konzultant IS/IT
honza@intellisoft.cz
Honza se zabývá vývojem webových aplikací od roku 2000. Rád používá ASP.NET 2.0 a je přímo posedlý neustálým zlepšováním svých aplikací.
Ve volném čase je jeho vášní dobré jídlo a pití. Nejraději se baví přípravou středomořských specialit a báječnými víny z Francie.
Jak pomocí JavaScriptu obsloužit události prvků ve stránce asi víte. Jak ale přidat obsluhu události prvku, který už má danou událost zaregistrovanou? Tento článek vám ukáže, jak přidat prvku další obsluhu události, tak aby vše fungovalo ve všech dnes běžně používaných prohlížečích.
Jak registrovat událost?
Základní obsluha události jakéhokoliv HTML prvku se většinou nastavuje buď přímo ve stránce nebo se inicializuje v kódu klientského skriptování. Většinou jsou tedy události registrovány nějak takto:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Registrace události</title>
<script type="text/javascript">
//Registrace události v JavaScriptu.
window.onload = function()
{
alert('Událost zaregistrovaná v JavaScriptu');
}
</script>
</head>
<!-- Registrace události ve stránce -->
<body onload="alert('Událost zaregistrovaná ve stránce.');">
</body>
</html>
Pokud si uvedený příklad spustíte, budete možná překvapeni, že stránka zobrazí pouze jeden dialog a ne dva, jak byste možná čekali. Proč tomu tak je?
Nejdříve se ve stránce zaregistruje obsluha události z kódu JavaScriptu, protože se ve stránce nachází dříve. Pak následuje nastavení obsluhy pomocí atributu onload uvnitř prvku body. To se také provede, ale při přiřazení dojde k nahrazení všech předchozích registrací. Nahradí se tedy i ta, kterou jsme si nastavili přímo v JavaScriptu.
Jak přidat další obsluhu události?
Naštěstí nic není ztraceno, protože tvůrci prohlížečů pamatovali i na další možnosti práce s událostmi.
V současné době tedy každý běžně používaný prohlížeč obsahuje podporu pro dynamickou registraci a odregistraci událostí. Je tedy možné prvku ve stránce kdykoliv obsluhu události přidat nebo naopak odebrat, aniž by byly ovlivněny ostatní nastavené handlery.
Jak už tomu ale bohužel bývá, jde na to každý prohlížeč trochu jinak.
Mozilla a Netspace
Tvůrci Netspace a Mozilly šli cestou standardů a pro registraci událostí používají interface EventListener, tak jak ho popisuje specifikace W3C.
V těchto prohlížečích se pro registraci událostí používá metoda addEventListener, pro odregistrování pak metoda removeEventListener.
Internet Explorer
Internet Explorer vidí celou věc jinak a tak registraci událostí provádí úplně jiným způsobem.
V Internet Exploreru je možné provést registraci události pomocí metody attachEvent. Odregistrování události se pak provede pomocí metody detachEvent.
Aby toho nebylo málo, tak u Internet Exploreru se označuje událost click jako onclick, mousedown jako onmousedown apod.
Řešení pro všechny prohlížeče
Jak tedy zaregistrovat obsluhu události, tak aby fungovala ve všech prohlížečích? Podívejte se na příklad níže.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Registrace události</title>
</head>
<body>
<button id="button">Klikni na mě</button>
<script type="text/javascript">
var button = document.getElementById('button');
if (button)
{
attachEvent(button, 'click', function() {alert('1. kliknutí')});
attachEvent(button, 'click', function() {alert('2. kliknutí')});
}
function attachEvent(source, eventType, handler)
{
if (source)
{
if (source.addEventListener)
{
source.addEventListener(eventType, handler, false);
return true;
}
else if (source.attachEvent)
{
return source.attachEvent('on' + eventType, handler);
}
}
return false;
}
function detachEvent(source, eventType, handler)
{
if (source)
{
if (source.removeEventListener)
{
source.removeEventListener(eventType, handler, false);
return true;
}
else if (source.detachEvent)
{
return source.detachEvent('on' + eventType, handler);
}
}
return false;
}
</script>
</body>
</html>
Na celém řešení asi nenajdete nic překvapivého. Funkce si nejdříve zjistí, jakou formu práce s událostmi prohlížeč podporuje a pak se pomocí příslušné metody pokusí danou událost zaregistrovat (případně odregistrovat).