Вход

Просмотр полной версии : Выполнение события 1 раз и снятие события?


seyfer
16.11.2012, 09:48
Возможно ли это?

Например я хочу удалить событие вот так:



//где-то назначаю событие
eventUtility.addEvent(block_edit, "click", addSeats);

-----------------------------где-то в другом файле в другой области-----------------------

//ф-я обработчик
var addSeats = function() {

var rows_div = document.getElementById("add_seats_rows");
var cols_div = document.getElementById("add_seats_cols");
//что-то делаем

eventUtility.removeEvent(block_edit, "click", addSeats);

}


Т.е. я хочу, чтобы событие выполнилось 1 раз и с элемента снялся обработчик.

jquery не предлагать.

seyfer
16.11.2012, 10:13
Сделал так: var addSeats = function() {
if (seats.added != true)
{
// eventUtility.removeEvent(block_menu_form, "click", addSeats);

var rows_div = document.getElementById("add_seats_rows");
var cols_div = document.getElementById("add_seats_cols");


seats.added = true;
}

}

Если нужно повторить, то seats.added = false;
seats - глобальный объект.

Еще варианты?

danik.js
17.11.2012, 14:40
block_edit.addEventListener('click', addSeats);

var addSeats = function() {

var rows_div = document.getElementById("add_seats_rows");
var cols_div = document.getElementById("add_seats_cols");
//что-то делаем

block_edit.removeEventListener("click", addSeats);
}


То-есть именно так как вы написали в самом начале. А в чем собственно проблема? У вашего eventUtility отсутствует метод removeEvent() ? значит нужно его дописать. Гуглим по теме "кроссбраузерный addEventListener"

seyfer
19.11.2012, 13:36
Есть конечно removeEvent(), но назначается он в одном месте, а снимается в другом и ф-я назначенная на эвент не глобальная
Пробовал засунуть ф-ю в глобальный объект, но не сработало тоже.
Например:
var actions = {addSeats : function () {} }

В программе
eventUtility.addEvent(block_edit, "click", actions.addSeats);

в другой области видимости
eventUtility.removeEvent(block_edit, "click", actions.addSeats);

не снимает.

danik.js
Вообще ваш комментарий идиотский. Во первых не заметили, что у меня таки есть removeEvent() в коде выше, во вторых не поняли проблему совершенно.

danik.js
19.11.2012, 15:18
Вобще-то ваш вопрос идиотский. Верней, у вас даже вопроса нет. Про возможность - не в счет.

Вы приводите код:

//где-то назначаю событие
eventUtility.addEvent(block_edit, "click", addSeats);

ф-я обработчик
var addSeats = function() {

var rows_div = document.getElementById("add_seats_rows");
var cols_div = document.getElementById("add_seats_cols");
//что-то делаем

eventUtility.removeEvent(block_edit, "click", addSeats);

}


addSeats в области видимости обоих вызовов. Стало быть код ваш не работает (вы привели код, но даже не прокомментировали его) из-за отсутствия/кривости removeEvent. А во втором комментарии вы вообще закомментили этот вызов. Это можно понимать как то, что у вас нет такого метода.

Далее, я привожу код, используя нативные методы (чтоб сработало наверняка), причем ЯСНО ПИШУ, что код идентичен вашему.

Короче, прежде чем что-то писать, думайте, это полезно.

не поняли проблему совершенно

Может, потому что вы ее не описали? Вы описали задачу, вы привели код, решающий вашу задачу, но даже не написали в чем собственно проблема.

seyfer
11.12.2012, 08:12
danik.js
И все таки вы идиот.
Комментарии написаны, они как раз и описывают проблему. Области видимости РАЗНЫЕ, см. комментарий:

//где-то назначаю событие

Это не значит, что прямо выше ф-ии. Код приведен только для примера, вы мыслите слишком узко.

Код removeEvent работает кроссбраузерно.

/**
* удаление события с элемента
* @param {type} el
* @param {type} type
* @param {type} fn - имя ф-ии
* @returns {undefined}
*/
removeEvent: function(el, type, fn) {

if (el) {
if (typeof removeEventListener !== "undefined") {
el.removeEventListener(type, fn, false);
} else if (typeof detachEvent !== "undefined") {
el.detachEvent("on" + type, fn);
} else {
el["on" + type] = null;
}
}

},

Убейтесь, недоразработчик.
Тут как бы форум по javascript и я ожидаю адекватные ответы по теме, а не идиотские придирки или тупые ответы.

seyfer
11.12.2012, 08:16
Вообще было бы интересно все таки получить ответ от кого-то более адекватного.

Получалось ли у кого-то снимать событие внутри ф-ии, которая навешана на это же событие?

Изначально думал так делать. Но событие не снималось, в итоге сделал через переменную-метку.

cyber
11.12.2012, 10:20
И все таки вы идиот.
Вообще было бы интересно все таки получить ответ от кого-то более адекватного.
Вы оскорбляете людей и просите помощи?
Я не думаю что кто то захочет вам помогать!

Sanda
11.12.2012, 10:34
Вообще можно было попробовать без своего EventUtils, прежде чем начинать оскорбления. Не знаю, у кого как, а у меня под FF отлично работает. Ищите ошибку в утилсах.

