【发布时间】:2014-01-16 02:50:09
【问题描述】:
我设计的一个网站使用了一个导航菜单,它在 :hover 上显示子菜单。最初的网站没有使用任何响应式设计:它只针对桌面环境。我现在使用响应式设计技术来定位移动设备和平板电脑,其中许多是基于触摸而不是基于鼠标的。
我面临的最大问题(许多其他人似乎也面临过)是基于悬停的导航菜单:它在鼠标环境中运行良好,但在触摸设备上,没有可靠的方法来触发悬停,使页面难以使用。
目标是这样的:
- 当鼠标悬停在菜单上时,显示子菜单。
- 当用鼠标单击菜单时,打开锚标记的链接。
- 第一次通过触摸单击菜单时,显示子菜单。
- 第二次通过触摸单击菜单时,打开锚标记的链接。
- 为也连接了鼠标设备的平板电脑无缝切换功能。
我的团队不愿意在基于鼠标的机器上牺牲悬停效果。他们喜欢它,不想让菜单基于所有设备点击。我同意这一点。
环顾网络后,我找不到任何单一的解决方案来解决我的问题。我将其中的一些放在一起,开发了一些在 Android 上经过良好测试的东西,得到了我想要的功能。有什么可以改进的和/或您认为这种方法有什么问题吗?
jQuery(document).ready(function() {
var touched=false;
jQuery(".nav").on('touchstart', 'li .has_children', function (e) { touched=true; });
jQuery("html").on('mousemove', function (e) { touched=false; });
jQuery("html").on('click', updatePreviousTouched );
jQuery(".nav").on('click', 'li .has_children', function (e) {
updatePreviousTouched(e);
if( touched ) {
if (jQuery(this).data('clicked_once')) {
jQuery(this).data('clicked_once', false);
return true;
} else {
e.preventDefault();
jQuery(this).trigger("mouseenter");
jQuery(this).data('clicked_once', true);
}
}
touched=false;
});
var previous_touched;
function updatePreviousTouched(e) {
if( typeof previous_touched != 'undefined' && previous_touched != null && !previous_touched.is( jQuery(e.target) ) ) {
previous_touched.data('clicked_once', false);
}
previous_touched=jQuery(e.target);
}
}
这是一个 jfiddle:http://jsfiddle.net/5FfCF/1/
如果此解决方案可以改进,请提供任何建议。如果您发现它对您不起作用,也请告诉我。我在这里发布它是为了尝试获得任何改进建议并发布这个想法,以便其他人可以从中受益。
这是我目前的测试结果:
- Windows 7 在主要 5 种浏览器上:有效。
- 默认浏览器上的 Android 平板电脑:有效。
- 在 IE 和 Chrome 上带有触摸屏的 Windows 7 笔记本电脑:工作排序。该机器正在运行两种浏览器的桌面版本,因此它不会触发“touchstart”事件。在触摸屏和浏览器之间的某个地方,有些东西正在将触摸转换为鼠标事件。但是,由于鼠标是该设备的不可拆卸部分,我不认为这是失败的。如果它像平板电脑一样工作,我会喜欢它,但似乎还没有可用的技术。
- iOS iPad:这在我编写上面的 javascript 之前 可以正常工作。 ios 似乎在幕后为我们做了一些悬停/点击魔术。我有一个团队成员检查我的 javascript 是否破坏了 iOS 功能,一旦我得到答案,我将编辑这篇文章。
其他说明:
- 这只是桌面和平板电脑站点的菜单。移动网站有一个不同的基于点击的菜单。我不建议将此解决方案用于手机大小的设备。
【问题讨论】:
-
这个问题似乎是题外话,因为它是一个代码审查请求。这更适合codereview.stackexchange.com
-
大声笑,我被那该死的东西吞没了。这个网站我发誓它比破解更糟糕。
标签: javascript jquery html css responsive-design