版本1.以下版本
这是我最初拥有的非常基本表示,我似乎无法比它更短,所以我很抱歉代码加载。我评论了问题可能存在的地方。
扩展小提琴:http://jsfiddle.net/BramVanroy/tKL8E/53/
如您所见,有一个可以悬停的菜单。在普通视图(水平菜单)中,将出现工具提示,表示链接的标题(基本上,修改后的工具提示)。当您将窗口大小调整为< 800,菜单应该变为垂直(媒体查询)。问题是,在if-function中调用的函数仍然有效。修改后的工具提示会一直显示并显示动画(而不是标准工具提示),箭头仍处于定位状态。
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;
我认为他们停止显示菜单,但我似乎找不到它们的原因。
答案 0 :(得分:1)
我不是这方面的专家,但我找到了解决问题的方法。经过大量测试后,我发现,不知何故,在其中一个if状态中触发的部分函数仍保持绑定状态。我发现因为:
$(window).resize()
触发了该功能; 我得出的结论是存在绑定问题,我尝试了这个并且它有效:在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中调整窗口大小时,菜单高度仍然存在一些问题。
答案 1 :(得分:1)
基于 NEW:VERSION 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);
的数量总是均匀,我真的不知道为什么。但这意味着您的子菜单会一次又一次地显示/隐藏,然后最终隐藏。)
因此,我通过添加以下代码在绑定之前取消绑定所有单击函数。有用。见here
$("nav li.has-sub-menu").unbind("click");
然后我要说的另一点是,在函数triangleMenu
中,所有代码都会在调整大小时执行多次。
所以我认为我们可以在这里添加一个布尔变量来保存它现在是> 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
}
}
Here 是jsfiddle。
<强>更新强>
您是否知道为何多次录制点击?这太奇怪了?
因为在调整浏览器大小时,将始终调用$(window).resize
。
您可以添加console.log
进行检查,如下所示:
$(window).resize(function () {
console.log('resizing');
triangleMenu();
});
你能解释一下is_mobile var吗?
关于这一点,您可以将上面的代码与您的代码进行比较,如下所示:
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_mobile
设置为false
,所以我不需要重复执行init和绑定。仅当wW
是<=800
时,我才将is_mobile
设置为true
,标记我现在要更改为移动设备大小,然后执行init和bind。在这些之后,只要wW
为<=800
,我就不需要执行init和绑定agin。反之亦然。
我的英语不是很好,我不知道我是否解释清楚。