Django网站移动端下拉菜单需双击跳转问题修复求助
移动端下拉菜单需双击跳转问题修复
问题现象
使用Django框架开发站点时,页面桌面端响应式效果符合设计预期,但切换到移动端访问模式时,下拉菜单需要双击才能跳转到目标链接:单击操作只会触发类似hover的展开效果,代码中未编写对应hover触发逻辑。此前尝试使用@media (pointer: fine) {}方案修复时,出现下拉菜单常显、无法正常收起的问题。
原有实现代码
HTML部分
<div class="dropdown-toggle" role="button" data-toggle="dropdown" aria-expanded="true"> <strong class="text-uppercase">{{ user.username }} <i class="fa fa-caret-down"></i></strong> </div> <ul class="custom-menu"> <li><a href="{% url 'account' %}">{% "Account" %}</a></li> <li><a href="{% url 'orders' %}"></i> {% "Orders " %}</a></li> <li><a href="{% url 'logout' %}"> {% "Logout" %}</a></li> </ul>
注:上述HTML中Orders链接内存在多余的
</i>闭合标签,无对应开标签,会造成DOM解析异常,建议直接删除。另外模板中{% "Account" %}类写法不符合Django模板语法,若做国际化需改为{% trans "Account" %},该语法问题不影响本次点击逻辑。
CSS部分
.custom-menu { position: absolute; padding: 15px; background: #FFF; -webkit-box-shadow: 0px 6px 12px rgba(0, 0, 0, 0.175); box-shadow: 0px 6px 12px rgba(0, 0, 0, 0.175); z-index: 100; top: 100%; min-width: 200px; opacity: 0; visibility: hidden; -webkit-transition: 0.3s all; transition: 0.3s all; } .dropdown.open>.custom-menu { opacity: 1; visibility: visible; }
问题根因
移动端浏览器对触摸点击会模拟一套兼容桌面端的事件序列:第一次触摸元素时,优先触发hover状态、给元素加对应状态类,不会触发内部链接的click跳转事件;第二次触摸才会正式触发点击跳转。
之前使用pointer: fine媒体查询失效,是因为错误将下拉菜单的基础显隐规则全部包裹进了仅适配鼠标设备的媒体查询块,导致移动端加载不到菜单隐藏的默认样式,出现菜单常显无法收起的问题。
修复方案
- 调整CSS结构:将菜单基础显隐规则放在全局样式中,仅把「桌面端hover自动展开菜单」的逻辑放进
pointer: fine媒体查询块,确保移动端和桌面端都能正确读取到菜单默认隐藏、父级带open类时显示的核心规则。修正后完整CSS如下:
.custom-menu { position: absolute; padding: 15px; background: #FFF; -webkit-box-shadow: 0px 6px 12px rgba(0, 0, 0, 0.175); box-shadow: 0px 6px 12px rgba(0, 0, 0, 0.175); z-index: 100; top: 100%; min-width: 200px; opacity: 0; visibility: hidden; -webkit-transition: 0.3s all; transition: 0.3s all; } .dropdown.open > .custom-menu { opacity: 1; visibility: visible; } /* 仅带精确定位指针的设备(鼠标、触控板)支持hover触发 */ @media (pointer: fine) { .dropdown:hover > .custom-menu { opacity: 1; visibility: visible; } }
- 增加触摸设备专属JS逻辑,拦截默认的事件冒泡,实现第一次点击展开菜单、点击菜单项直接跳转、点击页面其他区域关闭菜单的逻辑,避免需要双击的问题:
const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0; if (isTouchDevice) { // 下拉触发器触摸逻辑 const toggle = document.querySelector('.dropdown-toggle'); toggle.addEventListener('touchstart', function(e) { const parent = this.closest('.dropdown'); // 关闭其他已打开的下拉 document.querySelectorAll('.dropdown.open').forEach(item => { if (item !== parent) item.classList.remove('open'); }); // 切换当前下拉状态 parent.classList.toggle('open'); e.preventDefault(); }); // 点击菜单项直接跳转,阻止冒泡 document.querySelectorAll('.custom-menu a').forEach(link => { link.addEventListener('touchstart', function(e) { e.stopPropagation(); window.location.href = this.href; }); }); // 点击非下拉区域关闭菜单 document.addEventListener('touchstart', function(e) { if (!e.target.closest('.dropdown')) { document.querySelectorAll('.dropdown.open').forEach(item => item.classList.remove('open')); } }); }
内容的提问来源于stack exchange,提问作者user18532068
相关产品推荐
相关产品推荐

