Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/441.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript setTimeout/clearTimeout问题,不';似乎没有重置_Javascript_Jquery_Settimeout - Fatal编程技术网

Javascript setTimeout/clearTimeout问题,不';似乎没有重置

Javascript setTimeout/clearTimeout问题,不';似乎没有重置,javascript,jquery,settimeout,Javascript,Jquery,Settimeout,我试图创建当鼠标悬停在菜单名上时下拉的菜单。由于名称和菜单div不相邻,我需要一种方法来延迟菜单消失,这样用户就可以从名称移动到菜单本身。我为此使用了一个设置超时。一旦在菜单上悬停,我需要它保持打开状态,直到鼠标离开,然后它应该隐藏 我所尝试的完全是一团糟。我不知道怎么修。因为setTimeout在初始鼠标指针内,所以计时器在自身上循环。。。但是如果我把setTimeout放在其他地方,它似乎不起作用 代码如下: $(document).ready(function() { $('.head

我试图创建当鼠标悬停在菜单名上时下拉的菜单。由于名称和菜单div不相邻,我需要一种方法来延迟菜单消失,这样用户就可以从名称移动到菜单本身。我为此使用了一个设置超时。一旦在菜单上悬停,我需要它保持打开状态,直到鼠标离开,然后它应该隐藏

我所尝试的完全是一团糟。我不知道怎么修。因为setTimeout在初始鼠标指针内,所以计时器在自身上循环。。。但是如果我把setTimeout放在其他地方,它似乎不起作用

代码如下:

$(document).ready(function() {
  $('.headermenushow').mouseover(function () {
    $(this).next('.dropmenu').show(0, function () {
      timer = setTimeout(function() {
        $('.dropmenu').hide(10);
      }, 2000);
    });

    $(this).next('.dropmenu').mouseover(function () {
      clearTimeout(timer);
    });

  });
});
下面是一个简略的jsfiddle,显示了我希望如何使用它:


任何帮助都会很好。不太确定如何使其更好地工作…

