首页 > 解决方案 > 只有在持续时间超过几秒钟时才触发 mouseleave 事件 - jQuery

问题描述

我创建了一张幻灯片,当用户尝试离开页面时触发(鼠标离开标签/网址)。问题是它会立即触发并且这样做会很烦人,因此......

我想过使用 setTimeout 和 clearTimeout 来延迟事件的触发,直到 mouseleave 事件发生后仅 500 毫秒,并且只有当它们在那里停留一段时间。

这意味着,我希望该事件仅在用户鼠标离开超过 500 毫秒时触发。否则,如果他们在持续时间之前返回,则事件不会触发..

制作滑出式。确保单击文档,然后向顶部滚动

jsFiddle

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: "\2715";
}

.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;
}

我发现了一些其他的答案,它们的作用类似于我在延迟触发事件时的想法。

例一 例二

我一直在使用它,但由于代码较旧(几个月前)而且我仍然相对较新。我正在学习需要: - 对正在做什么做出更好的评论 - 确保在构建解决方案时彻底了解您正在使用的代码。

感谢您的帮助,我将继续尝试调整它,但找不到任何可行的具体方法。

标签: javascriptjquerysettimeoutdelaymouseleave

解决方案


我想我能做到。
不过,我不太明白你所说的变量是什么意思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);

推荐阅读