根据窗口宽度在Superfish和FlexNav之间切换
Switch between Superfish and FlexNav depending on window width
我正在尝试在一个页面上使用 2 个jQuery
导航脚本(Superfish
用于桌面,FlexNav
用于移动设备(。我目前正在使用 matchMedia
以及 Paul Irish 的polyfill
来响应 CSS3
JavaScript
中的媒体查询状态更改。
当前的代码只完成了总体目标的 50%。如果您最初访问窗口大小等于或大于 999px 宽的网页,那么您将获得Superfish
,如果您最初访问窗口大小小于 999px 的网页,那么您将获得FlexNav
。当您将窗口大小调整为 999px 以上或以下时,两个脚本都处于活动状态时,会出现此问题。
// media query event handler
if (matchMedia) {
var mq = window.matchMedia("(min-width: 999px)");
mq.addListener(WidthChange);
WidthChange(mq);
}
// media query change
function WidthChange(mq) {
if (mq.matches) {
$("ul.sf-menu").superfish({
delay: 350,
speed: 400,
});
} else {
$("ul.flexnav").flexNav({
'animationSpeed': '250',
'transitionOpacity': true,
'buttonSelector': '.menu-button',
'hoverIntent': false
});
}
}
尽管我想让它与matchMedia
一起工作,但我对所有建议都持开放态度。
更新:感谢斯蒂芬的建议,我现在有以下代码:
jQuery(document).ready(function () {
// add destroy function for FlexNav
flexNavDestroy = function () {
$('.touch-button').off('touchstart click').remove();
$('.item-with-ul *').off('focus');
}
// media query event handler
if (matchMedia) {
var mq = window.matchMedia("(min-width: 999px)");
mq.addListener(WidthChange);
WidthChange(mq);
}
// media query change
function WidthChange(mq) {
if (mq.matches) {
if (typeof (flexNav) != "undefined") {
flexNavDestroy();
}
superfish = $("ul.sf-menu").superfish({
delay: 350,
speed: 400,
});
} else {
if (typeof (superfish) != "undefined") {
superfish.superfish('destroy');
}
flexNav = $("ul.flexnav").flexNav({
'animationSpeed': '250',
'transitionOpacity': true,
'buttonSelector': '.menu-button',
'hoverIntent': false
});
}
}
});
剩余问题:FlexNav
的销毁功能只是部分销毁它。
最好的方法可能是在激活另一个插件时销毁另一个插件。
如果我查看Superfish的源代码,则有一个销毁函数可以做到这一点,但是flexNav没有这样的功能。不过,您可以创建一个:
flexNavDestroy = function(){
$('.touch-button').off('touchstart click').remove();
$(('.item-with-ul *').off('focus');
}
然后你可以这样做:
function WidthChange(mq) {
if (mq.matches) {
if(typeof(flexNav) != "undefined") {
flexNavDestroy();
}
superfish = $("ul.sf-menu").superfish({
delay: 350,
speed: 400,
});
} else {
if(typeof(superfish) != "undefined") {
superfish.superfish('destroy');
}
flexNav = $("ul.flexnav").flexNav({
'animationSpeed': '250',
'transitionOpacity': true,
'buttonSelector': '.menu-button',
'hoverIntent': false
});
}
}
更新我对 FlexNav 进行了更多的研究,我错过了一些东西。
我认为样式正在冲突,因为默认情况下 FlexNav 设置了很多样式。我们可以通过使用两个类来轻松防止这种情况:一个用于 flexnav 样式(默认.flexnav
(,我们可以将其删除以隐藏其所有样式,另一个用于绑定 javascript 函数(将始终保留在那里,否则我们无法重新附加它(。
我通常喜欢在 js-
前面附加任何作为 JS 钩子的类,因此在我的示例中(如下(我将菜单上的.flexnav
类替换为 .js-flexnav
。然后要激活 flexnav,您必须在调用$('ul.flexnav').flexNav()
之前添加此行
$('.js-flexnav').addClass('flexnav');
在 destroy 函数中,您将不得不再次删除该类,我将很快显示该类。
此外,我不确定Superfish如何显示和隐藏,但是由于FlexNav折叠了所有子菜单,因此也可以肯定地说您应该重新显示它们,以便Superfish可以自己做
。更新的销毁函数反映了这一点:
function flexNavDestroy(){
$('.touch-button').off('touchstart click').remove();
$('.item-with-ul *').off('focus');
$('.js-flexnav').removeClass('flexnav').find('ul').show(); // removes .flexnav for styling, then shows all children ul's
}
下面是一个jsFiddle,显示了使用新代码激活/停用flexNav:http://jsfiddle.net/9HndJ/
让我知道这是否适合您!
这是一条替代路径:
页面加载后:
将菜单缓存在jQuery对象中,克隆它并在每个克隆上实例化两个插件
$menucontainer= $("#menu_container");
$memufish = $menucontainer.find(".menu");
$menuflex=$menufish.clone();
$menufish.superfish().detach();
$menuflex.prependTo($menucontainer).flexnav().detach();
(无论如何它们都是加载的,所以即使大多数时候不需要也没什么大不了的,它会在那里并准备好以防万一 - 但是测试您是否可以在克隆上实例化而不将其附加到 DOM (
根据宽度附加/预置所需的一个
$menuflex.prependTo($menucontainer);
在更改宽度时,分离一个重新连接另一个
$menufish.detach();
$menuflex.prependTo($menucontainer);
您也可以按照自己的方式检查插件是否在宽度更改时实例化(为了不无用地实例化加载(,但无论如何我相信使用 clone()
和 detach()
非常适合轻松解决您的问题。销毁方式似乎很麻烦,大量的工作(对于脚本以及当某些用户对窗口大小调整赞不绝口时(时间损失和许多错误的风险对我来说(预计每次销毁重新实例化时都会有越来越多的滞后 - detach()
不用担心(
缺点 : 将使用更多的内存大修
优点 :
脚本将减少工作,从一个切换到另一个将非常快
您可以从中制作一个插件,并非常轻松地将其他菜单插件添加到您的应用程序中,而不必担心冲突以及如何破坏
- 函数参数中的数据与指定变量之间的任何性能差异
- 全局变量和全局对象的属性之间有什么区别吗
- java.net和javascript之间正则表达式的差异
- JavaScript中的函数和对象之间没有区别吗?
- 获取@ResponseBody的一部分作为主干和Spring MVC控制器之间的参数
- Jquery在函数之间传递表行
- 根据某些条件在视图之间切换
- 在控制器和数据对象之间同步数据
- d3中堆栈函数和嵌套函数之间的差异
- JQuery:在页面之间滑动
- 如何使用JavaScript查找1和N之间的所有数字的总和
- 操作放置在画布上的元素之间的连接
- 在下划线中使用_(obj).map(callback)和_.map(obj,callback)之间的区别
- jquery在表单之间切换
- Nodejs API控制器,用于在API之间切换
- 如何在aspx页面之间传递参数
- 在索引.html和应用.js [node.js] 之间共享变量
- 什么是&&在没有if的行中的变量之间
- DOM元素和angular元素之间的主要区别是什么
- 根据窗口宽度在Superfish和FlexNav之间切换