Страницы

Поиск по вопросам

пятница, 10 января 2020 г.

Передача аргументов функции в обработчике события

#javascript


Какие есть способы, а самое главное как правильно передавать аргументы в функцию
в обработчике событий
Например:  

var menu = document.querySelector('.nav');
var ul = menu.querySelector('ul');
function handler(event, bool) {
    event = event || window.event;
    if(event.target.tagName == 'LI') {
        if(bool) {
            ul.style.backgroundColor = 'red';
        } else {
            ul.style.backgroundColor = '';
        }

    }
}
menu.addEventListener('mouseout',handler.bind(null, event, false), false);
menu.addEventListener('mouseover',handler.bind(this, event, true), false);   


Вроде работает, но разнице нет какой контекст я передаю в bind, хоть this, хоть null,
хоть вася....
Далее. Изначально код функции был такой:    

function handler(event, bool) {
    if(event.target.tagName == 'LI') {
        var ul = menu.querySelector('ul');
        if(bool) {
            ul.style.backgroundColor = 'red';
        } else {
            ul.style.backgroundColor = '';
        }

    }
}


При этом event == undefined,  ul == undefined.
Добавил в начало функции строку: event = event || window.event; - event появился,
вынес var ul = menu.querySelector('ul'); из функции стало работать.
Так как же правильно передавать аргументы?
    


Ответы

Ответ 1



Используйте handler.bind(null, false) С сигнатурой function handler(bool, event) handler.bind(null, false) как раз вернёт функцию с одним аргументом для события. function handler(bool, event) { console.log(bool, event); } let handleFalse = handler.bind(null, false); let handleTrue = handler.bind(null, true); handleFalse('Event 1'); handleTrue('Event 2'); Либо можно использовать замыкание(если не нужен контекст this): function getHandler(bool) { return function handler(event) { console.log(bool, event); } } let handleFalse = getHandler(false); let handleTrue = getHandler(true); handleFalse('Event 1'); handleTrue('Event 2'); Ну и соберём в кучу: var menu = document.querySelector('.nav'); var ul = menu.querySelector('ul'); function handler(bool) { return function (event) { event = event || window.event; if(event.target.tagName == 'LI') { event.target.style.backgroundColor = bool ? 'red' : ''; } } } menu.addEventListener('mouseout',handler(false), false); menu.addEventListener('mouseover',handler(true), false); Хотя, на мой взгляд, .nav li:hover{} куда лучше

Ответ 2



Для того, чтобы контекст имел значение - в функции обработчике нужно явно использовать this. Первым параметром в bind нужно передать тот объект, который бы вы хотели видеть в качестве this. Воспользуюсь спиппетом от @vp_arth. var menu = document.querySelector('.nav'); function handler(bool, event) { event = event || window.event; if(event.target.tagName == 'LI') { // в оригинале красится весь список, поступим так же this.querySelector('ul') .style.backgroundColor = bool ? 'red' : ''; } } menu.addEventListener('mouseout',handler.bind(menu, false), false); menu.addEventListener('mouseover',handler.bind(menu, true), false); Обратите внимание, что в функции-обработчике handler.bind(menu, false) this === menu, и bool === false. Рассмотрим, в чём ошибки вашего кода. handler.bind(null, event, false) - Вы создаёте функцию здесь и сейчас, привязывая: null в качестве this, глобальную переменную event в качестве первого параметра(на данном этапе она равна undefined) false в качестве второго параметра В итоге, при возникновении события, происходит вызов handler(undefined, false, event) в контексте null(т.е. без контекста), результаты которого вы и видели.

Ответ 3



var btn = document.getElementById("btn"); var theVal = "спасибо за минус дружище )-"; btn.addEventListener("click", function(event, str = theVal){ alert(str); }); одна функция на два события с разными параметрами function work(str){ document.getElementById("btn").innerHTML = str; } btn.addEventListener("mouseover", function (event, str = 'спасибо за минусы'){ work(str); }); btn.addEventListener("mouseout", function (event, str = 'и одному человеку за плюс ✌'){ work(str); });
click


Комментариев нет:

Отправить комментарий