如何添加延迟以在 angularjs 中悬停元素?
Posted
技术标签:
【中文标题】如何添加延迟以在 angularjs 中悬停元素?【英文标题】:How do I add a delay for hovering an element in angularjs? 【发布时间】:2014-09-10 05:27:35 【问题描述】:我有一个元素:
<span ng-mouseenter="showIt()" ng-mouseleave="hideIt()">Hover Me</span>
<div class="outerDiv" ng-show="hovering">
<p>Some content</p>
<div class="innerDiv">
<p>More Content</p>
</div>
</div>
这里是 JS:
// mouseenter event
$scope.showIt = function ()
$scope.hovering = true;
;
// mouseleave event
$scope.hideIt = function ()
$scope.hovering = false;
;
我希望能够为悬停事件设置 500 毫秒的延迟。
我已经有了这个问题的答案,但我不能再发布 8 小时。我会回来的!
【问题讨论】:
【参考方案1】:就像这里大多数人已经提到的那样,我在 mouseenter 事件中添加了一个计时器。
// create the timer variable
var timer;
// mouseenter event
$scope.showIt = function ()
timer = $timeout(function ()
$scope.hovering = true;
, 500);
;
我遇到的问题是,如果我滚动过该项目并且鼠标光标击中它,那么半秒后仍然会出现弹出窗口。我希望能够滚动过去一个项目而不会意外发生弹出窗口。
将超时设置在变量中允许我取消超时。我在鼠标离开事件中执行此操作以确保用户不会意外触发弹出窗口。
// mouseleave event
$scope.hideIt = function ()
$timeout.cancel(timer);
$scope.hovering = false;
;
这是一个小提琴,以防有人想看到它的实际效果: jsfiddle
【讨论】:
【参考方案2】:我建议使用 CSS 过渡和 angular-animate:
JS
var app = angular.module('app', ['ngAnimate']);
CSS
.outerDiv.ng-hide-remove
-webkit-transition: 0.5s linear all;
transition: 0.5s linear all;
transition-delay: 0.5s;
opacity: 0;
.outerDiv.ng-hide-remove.ng-hide-remove-active
opacity: 1;
HTML
<span ng-mouseenter="hovering=true" ng-mouseleave="hovering=false">Hover Me</span>
<div class="outerDiv" ng-show="hovering">
<p>Some content</p>
<div class="innerDiv">
<p>More Content</p>
</div>
</div>
Demo Plunker
【讨论】:
【参考方案3】:使用$timeout:
$scope.showIt = function ()
$timeout(function()
$scope.hovering = true;
, 500);
;
不要忘记将其添加为依赖项。
如果您想多玩一些,您可以创建自己的指令,例如 delayedMouseEnter
,其中包含延迟并改用它。
【讨论】:
【参考方案4】:window.setTimeout
在指定延迟后调用函数或执行代码sn-p。
$scope.hideIt = function ()
window.setTimeout(function()
$scope.hovering = false;
$scope.$apply();
, 500); // 500ms delay
;
或 Angular $timeout
服务:
$scope.hideIt = function ()
$timeout(function()
$scope.hovering = false;
, 500); // 500ms delay
;
【讨论】:
推荐使用$timeout
服务而不是setTimeout
,因为它允许测试并自动调用$scope.$apply()
,这在此代码中是缺失的。
因为他回答说我还不能发布我使用 $timeout 然后在 mouseleave 上取消它。 link【参考方案5】:
我为此写了一个简单的指令。
(function ()
'use strict';
angular
.module('app')
.directive('scHover', scHoverDirective);
function scHoverDirective($timeout)
return
link: function(scope, element, attrs, modelCtrl)
var inTimeout = false;
var hoverDelay = parseInt(attrs.scHoverDelay, 10) | 1000;
element.on('mouseover', function ()
inTimeout = true;
$timeout(function ()
if (inTimeout)
scope.$eval(attrs.scHover);
inTimeout = false;
, hoverDelay);
);
element.on('mouseleave', function ()
inTimeout = false;
scope.$apply(function ()
scope.$eval(attrs.scHoverEnd);
);
);
)();
使用示例(sc-hover-delay 是可选的):
<div sc-hover='vm.title="Hovered..."' sc-hover-end='vm.title=""' sc-hover-delay="800">Hover me! vm.title </div>
这里是一个笨蛋:http://plnkr.co/edit/iuv604Mk0ii8yklpp6yR?p=preview
【讨论】:
【参考方案6】:感谢您提出这个问题,因为这个示例帮助我理解 $timeout 的工作原理比 AngularJS 的文档做得更好。不过,我确实在正确答案上稍微改进了操作,想在这里分享一下。
您永远不必创建一个名为 timer 的空变量。事实上,这样做会耗尽你不必这样做的内存。你有一个变量和两个函数来处理实际上是一个单一的操作。
所以,我所做的是创建一个名为“toggleHover”的函数,它接受一个名为“bool”的布尔参数。然后一个 if/else 语句确定您需要运行哪个 $timeout 函数。
AngularJS 在控制器中
$scope.hovering = false; //Sets the initial state of hover
$scope.toggleHover = function (bool)
if (bool === true)
$timeout(function ()
$scope.hovering = !$scope.hovering;
, 500);
else
$timeout(function()
$scope.hovering = !$scope.hovering;
, 500);
;
html/视图
<span ng-mouseenter="toggleHover(true)" ng-mouseleave="toggleHover(false)">Hover Me</span>
示例
http://jsfiddle.net/89RTg/12/
【讨论】:
对不起,如果我没有得到这个 .. 查看您的代码,您甚至不需要布尔值,除非您想更改进入与离开的时间。但是如果你这样做,并且离开比进入更快,你需要清除进入的超时时间(或者它可能会在你离开后触发)。这就是为什么你需要这个变量。 为什么还需要 if else ?两者都在做同样的事情吗?【参考方案7】:你好,上面的答案很好 只是想添加,如果需要,当您将鼠标悬停并且它仍然没有触发或您销毁指令时,请不要忘记取消您的计时器
$timeout.cancel( timer );
$scope.$on("$destroy",
function( event )
$timeout.cancel( timer );
);
【讨论】:
以上是关于如何添加延迟以在 angularjs 中悬停元素?的主要内容,如果未能解决你的问题,请参考以下文章