【问题标题】:Mouseenter and mouseleave - wait a moment before triggering function?Mouseenter 和 mouseleave - 在触发功能之前稍等片刻?
【发布时间】:2019-10-16 21:43:38
【问题描述】:

我有一个元素,我想在用户鼠标移入或移出时更改其 CSS。一些触发它的函数,很简单:

function expandDiv(){
  div1.classList.add('expanded')
}

function shrinkDiv(){
  div1.classList.remove('expanded')
}

但是,我希望用户在函数实际触发之前快速悬停在(或远离)该元素上(例如 200 毫秒)。这是为了可用性,因为快速通过元素不应触发该功能。这个问题在here 讨论过,我喜欢这个解决方案:

var delay = function (elem, callback) {
var timeout = null;
    elem.onmouseover = function() {
        // Set timeout to be a timer which will invoke callback after 1s
        timeout = setTimeout(callback, 1000);
    };

    elem.onmouseout = function() {
        // Clear any timers set to timeout
        clearTimeout(timeout);
    }
};

但是当回调函数是我的expandDiv()shrinkDiv() 函数时,此解决方案仅在一个方向上有效。我尝试使用delay() 结构简单地编写2 个函数并反转onmouseoutonmouseenter 事件:

// Delay functions
var delayIn = function (elem, callback) {
    var timeout = null;
    elem.onmouseover = function() {
        // Set timeout to be a timer which will invoke callback after 1s
        timeout = setTimeout(callback, 1000);
    };

    elem.onmouseout = function() {
        // Clear any timers set to timeout
        clearTimeout(timeout);
    }
};

var delayOut = function (elem, callback) {
    var timeout = null;
    elem.onmouseout = function() {
        // Set timeout to be a timer which will invoke callback after 1s
        timeout = setTimeout(callback, 200);
    };

    elem.onmouseover = function() {
        // Clear any timers set to timeout
        clearTimeout(timeout);
    }
};

delayIn(div1, expandDiv);
delayOut(div1, shrinkDiv);

但这不起作用。当 delayIn 和 delayOut 都被调用时,delayIn 函数什么也不做。请参阅此代码笔:

https://codepen.io/slutske22/pen/eYYzQqE?editors=0010

我不确定出了什么问题。 div 应该在鼠标悬停一秒后展开,除非您在第二秒结束之前将鼠标悬停。但它什么也没做。我添加了一个“Expand the Div”按钮来强制它,你可以看到,如果你然后将鼠标悬停在 div 上并鼠标移出,它确实会从 shrinkDiv 函数中缩小,但是没有延迟,因为应该有延迟输出函数。

我也试图将此行为链接到一个按钮。有一个“缩小 div”按钮。期望的行为是您单击按钮,并且在定义的 setTimout 延迟之后 div 将缩小,除非您在超时完成之前鼠标输入 div。这也不会发生。

我觉得这是一个相对简单的任务,但它让我望而却步。我想学习如何在没有 jQuery 的情况下做到这一点。我也意识到这可能应该是this thread 中的一个推荐,但我是新手,还不能发表评论。对不起,如果这是不好的形式。

【问题讨论】:

  • 您在delayIn 中分配的onmouse* 处理程序在delayOut 中被覆盖

标签: javascript css hover settimeout cleartimeout


【解决方案1】:

您在 delayIn 中分配的 onmouse* 处理程序会在 delayOut 中被覆盖 - 这就是为什么只有一个“动画”会做它应该做的事情

var div1 = document.querySelector('#div1')
var button = document.querySelector('#button')


function expandDiv(){
  div1.classList.add('expanded')
}

function shrinkDiv(){
  div1.classList.remove('expanded')
}


var delayInOut = function(elem, incb, outcb) {
    var timeout = null;
    var clearto = function() {
      clearTimeout(timeout);
      timeout = null;
    };
    elem.onmouseover = function() {
      clearto();
      timeout = setTimeout(incb, 1000);
    }
    elem.onmouseout = function() {
      clearto();
      timeout = setTimeout(outcb, 200);
    }
}
delayInOut(div1, expandDiv, shrinkDiv);


expandButton.onclick = expandDiv

shrinkButton.addEventListener("click", function(){
  var timeout = setTimeout(shrinkDiv, 1000);
}, false)
body{
  position: relative;
  padding: 0px;
  margin: 0px;
}
#div1{
  position: absolute;
  top: 20px;
  left: 20px;
  right: 20px;
  height: 50px;
  background-color: darkblue;
  transition: height 1s;
}
#div1.expanded{
  height: 70px;
}

#expandButton{
  position: absolute;
  left: 20px;
  top: 100px;
}
#shrinkButton{
  position: absolute;
  left: 20px;
  top: 125px;
}
<body>
  <div id="div1"></div>
  <button id="expandButton">Expand Div</button>
  <button id="shrinkButton">Shrink Div After Delay</button>
</body>

作为一个兴趣点,您可以在没有 javascript 的情况下实现这一点,包括扩展和收缩的不同延迟:

body{
  position: relative;
  padding: 0px;
  margin: 0px;
}
#div1{
  position: absolute;
  top: 20px;
  left: 20px;
  right: 20px;
  height: 50px;
  background-color: darkblue;
  transition: height 1s ease-in-out 200ms;
}
#div1:hover{
  transition-delay:1s;
  height: 70px;
}
<body>
  <div id="div1"></div>
</body>

【讨论】:

  • 您的delayInOut 正在为我工​​作。谢谢!我也能够消除 if 语句,至少现在是这样。 css 中定义的延迟很好,但是如果您将鼠标移回或移出 div,它不会禁用转换。可以?您将如何解决有关按钮的问题?按下按钮后,div 将在 x 毫秒内缩小,除非您将鼠标移入 div?我觉得我需要一个单独的函数,不是吗?
  • 是的,我不确定是否需要 if 语句 @SethLutske - 从代码中删除它们
  • @SethLutske - 我以为你的按钮是用来测试的……当然,如果你需要像你的代码这样的按钮,那么只有 CSS 的解决方案就行不通
猜你喜欢
  • 2019-06-17
  • 1970-01-01
  • 1970-01-01
  • 2019-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多