Javascript - 在调整大小时删除事件侦听器
Javascript - Remove event listener at resize
我正在做一些工作,使导航完全可以通过鼠标悬停、键盘和单击来访问,具体取决于分辨率。
我正在移动设备上寻找,只有点击有效。悬停、单击、键盘以获得更高的分辨率。
重要编辑:
它仅在我以正确的分辨率(低或高)加载页面时 完美 工作。 但是,如果我实时调整大小,removeEventListener
将不起作用。
加:我不知道我的stopImmediatePropagation
是否是避免多重功能的更好解决方案。
这里是代码的思路。
JS
window.addEventListener("DOMContentLoaded", onLoadFunction);
function onLoadFunction(e) {
menu_burger();
onResizeFunction(); //trigger resize function immediately
window.addEventListener("resize", onResizeFunction);
}
function onResizeFunction(e) {
if (window.innerWidth > 770) {
window.removeEventListener('resize', menu_onClick);
menu_onClick();
menu_mouseOver();
menu_onFocus();
menu_onFocusDetection();
} else {
window.removeEventListener('resize', menu_onClick);
window.removeEventListener('resize', menu_mouseOver);
window.removeEventListener('resize', menu_onFocusDetection);
window.removeEventListener('resize', menu_onFocus);
menu_onClick();
}
}
// FONCTIONS MENU
const focusDetectionEntry = document.querySelectorAll('.nav-list--focus-detection > li[aria-expanded] > button');
const focusEntry = document.querySelectorAll('.nav-list--focus > li[aria-expanded] > button');
const overEntry = document.querySelectorAll('.nav-list--over > li[aria-expanded] > button');
const clickEntry = document.querySelectorAll('.nav-list--click > li[aria-expanded] > button');
function menu_burger() {
document.querySelector('.menu-burger').addEventListener('click', function () {
this.classList.toggle('menu--open');
document.querySelector('.main-nav-list').classList.toggle('main-nav-list--open');
});
}
function menu_mouseOver() {
overEntry.forEach(sub => {
var subParent = sub.parentElement;
subParent.addEventListener('mouseover', function(e) {
subParent.setAttribute('aria-expanded', 'true');
console.log('OVER IN');
e.stopImmediatePropagation();
});
subParent.addEventListener('mouseout', function(e) {
subParent.setAttribute('aria-expanded', 'false');
console.log('OVER OUT');
e.stopImmediatePropagation();
});
})
}
function menu_onClick() {
clickEntry.forEach(sub => {
var subParent = sub.parentElement;
sub.addEventListener('click', function(e) {
let attrState = subParent.getAttribute('aria-expanded');
if (attrState === 'false') {
subParent.setAttribute('aria-expanded', 'true')
} else if (attrState === 'true') {
subParent.setAttribute('aria-expanded', 'false');
}
console.log('CLICK');
e.stopImmediatePropagation();
});
})
}
function menu_onFocus() {
focusEntry.forEach(sub => {
var subParent = sub.parentElement;
sub.addEventListener('keyup', (e) => {
console.log('TOUCHE');
if (e.keyCode === 27) {
console.log('ECHAP');
subParent.setAttribute('aria-expanded', 'false');
}
e.stopImmediatePropagation();
});
})
}
function menu_onFocusDetection() {
focusDetectionEntry.forEach(sub => {
var subParent = sub.parentElement;
sub.addEventListener('focus', function (e) {
subParent.setAttribute('aria-expanded', 'true');
console.log('FOCUS');
e.stopImmediatePropagation();
});
subParent.addEventListener('focusout', function (e) {
console.log('FOCUS OUT');
//console.log(e.relatedTarget); //target actuel
if (!subParent.contains(e.relatedTarget)) {
subParent.setAttribute('aria-expanded', 'false');
}
e.stopImmediatePropagation();
});
})
}
我试过类似的东西,但没有成功:
function menu_onFocusDetection() {
focusDetectionEntry.forEach(sub => {
var subParent = sub.parentElement;
// si focus sur le bouton, on modifie sont parent
function test(ev) {
subParent.setAttribute('aria-expanded', 'true');
console.log('FOCUS');
ev.stopImmediatePropagation();
}
// si le focus sort du li
function test2(ev2) {
// console.log(ev2.relatedTarget); //target actuel
console.log('FOCUS OUT');
if (!subParent.contains(ev2.relatedTarget)) {
subParent.setAttribute('aria-expanded', 'false');
}
ev2.stopImmediatePropagation();
}
if (window.innerWidth > 770) {
sub.addEventListener('focus', test);
sub.addEventListener('focusout', test2);
} else {
sub.removeEventListener('focus', test);
sub.removeEventListener('focusout', test2);
}
})
}
事件处理程序在每次事件发生时执行,而不仅仅是第一次。他们只需要注册一次。
将点击和鼠标悬停处理程序移至独立函数声明,并在外部块中注册这些处理程序。所以基本上:
window.addEventListener("load", onLoadFunction);
function onLoadFunction(e) {
onResizeFunction();// trigger resize function immediately
window.addEventListener("resize", onResizeFunction);
}
function onResizeFunction(e) {
if (window.innerWidth > 770) {
//over + click
over();
click();
} else {
//only click
click();
}
}
function click() {
console.log('CLICK');
}
function over() {
console.log('OVER');
}
document.querySelector('.test').addEventListener('click', click);
document.querySelector('.test').addEventListener('mouseover', over);
好的,这就是答案:
我不得不拆分我的函数并在每个函数中执行条件。
window.addEventListener("DOMContentLoaded", onLoadFunction);
function onLoadFunction(e) {
onResizeFunction(); //trigger resize function immediately
window.addEventListener("resize", onResizeFunction);
}
function onResizeFunction(e) {
menu_onFocusDetection();
}
function initEntries() {
focusDetectionEntry = document.querySelectorAll('.nav-list--focus-detection > li[aria-expanded] > button');
}
function focus(e) {
this.parentElement.setAttribute('aria-expanded', 'true');
e.stopImmediatePropagation();
}
function menu_onFocusDetection() {
focusDetectionEntry.forEach(sub => {
var subParent = sub.parentElement;
if (window.innerWidth > 770) {
sub.addEventListener('focus', focus);
subParent.addEventListener('focusout', focusOut);
} else {
sub.removeEventListener('focus', focus);
subParent.removeEventListener('focusout', focusOut);
}
});
}
我正在做一些工作,使导航完全可以通过鼠标悬停、键盘和单击来访问,具体取决于分辨率。
我正在移动设备上寻找,只有点击有效。悬停、单击、键盘以获得更高的分辨率。
重要编辑:
它仅在我以正确的分辨率(低或高)加载页面时 完美 工作。 但是,如果我实时调整大小,removeEventListener
将不起作用。
加:我不知道我的stopImmediatePropagation
是否是避免多重功能的更好解决方案。
这里是代码的思路。
JS
window.addEventListener("DOMContentLoaded", onLoadFunction);
function onLoadFunction(e) {
menu_burger();
onResizeFunction(); //trigger resize function immediately
window.addEventListener("resize", onResizeFunction);
}
function onResizeFunction(e) {
if (window.innerWidth > 770) {
window.removeEventListener('resize', menu_onClick);
menu_onClick();
menu_mouseOver();
menu_onFocus();
menu_onFocusDetection();
} else {
window.removeEventListener('resize', menu_onClick);
window.removeEventListener('resize', menu_mouseOver);
window.removeEventListener('resize', menu_onFocusDetection);
window.removeEventListener('resize', menu_onFocus);
menu_onClick();
}
}
// FONCTIONS MENU
const focusDetectionEntry = document.querySelectorAll('.nav-list--focus-detection > li[aria-expanded] > button');
const focusEntry = document.querySelectorAll('.nav-list--focus > li[aria-expanded] > button');
const overEntry = document.querySelectorAll('.nav-list--over > li[aria-expanded] > button');
const clickEntry = document.querySelectorAll('.nav-list--click > li[aria-expanded] > button');
function menu_burger() {
document.querySelector('.menu-burger').addEventListener('click', function () {
this.classList.toggle('menu--open');
document.querySelector('.main-nav-list').classList.toggle('main-nav-list--open');
});
}
function menu_mouseOver() {
overEntry.forEach(sub => {
var subParent = sub.parentElement;
subParent.addEventListener('mouseover', function(e) {
subParent.setAttribute('aria-expanded', 'true');
console.log('OVER IN');
e.stopImmediatePropagation();
});
subParent.addEventListener('mouseout', function(e) {
subParent.setAttribute('aria-expanded', 'false');
console.log('OVER OUT');
e.stopImmediatePropagation();
});
})
}
function menu_onClick() {
clickEntry.forEach(sub => {
var subParent = sub.parentElement;
sub.addEventListener('click', function(e) {
let attrState = subParent.getAttribute('aria-expanded');
if (attrState === 'false') {
subParent.setAttribute('aria-expanded', 'true')
} else if (attrState === 'true') {
subParent.setAttribute('aria-expanded', 'false');
}
console.log('CLICK');
e.stopImmediatePropagation();
});
})
}
function menu_onFocus() {
focusEntry.forEach(sub => {
var subParent = sub.parentElement;
sub.addEventListener('keyup', (e) => {
console.log('TOUCHE');
if (e.keyCode === 27) {
console.log('ECHAP');
subParent.setAttribute('aria-expanded', 'false');
}
e.stopImmediatePropagation();
});
})
}
function menu_onFocusDetection() {
focusDetectionEntry.forEach(sub => {
var subParent = sub.parentElement;
sub.addEventListener('focus', function (e) {
subParent.setAttribute('aria-expanded', 'true');
console.log('FOCUS');
e.stopImmediatePropagation();
});
subParent.addEventListener('focusout', function (e) {
console.log('FOCUS OUT');
//console.log(e.relatedTarget); //target actuel
if (!subParent.contains(e.relatedTarget)) {
subParent.setAttribute('aria-expanded', 'false');
}
e.stopImmediatePropagation();
});
})
}
我试过类似的东西,但没有成功:
function menu_onFocusDetection() {
focusDetectionEntry.forEach(sub => {
var subParent = sub.parentElement;
// si focus sur le bouton, on modifie sont parent
function test(ev) {
subParent.setAttribute('aria-expanded', 'true');
console.log('FOCUS');
ev.stopImmediatePropagation();
}
// si le focus sort du li
function test2(ev2) {
// console.log(ev2.relatedTarget); //target actuel
console.log('FOCUS OUT');
if (!subParent.contains(ev2.relatedTarget)) {
subParent.setAttribute('aria-expanded', 'false');
}
ev2.stopImmediatePropagation();
}
if (window.innerWidth > 770) {
sub.addEventListener('focus', test);
sub.addEventListener('focusout', test2);
} else {
sub.removeEventListener('focus', test);
sub.removeEventListener('focusout', test2);
}
})
}
事件处理程序在每次事件发生时执行,而不仅仅是第一次。他们只需要注册一次。
将点击和鼠标悬停处理程序移至独立函数声明,并在外部块中注册这些处理程序。所以基本上:
window.addEventListener("load", onLoadFunction);
function onLoadFunction(e) {
onResizeFunction();// trigger resize function immediately
window.addEventListener("resize", onResizeFunction);
}
function onResizeFunction(e) {
if (window.innerWidth > 770) {
//over + click
over();
click();
} else {
//only click
click();
}
}
function click() {
console.log('CLICK');
}
function over() {
console.log('OVER');
}
document.querySelector('.test').addEventListener('click', click);
document.querySelector('.test').addEventListener('mouseover', over);
好的,这就是答案:
我不得不拆分我的函数并在每个函数中执行条件。
window.addEventListener("DOMContentLoaded", onLoadFunction);
function onLoadFunction(e) {
onResizeFunction(); //trigger resize function immediately
window.addEventListener("resize", onResizeFunction);
}
function onResizeFunction(e) {
menu_onFocusDetection();
}
function initEntries() {
focusDetectionEntry = document.querySelectorAll('.nav-list--focus-detection > li[aria-expanded] > button');
}
function focus(e) {
this.parentElement.setAttribute('aria-expanded', 'true');
e.stopImmediatePropagation();
}
function menu_onFocusDetection() {
focusDetectionEntry.forEach(sub => {
var subParent = sub.parentElement;
if (window.innerWidth > 770) {
sub.addEventListener('focus', focus);
subParent.addEventListener('focusout', focusOut);
} else {
sub.removeEventListener('focus', focus);
subParent.removeEventListener('focusout', focusOut);
}
});
}