JavaScript. Глобальный обработчик событий. Как?
Вот примерный код:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
<script type="text/javascript">
document.onclick = getObject;
function getObject() {
alert(this);
};
</script>
</head>
<body>
<div style="background-color: silver;">содержимое первого дива</div>
<div style="background-color: red;">содержимое второго дива</div>
</body>
</html>
Откуда возникла такая идея? Ну к примеру представим такую ситуацию: на странице бооольшая пребольшая таблица. Нужно для каждой ячейки создать функцию-обработчик... не очень удобно. А вот бы создать глобальную функцию-обработчик которая вызывалась бы при каждом Click на любом из элементов можно было вызвать функцию-обработчик и уже в ней решать, что делать. Например отловив элемент который был кликнуть по this и уже потом что-то делать с этим элементом.
Возможно ли?
(совет №4 - "Попробуйте делегацию событий")
Добавлено: Хотя нет, извини, у самого не выходит, сдается addListener - это из ЭкшнСкрипт эппопеи, неужели в статье "надули"? Пойду рыть документацию.
1) требуемый вровень абстракции не достигнут. Все равно требуется для ul делать привязку по ID.
2) Как с кросс браузерностью? Какие то странные функции....
Хотя я могу быть не в полне в адеквате... время познее, а у меня перед этим был еще целый день ремонта... Но с ходу чего-то не совсем то...
Есть у тебя функция обработчик и есть большая таблица.
Разве сложно в цикле пройти по всем ячейкам и привязать
к определенному событию твой обработчик?
Сделать что-то вроде такого:
{
// код
}
var table_lnk = getElementById('table_id');
var table_rows_arr = table_lnk.getElementByTagName('tr');
for (i=0; i<table_rows_arr.length; i++)
{
var row_cells_arr = table_rows_arr.getElementByTagName('td');
for (j=0; j<row_cells_arr.length; j++)
{
row_cells_arr[j].onclick = Your_Handler;
}
}
И id каждой ячейке присваивать совершенно не нужно.
В функции Your_Handler this будет указывать на элемент,
которому обработчик принадлежит... Вроде как получилось
как раз то, что ты хочешь:)
Можно придумать всяких вариаций на тему. Например попробовать
применить идеологию Observer'а, для пущей стройности, если
у тебя код очень большой и часто возникает необходимость в таких
действиях...
Если я не прав где-то поправьте:)
Ведь каждое событие проходит по всей dom-иерархии. Нужен глобальный обработчик на таблицу — приделывайте onClick на <TABLE>, нужен вообще глобальный — на window.
Или я не в теме?
Если я все правильно понял, то смотрим addEventListener и attachEvent здесь http://www.javascriptkit.com/domref/elementmethods.shtml и используем эти методы для document.
потом для Event Object смотрим srcElement и target здесь http://www.javascriptkit.com/domref/domevent.shtml
ЗЫ если нужно приведу готовый пример кода
Есть у тебя функция обработчик и есть большая таблица.
Разве сложно в цикле пройти по всем ячейкам и привязать
к определенному событию твой обработчик?
Все верно. Один из решений в этом и заключается. И я его прекрасно зная и реализовывал. Но нахожу его крайне нецелесобразным. А если я хочу например вызвать функцию-обработчик по Click на любом элемента страницы, а не только таблицы? Вещать обработчики на каждый элемента страницы? Если событий много? А вдруг у элемента уже есть обработчик под это событие? А хорошо ли то, что серверный движок знает о содержимом страницы или изменяет её.
В общем с случае существования "глобальных" функций обработчиков вся логика была бы сосредоточена внутри JS скриптов.
Так что... такое решение известно. Нужно искать и другие методы решения.
наверняка же :)=
http://developer.yahoo.com/yui/event/
http://extjs.com/deploy/ext/docs/index.html
Безусловно было и есть! Поэтому и решил отписать на форум. Наверняка я не первый, кто подумал о подобной задаче...
За ссылки спасибо! Буду раскуривать, что там к чему.
Ведь каждое событие проходит по всей dom-иерархии. Нужен глобальный обработчик на таблицу — приделывайте onClick на <TABLE>, нужен вообще глобальный — на window.
Или я не в теме?
Не совсем. Я в первом посте привел приблизительный код и он не работает. Я вообще в доках по JS не нашел ни каких потяний близких к тому, о чем я тут толкую.
OnClick на Table? И? Я вот хочу изменить цвет кликнутой ячейки, к примеру. Функция обработчик повешенная на Table с таблицей работать и будет... и тот же this вернет таблицу... потом перебор потомков... не то.
Если я все правильно понял, то смотрим addEventListener и attachEvent здесь http://www.javascriptkit.com/domref/elementmethods.shtml и используем эти методы для document.
потом для Event Object смотрим srcElement и target здесь http://www.javascriptkit.com/domref/domevent.shtml
ЗЫ если нужно приведу готовый пример кода
Я думал о подобном решении. Однако посмотрев, что подобные свойства и методы понимает только IE, отказался от него. Хотя возможно, если еще покапаться в документации, то может чего и получиться соорудить кроссбраузерное. Хотя если либы приведенные ReDrum-ом обеспечат нужный функционал с сохранение кроссбраузерности, то мучиться нечего.
и
и получаем то что надо.
Неправда. Оно есть и в ФФ/Опере, только называется по другому.
Либы, приведённые ReDrum, просто ацкие штуки. Можешь ещё посмотреть в сторону http://dojotoolkit.org/ . Мне часто проще самому сделать нужное, чем искать в таких обьёмах нужное... Хотя первый раз всегда самый сложный.
Если я привожу не кроссбраузерное решение, то я честно об этом предупреждаю ;)
Это кроссбраузерное решение.
Вот пример кода (специально для этого топика):
<head>
<title>Global Click</title>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<style type="text/css">
#test {
border-collapse: collapse;
}
#test td {
width: 100;
height: 100;
border: 1px solid black;
color: red;
text-align: center;
vertical-align: middle;
font-size: 20px;
}
</style>
</head>
<body>
<table id="test">
<tr><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td></tr>
</table>
<script language="javascript" type="text/javascript">
function clickFunction(e)
{
var evtObj = (e.target) ? e.target : e.srcElement;
if (evtObj.nodeName == "TD"){
if (evtObj.innerHTML == "1") {
evtObj.innerHTML = "0";
evtObj.style.backgroundColor = "white";
evtObj.style.color = "red";
} else {
evtObj.innerHTML = "1";
evtObj.style.backgroundColor = "red";
evtObj.style.color = "white";
}
}
}
var testTable = document.getElementById('test');
if (testTable.addEventListener) {
testTable.addEventListener ('click', clickFunction, true); // Opera, FF, NN
} else {
testTable.attachEvent('onclick', clickFunction); // fucking IE
}
</script>
</body>
</html>
Пощелкай по ячейкам. Можно вместо testTable использовать document (все зависит от того на сколько глобальным должен быть обработчик)
ЗЫ раз уже начали обмениваться ссылками на либы, то вот не менее ацкие
http://www.bindows.net/ (см. демку)
http://www.prototypejs.org/
bindows платная и не поддерживает оперу
Не менее интересный конкурент данной либы: http://mootools.net/
В данном случае используется "недокументированная фича" IE :)
Можешь проверить. В IE 5.0, 5.5, 6.0 все будет работать 100%.
Хотя все-таки на такие фичи не особо стоит полагаться, поэтому ты 99% прав.
[QUOTE=vectoroc]bindows платная[/QUOTE]
Это зависит для чего ты будешь ее использовать...
http://www.bindows.net/download/pricing.html
[QUOTE=vectoroc]и не поддерживает оперу[/QUOTE]
Я хоть и ярый фанат Оперы, но в данном случае полностью поддерживаю разработчиков. Во-первых такие продукты ориентированы в основном на предприятия, где, как правило, используется либо ИЕ (наверное 90%) либо ФФ, а во-вторых такие вещи легче оптимизировать под эти два браузера, чем под эти два браузеры плюс Оперу. :)