<body>
<script>
(function () {
var doc = document;
var btn = doc.createElement('button');
btn.appendChild(doc.createTextNode('Click me'));
doc.body.appendChild(btn);
var handler = function () {
alert('It works!');
btn.removeEventListener('click', handler);
}
btn.addEventListener('click', handler);
}());
</script>
</body>

seyfer
21.05.2013, 08:57
Ни кто так и не понял задачи. Смотрите пример кода и пишете как видите. Прочитайте внимательно описание.

addEventListener и removeEventListener вызываются в разных областях видимости у меня! Вы приводите примеры в одной области видимости, и пишете, что работает.

Конечно так работает!!! :)

seyfer
21.05.2013, 08:59
Вообще можно было попробовать без своего EventUtils

Конечно же я пробовал.

Ни кто мне не сказал ничего нового. Печально.

Aetae
21.05.2013, 09:57
this.removeEventListener

simple
21.05.2013, 10:34
elem.addEventListener(event, handler.bind(elem), false);
....
function handler() {
this.removeEventListener(event, arguments.callee);
};

seyfer
21.05.2013, 10:52
А если использовать мой хелпер, получается:

eventUtility.addEvent(block_edit, "click", actions.addSeats);

//в другой области видимости
function addSeats()
{
eventUtility.removeEvent(this, "click", actions.addSeats);
}

Так не работало, видимо actions.addSeats считается уже другим экземпляром.

arguments.callee - ссылается на сам себя, т.е. this ? Так не пробовал, может быть получится так.

eventUtility.removeEvent(this, "click", arguments.callee);

Благодарю за наводку, уже лучше, чем предыдущие ответы. :)

danik.js
21.05.2013, 13:09
<body>
<script>
document.addEventListener('mousemove', onMouseMove)

function onMouseMove(){
document.body.innerHTML += 'mousemove<br>';
//document.removeEventListener('mousemove', onMouseMove);
}
</script>
</body>


<body>
<script>
document.addEventListener('mousemove', onMouseMove)

function onMouseMove(){
document.body.innerHTML += 'mousemove<br>';
document.removeEventListener('mousemove', onMouseMove);
}
</script>
</body>

seyfer
22.05.2013, 07:29
<body>
<script>
document.addEventListener('mousemove', onMouseMove)

function onMouseMove(){
document.body.innerHTML += 'mousemove<br>';
//document.removeEventListener('mousemove', onMouseMove);
}
</script>
</body>


<body>
<script>
document.addEventListener('mousemove', onMouseMove)

function onMouseMove(){
document.body.innerHTML += 'mousemove<br>';
document.removeEventListener('mousemove', onMouseMove);
}
</script>
</body>


У вас в данном случаем одна область видимости. :D
Ну и даже если написать иначе, но в такой последовательности - сработают замыкания.

У меня задача была сделать чтобы работало так же в РАЗНЫХ областях видимости. Как вы не можете этого понять то...........

seyfer
22.05.2013, 07:35
Попробуйте обернуть

document.addEventListener('mousemove', onMouseMove)

в другую ф-ю. и представить, что onMouseMove принадлежит глобальному объекту.

var seat = {
onMouseMove : function() {};
}

Тогда первой идеей будет в каждой ф-ии вызывать

function1 () {
document.addEventListener('mousemove', seat.onMouseMove);
}
function2 () {
document.removeEventListener('mousemove', seat.onMouseMove);
}

Попробуйте))) а у меня это не функции к тому же, а методы, т.е. в объектах. Моя задача более сложная, чем ваши простенькие примеры danik.js. Узко мыслите.

Из-за вашего ограниченного мышления danik.js мне тут минусов понаставили, однако вы просто не поняли задачу. Не идиотизм разве.

danik.js
22.05.2013, 10:37
у меня это не функции к тому же, а методы
В javascript нету методов, также как и классов. О чем ты вобще

<body>
<script>
var seat = {
onMouseMove: function() {
document.body.innerHTML += 'mousemove<br>';
document.removeEventListener('mousemove', seat.onMouseMove);
}
}
document.addEventListener('mousemove', seat.onMouseMove)
</script>
</body>

И че изменилось? ссылка на обработчик так и осталась ссылкой на обработчик.

Из-за вашего ограниченного мышления danik.js мне тут минусов понаставили
Не перекладывай свои недостатки на других. Тебе наставили минусов потому что ты тормоз, еще и возмущаешься.

Aetae
22.05.2013, 11:50
danik.js,
Ну ты упоролся: у него событие вешается не на глобальный document, а на видимый локально block_edit, которого нет в области видимости addSeats.

Он конечно тоже упоролся - писать свой обработчик событий не разобравшись с нативным, но с него спросу мало.

Так не работало, видимо actions.addSeats считается уже другим экземпляром.
Нет. Скорее всего, из-за кривой самопальной работы с событиями, this указывает куда-то не туда.

elem.addEventListener(event, handler.bind(elem), false);
....
function handler() {
this.removeEventListener(event, arguments.callee);
};

bind не нужен, событие всегда обрабатывается в контексте вызова.

danik.js
22.05.2013, 12:00
Ну ты упоролся: у него событие вешается не на глобальный document, а на видимый локально block_edit, которого нет в области видимости addSeats.
Ну и причем тут вообще события? Области видимости - основа языка. Вопрос был про разовое выполнение. А проблема с видимостью переменной - это уже другая тема.

Aetae
22.05.2013, 12:14
Вопрос был про разовое выполнение.
Вопрос был скорее "почему не работает".