0

版本 1. 编辑版本如下

这是我最初拥有的一个非常基本的表示,我似乎无法得到比这更短的,所以我很抱歉代码负载。我评论了问题可能出在哪里。

扩展小提琴:http: //jsfiddle.net/BramVanroy/tKL8E/53/

如您所见,有一个可以悬停的菜单。在普通视图(水平菜单)中,将出现代表链接标题的工具提示(基本上,修改后的工具提示)。当您将窗口大小调整为 < 800 时,菜单应变为垂直(媒体查询)。问题是,在 if 函数中调用的函数仍然有效。修改后的工具提示不断出现并具有动画效果(而不是标准工具提示),并且箭头仍在定位。

function triangleMenu() {
  var wW = $(window).width();
  if (wW > 800) {
    // Get rid of [title]'s and put them in data unless it has sub-items
    $("li:not(.has-sub-menu) > a[title]").each(function () {
      var $this = $(this);
      $this.data("title", $this.attr("title"));
      $this.removeAttr("title");
    });

    // tooltip positioning on hover and overlay fade on all li's
    $("nav li").hover(function () {
      // Bunch of vars

      if (
      ($this.parent("ul:not(.sub-menu)").length || ($this.parent("ul.sub-menu").length && $this.is(":last-child"))) && !$this.hasClass("has-sub-menu")) {

        tooltip.stop(true).css("right", "auto").text(title).animate({
          "left": posL - (tooltip.width() / 2),
            "top": posT + $this.offset().top + 20
        }, 300).fadeTo(200, 1);
      } else if (!$this.is(":last-child") && $this.parent("ul.sub-menu").length) {
        var condition = offL > ((wW / 2) - $this.width()),
          properties = {},
          cssProp = {};

        tooltip.stop(true).text(title);
        if (condition) {
          properties = {
            "left": (offL - tooltip.width() - 30)
          };
        } else {
          properties = {
            "left": (offL + $this.width() + 25)
          };
        }
        $.extend(properties, {
          "top": ($this.offset().top + (posT / 2) - (tooltip.height() / 2))
        });

        tooltip.animate(properties, 300).fadeTo(200, 1); // SO TOOLTIP ANIMATES, BUT ONLY WHEN WINDOW WIDTH EXCEEDS 800
      }
    },function () {
    });
  } else { // IF WINDOW IS TIGHTER THAN 800 PX
    // Put data back
    $("li:not(.has-sub-menu) > a").each(function () {
      var $this = $(this),
        title = $this.data("title");

      $this.attr("title", title);
    });
  }
}

triangleMenu();

$(window).resize(function () {
  triangleMenu();
});

再一次,我很抱歉这个例子的广泛性,但是在不丢失不起作用的功能的情况下进一步减少它是完全不可能的。


新:版本 2

在一些帮助和大量测试和含糖饮料的帮助下,我的“主菜单”开始工作了。调整大小的(移动/响应)菜单虽然不起作用。

新小提琴

当调整到较小的菜单时(您可能需要调整两次,更小,更大,更小),您应该能够通过单击打开具有子菜单的项目,但这不起作用。单击 li 时,子项会得到一堆内联样式,但我不知道它们来自哪里!

overflow: hidden; display: none; height: 159px; padding-top: 0px; margin-top: -2px; padding-bottom: 0px; margin-bottom: 0px;

我认为他们阻止了菜单显示,但我似乎无法找到他们的原因。

4

2 回答 2

1

我不是这方面的专家,但我找到了解决您问题的方法。经过大量测试后,我发现,在某种 if 状态下触发的部分函数仍然处于绑定状态。我发现是因为:

  1. $(window).resize()正在触发该功能;
  2. 初始窗口大小按预期工作;
  3. 但是在调整大小后,该功能似乎仍然存在。

我得出的结论是存在一个约束性问题,我尝试了这个并且它起作用了:在 else 语句中,我添加了这个第一行$("nav li").unbind('hover');。这摆脱了仍然绑定到元素的悬停功能。

但后来我意识到箭头也在持续。为了解决这个问题,我不得不添加两行代码。首先,我在 else 语句中添加了: $("ul:not(.sub-menu) > li, ul.sub-menu > li:last-child").removeClass("over-down");.

但这还不够,我还移入$("ul:not(.sub-menu) > li, ul.sub-menu > li:last-child").not(":has(ul.sub-menu)").addClass("over-down");$("nav li").hover()函数,将其转换为更简单的:

$(this).addClass("over-down");.

我不知道这是否是最优雅的解决方案,但它似乎有效。我希望专家能更好地解释这一点。

您可能会发现更多错误,但我认为这将帮助您解决此功能的其他问题。也许改变一些逻辑和步骤会做一个更健壮的代码。

PS:在 Chrome 中调整窗口大小时,菜单高度仍然存在一些问题。

于 2013-01-18T21:06:57.650 回答
1

基于您的新:版本 2

您缺少的重要内容是,$("nav li.has-sub-menu")在调整大小时绑定了太多相同的单击功能。

console.log(1)我在点击处理程序中添加一个,如下所示:

    $("nav li.has-sub-menu").click(function () {                                                                               
        var $this = $(this);
        console.log(1);
        $this.children("ul.sub-menu").stop(true).slideToggle("fast");
    }); 

它会打印很多1,我认为你不例外。

而且更重要的是,来电次数console.log(1);总是偶数,真不知道为什么。但这意味着您的子菜单一次又一次地显示/隐藏,然后最终隐藏。)

所以我在绑定之前取消绑定所有点击功能,通过添加以下代码。有用。看这里

$("nav li.has-sub-menu").unbind("click");

然后我想说的另一点,在function中triangleMenu,所有代码都会在调整大小时执行多次。

所以我想我们可以在这里添加一个布尔变量来保存它是 now> 800< 800,所以只有当这个变量发生变化时我们才能执行所有代码。

我执行如下:

var is_mobile;

function triangleMenu(){
    var wW = $(window).width();
    if (wW > 800 && (is_mobile === undefined || is_mobile)) {
       console.log('change to pc');
       is_mobile=false;
       //your code here
    } else if(wW <=800 && !is_mobile) {
       console.log('change to mobile');
       is_mobile=true;
       //your code here
    }
}

是jsfiddle。

更新

您知道为什么多次记录点击吗?这么奇怪?

因为当你调整浏览器的大小时,$(window).resize会一直被调用。您可以添加一个console.log进行检查,如下所示:

$(window).resize(function () {
    console.log('resizing');                                                                                                       
    triangleMenu();
});

你能解释一下 is_mobile 变量吗?

关于这一点,您可以将上面的代码与之前的代码进行比较,如下所示:

function triangleMenu(){
    var wW = $(window).width();
    if (wW > 800 ) {
       console.log('change to pc');
       //your code here
    } else {
       console.log('change to mobile');
       //your code here
    }
}

它会做的更少console.log,这意味着可以避免 js 重复做同样的事情。

is_mobile意味着,虽然wW现在是>800,无论在调整大小时它的宽度有多精确,我都设置is_mobilefalse,所以我不需要重复初始化和绑定。只有 ifwW是 first <=800,我设置is_mobiletrue,标记我现在要更改为移动大小,然后执行初始化和绑定。在这些之后,我不需要做 init 和 bind agin,只要wW<=800. 反之亦然。

我的英文不是很好,不知道解释清楚了没有。

于 2013-01-23T08:47:51.407 回答