此代码存在各种各样的问题:

  • 您正在
    .mouseover()
    事件中添加事件处理程序。这意味着每次出现mouseover事件时,都会添加另一组事件处理程序。当所有这些都执行时,它们会堆积起来,造成真正的混乱。每个活动对象只需要一组事件处理程序

  • 你的整个逻辑似乎有缺陷。只要鼠标停留在某个项目上,您就希望菜单保持下拉状态。mouseover事件仅在鼠标第一次移动到项目上时发生。当鼠标悬停在菜单上时,您没有任何方法将其保持在低位,因为您似乎只是在显示菜单2秒钟后盲目地将其隐藏,而不管鼠标是否仍在那里

  • 您正在为计时器使用隐式全局变量。这造成了一系列问题。首先,如果有多个
    .headermanushow
    对象,则每个对象的
    计时器将踩在其他对象上。第二个隐式全局变量很糟糕,很容易导致错误。在您想要的范围内精确地声明它

  • 你可以在计时器上安装计时器。无论何时将计时器保存到共享变量,都必须检查已运行的前一个计时器,或者在覆盖其变量之前停止任何前一个计时器。这可以防止丢失正在运行的计时器的轨迹,并防止堆积多个试图执行相同操作的计时器

  • 我们可能会帮助您编写更好的代码,但我们需要查看您的实际HTML并更好地理解您试图实现的行为

    仅供参考,您可能还需要查看CSS
    :hover
    选择器,该选择器允许您在悬停时显示/隐藏内容,而无需任何JS代码。因为我不知道你的HTML是什么样子,我不能肯定这是否适合你,但是很多菜单系统都使用它,如果做得好的话,它真的很简单


    现在您已经展示了您的HTML,下面是一个有效的版本。我必须说,很多这种javascript都是因为您的HTML并没有使它变得尽可能简单

    $(document).ready(function() {
        $(".headermenushow").hover(function() {
            // hide any previous dropdown menus
            $(".dropmenu").hide();
    
            var self = $(this);
            var timer = self.data("timer");
    
            // show the dropdown menu for this item
            self.next().show();
    
            // clear any previous timer for this menu
            if (timer) {
                clearTimeout(timer);
                self.data("timer", null);
            }
    
        }, function() {
            // hide only on a delay so that user can move
            // to the menu
            var self = $(this);
            var menu = self.next();
            var timer = self.data("timer");
            // clear any previous timer that might have been active
            if (timer) clearTimeout(timer);
            timer = setTimeout(function() {
                self.data("timer", null);
                // if mouse is not over the menu, then hide it
                if (!menu.data("hover")) {
                    menu.hide();
                }
            }, 500);
            self.data("timer", timer);
    
        });
    
        // keep track of hover state on the menu
        $(".dropmenu").hover(function() {
            $(this).data("hover", true);
        }, function() {
            $(this).data("hover", false);
            $(this).hide();
        });
    });
    

    工作演示:

    此代码存在各种各样的问题:

  • 您正在
    .mouseover()
    事件中添加事件处理程序。这意味着每次出现mouseover事件时,都会添加另一组事件处理程序。当所有这些都执行时,它们会堆积起来,造成真正的混乱。每个活动对象只需要一组事件处理程序

  • 你的整个逻辑似乎有缺陷。只要鼠标停留在某个项目上,您就希望菜单保持下拉状态。mouseover事件仅在鼠标第一次移动到项目上时发生。当鼠标悬停在菜单上时,您没有任何方法将其保持在低位,因为您似乎只是在显示菜单2秒钟后盲目地将其隐藏,而不管鼠标是否仍在那里

  • 您正在为计时器使用隐式全局变量。这造成了一系列问题。首先,如果有多个
    .headermanushow
    对象,则每个对象的
    计时器将踩在其他对象上。第二个隐式全局变量很糟糕,很容易导致错误。在您想要的范围内精确地声明它

  • 你可以在计时器上安装计时器。无论何时将计时器保存到共享变量,都必须检查已运行的前一个计时器,或者在覆盖其变量之前停止任何前一个计时器。这可以防止丢失正在运行的计时器的轨迹,并防止堆积多个试图执行相同操作的计时器

  • 我们可能会帮助您编写更好的代码,但我们需要查看您的实际HTML并更好地理解您试图实现的行为

    仅供参考,您可能还需要查看CSS
    :hover
    选择器,该选择器允许您在悬停时显示/隐藏内容,而无需任何JS代码。因为我不知道你的HTML是什么样子,我不能肯定这是否适合你,但是很多菜单系统都使用它,如果做得好的话,它真的很简单


    现在您已经展示了您的HTML,下面是一个有效的版本。我必须说,很多这种javascript都是因为您的HTML并没有使它变得尽可能简单

    $(document).ready(function() {
        $(".headermenushow").hover(function() {
            // hide any previous dropdown menus
            $(".dropmenu").hide();
    
            var self = $(this);
            var timer = self.data("timer");
    
            // show the dropdown menu for this item
            self.next().show();
    
            // clear any previous timer for this menu
            if (timer) {
                clearTimeout(timer);
                self.data("timer", null);
            }
    
        }, function() {
            // hide only on a delay so that user can move
            // to the menu
            var self = $(this);
            var menu = self.next();
            var timer = self.data("timer");
            // clear any previous timer that might have been active
            if (timer) clearTimeout(timer);
            timer = setTimeout(function() {
                self.data("timer", null);
                // if mouse is not over the menu, then hide it
                if (!menu.data("hover")) {
                    menu.hide();
                }
            }, 500);
            self.data("timer", timer);
    
        });
    
        // keep track of hover state on the menu
        $(".dropmenu").hover(function() {
            $(this).data("hover", true);
        }, function() {
            $(this).data("hover", false);
            $(this).hide();
        });
    });
    

    工作演示:

    您能为我们提供一个JSFIDLE吗?我们需要查看您的HTML并更好地理解您想要实现的目标。就目前的情况而言,很明显,您当前的代码存在许多错误,但不清楚您到底想做什么。添加的JSFIDLE-应该演示我想如何使用它。您可以为我们提供一个JSFIDLE。我们需要查看您的HTML,更好地理解您正试图完成的任务。就目前的情况而言,很明显,您当前的代码存在许多错误,但不清楚您到底想做什么。添加的JSFIDLE-应该演示我想如何使用它是的,有很多问题