仅当持续时间超过几秒时才触发 mouseleave 事件 - jQuery
Firing a mouseleave event only if it lasts longer than a few seconds long - jQuery
我创建了一个幻灯片,当用户试图离开页面(鼠标离开 tabs/url)时会触发该幻灯片。问题是它会立即触发并且这样做时会很烦人,因此...
我考虑过使用 setTimeout 和 clearTimeout 将事件的触发延迟到 mouseleave 事件发生后仅 500 毫秒,并且只有当它们在该持续时间内停留在那里时。
这意味着,我希望事件仅在用户鼠标离开超过 500 毫秒时触发。否则,如果他们 return 在持续时间之前,事件不会触发..
制作滑出。确保您在文档中单击,然后向外滚动到顶部
JS
$(() => {
// Sliding helper nav initial position hidden
function showSidebar() {
$('.nav__slide').removeClass('hidden_nav__slide');
$('.nav__slide').animate({
right: '0px',
}, {
queue: false,
duration: 800,
});
$('body').addClass('overlay');
}
// Limiting mouse events from firing too often.
function handleMouseOut(e) {
function debounce(func, wait, immediate) {
let timeout;
return (...args) => {
const context = this;
const later = () => {
timeout = null;
if (!immediate) {
func.apply(context, args);
}
};
const callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
}
const event = e || window.event;
const from = event.relatedTarget || event.toElement;
// Handling when the mouseover is outside of the clientY (in the browser/tab area above)
// but not outside of the browser window
if ((!from || from.nodeName === 'HTML') && event.clientY <= 0) {
debounce(showSidebar, 1000, true)();
}
}
// Hiding the sliding helper div after the user clicks the close button.
function hideSidenav() {
$('body').removeClass('overlay');
setTimeout(() => {
$('.nav__slide').addClass('hidden_nav__slide');
}, 700);
$('.nav__slide').animate({
right: '-450px',
}, {
queue: false,
duration: 800,
});
}
// Closing button to hide the sliding helper nav.
$('.js__button__close').click(() => {
hideSidenav();
document.removeEventListener('mouseout', handleMouseOut);
});
// Initializing the event.
function init() {
if (document.addEventListener) {
document.addEventListener('mouseout', handleMouseOut, false);
}
}
init()
});
HTML
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div>
<div>
<div class="nav__slide">
<font class="js__button__close button__close" color="red"></font>
<div class="logo-line"></div>
<h2 class="content-header">Words to return!</h2>
</div>
<h2 class="heading">A main title </h2>
<main class="main-content">
<ul>
<li>some words here</li>
</ul>
</main>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</div>
</div>
</body>
</html>
CSS
.nav__slide {
/* Positioning */
position: fixed;
/* Visuals */
background: #ffffff;
/* Positioning */
top: 0;
right: -450px;
width: 390px;
height: 100%;
z-index: 99;
/* Box-Model and Display */
overflow-y: auto;
overflow-x: hidden;
}
.nav__slide .button__close {
/* Visuals */
background: #ffffff;
/* Box-Model and Display */
height: 30px;
width: 30px;
cursor: pointer;
float: left;
}
.nav__slide .button__close:before {
/* Box-Model and Display */
display: flex;
justify-content: center;
padding-top: 20%;
content: "15";
}
.hidden_nav__slide {
/* Visuals */
visibility: hidden;
}
.nav__slide .content-container {
/* Box-Model and Display */
display: flex;
justify-content: center;
flex-flow: column wrap;
/* Typography */
font-weight: 400;
}
.nav__slide .content__logo {
/* Box-Model and Display */
width: 170px;
height: 60px;
}
.nav__slide .logo-line {
/* Visuals */
border-bottom: solid #dbdbdb 2px;
border-style: ridge;
opacity: 0.1;
/* Box-Model and Display */
width: 100%;
margin-left: -1%;
}
.nav__slide .content-header {
/* Positioning */
display: flex;
justify-content: center;
/* Typography */
font-weight: 200;
font-family: Arial, Helvetica, sans-serif;
font-size: 30px;
/* Box-Model and Display */
margin-bottom: 5%;
margin-top: 25%;
}
/* This will likely be removed depending
on the image that is used */
.nav__slide .stand-in-image {
/* Box-Model and Display */
width: 240px;
height: 140px;
}
.nav__slide .content-container__header {
/* Typography */
font-family: Arial, Helvetica, sans-serif;
list-style: none;
font-size: 16px;
line-height: 10px;
font-weight: 600;
/* Box-Model and Display */
margin-left: 20%;
}
.nav__slide .content-list__item {
/* Typography */
font-weight: 600;
font-family: Arial, Helvetica, sans-serif;
line-height: 26px;
font-size: 15px;
/* Box-Model and Display */
display: flex;
padding: 2%;
margin-left: 10%;
}
.nav__slide .coupon-button {
/* Typography */
font-size: 14px;
font-weight: 400;
color: #ffffff;
cursor: pointer;
/* Visuals */
background-color: #b2ca48;
/* Box-Model and Display */
padding: 10%;
margin-top: 10%;
margin-right: 5%;
}
.nav__slide .main-content {
/* Positioning */
display: flex;
justify-content: center;
flex-flow: row wrap;
z-index: 0;
}
/* Adding the overlay:after class onto the body */
.overlay:after {
/* Box-Model and Display */
content: "";
/* Positioning */
position: fixed;
width: 100%;
height: 100%;
/* Visuals */
opacity: 0.9;
background-color: #373737be;
/* Positioning */
left: 0;
top: 0;
}
我发现了一些其他答案,这些答案与我在延迟触发事件时的想法类似。
我一直在使用它,但由于代码较旧(几个月前)而且我仍然相对较新。我正在学习需要的教训:
- 对正在做什么做出更好的评论
- 确保在构建解决方案时彻底了解您使用的代码。
感谢您的帮助,我将继续尝试和调整它,但没有找到任何具体可行的方法。
我觉得我可以做到。
不过,我不太明白你说的变量是什么意思,immediate
。
另外,我稍微删减了你的代码,但我觉得没问题。
// Timer
let timer;
// Called, when mouse enter to the document.
function handleMouseEnter() {
// clear timer(stop).
clearTimeout(timer);
}
// Limiting mouse events from firing too often.
function handleMouseLeave() {
timer = setTimeout(function() {
// Show side bar.
showSidebar();
// Event off. (ShowSideBar will run only once.)
$(document)
.off('mouseleave', handleMouseLeave)
.off('mouseenter', handleMouseEnter);
}, 500);
}
// Initializing the event.
function init() {
// the same as document.addEventListener('mouseleave~
$(document)
.on('mouseleave', handleMouseLeave)
.on('mouseenter', handleMouseEnter);
}
已更新
// Limiting mouse events from firing too often.
function handleMouseLeave(e) {
// you can get original event.
console.log(e.originalEvent);
我创建了一个幻灯片,当用户试图离开页面(鼠标离开 tabs/url)时会触发该幻灯片。问题是它会立即触发并且这样做时会很烦人,因此...
我考虑过使用 setTimeout 和 clearTimeout 将事件的触发延迟到 mouseleave 事件发生后仅 500 毫秒,并且只有当它们在该持续时间内停留在那里时。
这意味着,我希望事件仅在用户鼠标离开超过 500 毫秒时触发。否则,如果他们 return 在持续时间之前,事件不会触发..
制作滑出。确保您在文档中单击,然后向外滚动到顶部
JS
$(() => {
// Sliding helper nav initial position hidden
function showSidebar() {
$('.nav__slide').removeClass('hidden_nav__slide');
$('.nav__slide').animate({
right: '0px',
}, {
queue: false,
duration: 800,
});
$('body').addClass('overlay');
}
// Limiting mouse events from firing too often.
function handleMouseOut(e) {
function debounce(func, wait, immediate) {
let timeout;
return (...args) => {
const context = this;
const later = () => {
timeout = null;
if (!immediate) {
func.apply(context, args);
}
};
const callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
}
const event = e || window.event;
const from = event.relatedTarget || event.toElement;
// Handling when the mouseover is outside of the clientY (in the browser/tab area above)
// but not outside of the browser window
if ((!from || from.nodeName === 'HTML') && event.clientY <= 0) {
debounce(showSidebar, 1000, true)();
}
}
// Hiding the sliding helper div after the user clicks the close button.
function hideSidenav() {
$('body').removeClass('overlay');
setTimeout(() => {
$('.nav__slide').addClass('hidden_nav__slide');
}, 700);
$('.nav__slide').animate({
right: '-450px',
}, {
queue: false,
duration: 800,
});
}
// Closing button to hide the sliding helper nav.
$('.js__button__close').click(() => {
hideSidenav();
document.removeEventListener('mouseout', handleMouseOut);
});
// Initializing the event.
function init() {
if (document.addEventListener) {
document.addEventListener('mouseout', handleMouseOut, false);
}
}
init()
});
HTML
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div>
<div>
<div class="nav__slide">
<font class="js__button__close button__close" color="red"></font>
<div class="logo-line"></div>
<h2 class="content-header">Words to return!</h2>
</div>
<h2 class="heading">A main title </h2>
<main class="main-content">
<ul>
<li>some words here</li>
</ul>
</main>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</div>
</div>
</body>
</html>
CSS
.nav__slide {
/* Positioning */
position: fixed;
/* Visuals */
background: #ffffff;
/* Positioning */
top: 0;
right: -450px;
width: 390px;
height: 100%;
z-index: 99;
/* Box-Model and Display */
overflow-y: auto;
overflow-x: hidden;
}
.nav__slide .button__close {
/* Visuals */
background: #ffffff;
/* Box-Model and Display */
height: 30px;
width: 30px;
cursor: pointer;
float: left;
}
.nav__slide .button__close:before {
/* Box-Model and Display */
display: flex;
justify-content: center;
padding-top: 20%;
content: "15";
}
.hidden_nav__slide {
/* Visuals */
visibility: hidden;
}
.nav__slide .content-container {
/* Box-Model and Display */
display: flex;
justify-content: center;
flex-flow: column wrap;
/* Typography */
font-weight: 400;
}
.nav__slide .content__logo {
/* Box-Model and Display */
width: 170px;
height: 60px;
}
.nav__slide .logo-line {
/* Visuals */
border-bottom: solid #dbdbdb 2px;
border-style: ridge;
opacity: 0.1;
/* Box-Model and Display */
width: 100%;
margin-left: -1%;
}
.nav__slide .content-header {
/* Positioning */
display: flex;
justify-content: center;
/* Typography */
font-weight: 200;
font-family: Arial, Helvetica, sans-serif;
font-size: 30px;
/* Box-Model and Display */
margin-bottom: 5%;
margin-top: 25%;
}
/* This will likely be removed depending
on the image that is used */
.nav__slide .stand-in-image {
/* Box-Model and Display */
width: 240px;
height: 140px;
}
.nav__slide .content-container__header {
/* Typography */
font-family: Arial, Helvetica, sans-serif;
list-style: none;
font-size: 16px;
line-height: 10px;
font-weight: 600;
/* Box-Model and Display */
margin-left: 20%;
}
.nav__slide .content-list__item {
/* Typography */
font-weight: 600;
font-family: Arial, Helvetica, sans-serif;
line-height: 26px;
font-size: 15px;
/* Box-Model and Display */
display: flex;
padding: 2%;
margin-left: 10%;
}
.nav__slide .coupon-button {
/* Typography */
font-size: 14px;
font-weight: 400;
color: #ffffff;
cursor: pointer;
/* Visuals */
background-color: #b2ca48;
/* Box-Model and Display */
padding: 10%;
margin-top: 10%;
margin-right: 5%;
}
.nav__slide .main-content {
/* Positioning */
display: flex;
justify-content: center;
flex-flow: row wrap;
z-index: 0;
}
/* Adding the overlay:after class onto the body */
.overlay:after {
/* Box-Model and Display */
content: "";
/* Positioning */
position: fixed;
width: 100%;
height: 100%;
/* Visuals */
opacity: 0.9;
background-color: #373737be;
/* Positioning */
left: 0;
top: 0;
}
我发现了一些其他答案,这些答案与我在延迟触发事件时的想法类似。
我一直在使用它,但由于代码较旧(几个月前)而且我仍然相对较新。我正在学习需要的教训: - 对正在做什么做出更好的评论 - 确保在构建解决方案时彻底了解您使用的代码。
感谢您的帮助,我将继续尝试和调整它,但没有找到任何具体可行的方法。
我觉得我可以做到。
不过,我不太明白你说的变量是什么意思,immediate
。
另外,我稍微删减了你的代码,但我觉得没问题。
// Timer
let timer;
// Called, when mouse enter to the document.
function handleMouseEnter() {
// clear timer(stop).
clearTimeout(timer);
}
// Limiting mouse events from firing too often.
function handleMouseLeave() {
timer = setTimeout(function() {
// Show side bar.
showSidebar();
// Event off. (ShowSideBar will run only once.)
$(document)
.off('mouseleave', handleMouseLeave)
.off('mouseenter', handleMouseEnter);
}, 500);
}
// Initializing the event.
function init() {
// the same as document.addEventListener('mouseleave~
$(document)
.on('mouseleave', handleMouseLeave)
.on('mouseenter', handleMouseEnter);
}
已更新
// Limiting mouse events from firing too often.
function handleMouseLeave(e) {
// you can get original event.
console.log(e.originalEvent);