【问题标题】:How do I add a delay for hovering an element in angularjs?如何添加延迟以在 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 小时。我会回来的!

【问题讨论】:

    标签: javascript angularjs hover hoverintent


    【解决方案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 );
            
                                }
                            );
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-12-14
              • 2018-01-19
              • 2012-11-08
              • 2021-08-17
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-11-22
              相关资源
              最近更新 更多