Увольнение и захват пользовательских событий - PullRequest
13 голосов
/ 14 августа 2011

представьте себе этот сценарий (это действительно просто сценарий):

  • У меня есть глобальный счетчик, который увеличивается с каждым щелчком мыши.
  • когда я достигну 50 кликов, я хочу запустить пользовательское событие с именем 'reachCount'
  • Я хочу зарегистрировать мой оконный объект для захвата этого события с чем-то вроде
    window.addEventListener('reachedCount', function(args){alert(args.count);}, false)

Итак, мои проблемы в том, что я не знаю и нигде не могу найти, как передать аргументы моему eventHandler. Кроме того, я попробовал опубликованный метод Rikudo, но он не работает в IE lt 9.

Возможно ли это? как?

Ответы [ 4 ]

16 голосов
/ 14 августа 2011

Используя ответ Рикудо Сеннина, вы можете передавать параметры в ваш обработчик событий, помещая их в само событие, как это делают обработчики DOM!

function fireEvent(name, target, param1, param2) {
    //Ready: create a generic event
    var evt = document.createEvent("Events")
    //Aim: initialize it to be the event we want
    evt.initEvent(name, true, true); //true for can bubble, true for cancelable
    evt.param1 = param1;
    evt.param2 = param2;
    //FIRE!
    target.dispatchEvent(evt);
}

function foobar(ev) {
    alert("foobar" + ' ' + ev.param1 + ' ' + event.param2);
}

function testEvents(param1) {
    window.addEventListener("foobar", foobar, false); //false to get it in bubble not capture.
    fireEvent("foobar", document, 'test', param1);
}
5 голосов
/ 07 мая 2013

Все ваши аргументы, как и вся остальная информация о событии, должны храниться внутри самого объекта события.Полностью автономный объект события несет все необходимую информацию об этом событии.Значения вашего аргумента обычно устанавливаются, когда новый объект пользовательского события создан (не при запуске события).

( Все фрагменты приведенного ниже примера кода в точности соответствуют всем другим фрагментам. Фактически, некоторые примеры сами по себе могут не иметь особого смысла; всякий раз, когда этослучается, обратитесь к фрагментам предыдущего примера.)

В качестве собственных аргументов в некоторых случаях вы можете повторно использовать существующие поля (или, возможно, даже добавлять свои собственные новые поля):

var newEvent = ...
newEvent['scrollX'] = your-own-custom-value;

Как именноони будут различаться в зависимости от того, сможете ли вы использовать новый стандартизированный способ HTML5, или вам придется использовать более старую поддержку браузера.(Различные «прокладки», которые добавляют поддержку пользовательских событий даже в старые браузеры, которые вообще ничего не предоставляют, здесь не рассматриваются - многие из них предоставят свой довольно уникальный способ задания аргументов.)

Способ HTML5 включает в себя параметр «словарь» (второй) для конструктора объекта, что-то вроде этого:

var newEvent = new CustomEvent('customname', { propertyname : propertyvalue,
                                            anotherpropname : anotherpropvalue,
                                              thirdpropname : thirdpropvalue,
                                                etcpropname : etcpropvalue }   );

Соответствующий более старый метод будет выглядеть примерно так:

var newEvent = document.createEvent();
newEvent.initEvent('customname', true, true);
newEvent['propertyname'] = propertyvalue;
newEvent['anotherpropname'] = anotherpropvalue;
newEvent['thirdpropname'] = thirdpropvalue;
newEvent['etcpropname'] = etcprovalue;

(Вышеприведенный пример также может прояснить, что на самом деле делает конструктор HTML5 CustomEvent.)

Использование таких имен существующих свойств (или создание собственных свойств :-), хотя, как правило, не рекомендуется, посколькупроблемы между браузерами и отладка могут быть довольно серьезными.Время от времени это будет необходимо, и это будет работать, но не полагайтесь на это как на общую технику.Даже если некоторые типы объектов событий включают в себя определенное именованное свойство, подобные типы объектов событий могут этого не делать.Некоторые свойства события могут быть доступны только для чтения.Объекты событий внутренне сильно изменяются от одного браузера к другому и даже между версиями браузера.А создание собственных новых свойств может запутать реализацию Javascript в браузере.

Вместо этого используйте одно конкретное свойство, которое «отложено», для использования в пользовательских событиях и ничего больше: detail .

Часто у вас будет несколько аргументов, ноесть только одно свойство, отведенное для вашего использования.Таким образом, общепринятый подход состоит в том, чтобы всегда превращать все ваши аргументы в один «объект», что-то вроде этого:

var myargs = { my : 1,
              own : getElementById('foo');
             args : { X : 32, Y : 53 }    };

Способ установки этой переменной в HTML5 будет выглядеть примерно так:

var newEvent = new CustomEvent('customname', { bubbles : true,
                                            cancelable : true,
                                                detail : myargs } );

Более старый интерфейс для выполнения того же действия будет выглядеть примерно так:

var newEvent = document.createEvent();
newEvent.initEvent('customname', true, true);
newEvent['detail'] = myargs;

(Конечно, если вы интенсивно используете синтаксис фигурных скобок Javasript для минимизации ввода, ваш код можетвыглядят немного иначе, чем в приведенных выше примерах, которые устанавливают приоритеты для ясности.)

(Два существующих свойства события, «пузыри» и «отменяемые», всегда должны быть установлены для каждого события, независимо от установки возможных пользовательских аргументов. Еслииспользуется новый путь HTML5, они всегда будут отображаться в виде двух дополнительных строк в объекте, который является вторым параметром конструктора CustomEvent. Если используется более старый способ, они будут вторым и третьим параметрами для initEvent (...) call.)

Также возможны два различных метода запуска пользовательского события.rovided.Более новый способ HTML5 использует object.dispatchEvent (newEvent).Старый способ использует object.fireEvent ('customname', newEvent, false).Здесь «объект» означает DOMObject / Element;что именно (если вообще что-то происходит), если «объект» - это нечто, кроме элемента DOM, даже более специфично для браузера, чем остальная часть этой темы.(Смешивание HTML5 и более старого способа в целом работает, но может сбивать с толку. Еще одним частым источником путаницы является наличие системной функции с именем fireEvent (...), а также определение вашей собственной функции с тем же именем.)

(Существуют некоторые тайные различия между двумя способами запуска пользовательского события. Более старый метод fireEvent (...) требует, чтобы вы повторно указали имя события, даже если вы уже указали его в initEvent (...). И более старый метод fireEvent (...) не вызывает «действие по умолчанию» [что бы это ни значило].)

С другой стороны, к пользовательским аргументам обращаются одинаково, независимо отиспользовался ли HTML5 или более старый метод настройки события.Это будет выглядеть примерно так:

function customhandler(evt) {
        alert(evt.detail.own);

Там, где некоторые из ваших пользовательских значений фактически являются объектами, нотация точек может быть настолько длинной, что может выглядеть как опечатка ... но это не так.Например:

function customhandler(evt) {
        alert(evt.detail.args.X);

Похоже, что некоторые из них могут работать немного по-другому в IE 9 и ниже, хотя.Надеемся, что это просто обычные проблемы с попыткой повторно использовать или даже создать свойства объекта события.Если проблемы более распространены, вы можете разместить сообщение «извините :-(» на своем веб-сайте, либо подождать, пока IE6 / 7/8/9 умрет, либо вы можете попытаться взломать его через браузер, либо выможет использовать какой-то шим / запасной вариант. Мне не ясно, лучше ли найти шим, который «выглядит точно так же», как обычный интерфейс, или использовать альтернативный интерфейс, предоставляемый шимом для всего (даже когда обычный интерфейсдоступно).

(Отказ от ответственности: Конечно, я могу ошибаться по поводу некоторых из вышеперечисленных ...: -)

3 голосов
/ 14 октября 2013

Ответы выше кажутся устаревшими.

Создание нового CustomEvent.

var data = { x:20, y:30, rotationY: 60 },
    end = new CustomEvent('MOTION_FINISHED', { detail: data });
    this.dispatchEvent(end);

Похоже, что только свойство 'detail' может передавать параметры. Я также читал, что доступны свойства «пузыри» и «отменяемые», но вы не упомянули их в своем вопросе.

Чтобы получить ваши параметры:

function _handler(e){
    var x = (e.detail && e.detail.x) || 0;
}
3 голосов
/ 14 августа 2011
function fireEvent(name, target) {
    //Ready: create a generic event
    var evt = document.createEvent("Events")
    //Aim: initialize it to be the event we want
    evt.initEvent(name, true, true); //true for can bubble, true for cancelable
    //FIRE!
    target.dispatchEvent(evt);
}

function foobar() {
    alert("foobar");
}

function testEvents() {
    window.addEventListener("foobar", foobar, false); //false to get it in bubble not capture.
    fireEvent("foobar", document);
}

Нашел этот код за 1 минуту поиска Google.http://the.unwashedmeme.com/blog/2004/10/04/custom-javascript-events/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...