JS多帖子下拉菜单显示异常:点击任意菜单均出现在顶部帖子下方的修复
修复帖子下拉菜单对应错误的问题
我在给网站的用户帖子做下拉菜单,用来实现分享、保存、删除功能,但不管点哪个帖子的下拉按钮,菜单都只显示在页面顶部的帖子下面,怎么让每个菜单对应自己的帖子?
原代码
PHP输出的HTML及JS
<div class="postBox"> <img class="postprofilepicture" src="../profilepictures/'.$ProfilePicture.'"> <a class="postusername" href="../user?page='.$UserName.'">'.$UserName.'</a> <p class="posttime">'.date('M jS, Y h:ia',strtotime($Date)).'</p> <p>'.$Text.'</p> <div class="dropdown"> <button onclick="myFunction()" class="dropbtn">···</button> <div Id="myDropdown" class="dropdown-content"> <a href="#home">Home</a> <a href="#about">About</a> <a href="#contact">Contact</a> <a href="#contact">4</a> <a href="#contact">5</a> <a href="#contact">6</a> </div> </div> </div> <br> <script> function myFunction() { document.getElementById("myDropdown").classList.toggle("show"); } window.onclick = function(event) { if (!event.target.matches(".dropbtn")) { var dropdowns = document.getElementsByClassName("dropdown-content"); var i; for (i = 0; i < dropdowns.length; i++) { var openDropdown = dropdowns[i]; if (openDropdown.classList.contains("show")) { openDropdown.classList.remove("show"); } } } } </script>
CSS
.dropbtn { color: #c42222; font-size: 30px; font-weight: bolder; border: none; cursor: pointer; right: 50px; } .dropbtn:hover, .dropbtn:focus { background-color: #f1f1f1; } .dropdown { position: relative; display: inline-block; } .dropdown-content { display: none; position: absolute; background-color: #f1f1f1; min-width: 160px; overflow: auto; box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); right: 0; z-index: 1; } .dropdown-content a { color: black; padding: 12px 16px; text-decoration: none; display: block; } .dropdown a:hover {background-color: #ddd;} .show {display: block;}
问题原因
- 重复ID冲突:所有下拉菜单共用同一个
id="myDropdown",getElementById只会返回页面中第一个匹配的元素,导致点击任何按钮都只操作顶部的菜单。 - 重复绑定事件:每个帖子都渲染一次
<script>,会让window.onclick事件被多次绑定,引发不必要的重复执行。
修复方案
1. 修改HTML结构(移除重复ID)
去掉下拉菜单的id属性,通过按钮的父容器定位对应菜单:
<div class="postBox"> <img class="postprofilepicture" src="../profilepictures/'.$ProfilePicture.'"> <a class="postusername" href="../user?page='.$UserName.'">'.$UserName.'</a> <p class="posttime">'.date('M jS, Y h:ia',strtotime($Date)).'</p> <p>'.$Text.'</p> <div class="dropdown"> <!-- 给函数传入当前按钮的引用 --> <button onclick="myFunction(this)" class="dropbtn">···</button> <div class="dropdown-content"> <a href="#share">分享</a> <a href="#save">保存</a> <a href="#delete">删除</a> </div> </div> </div> <br>
2. 统一JS代码(放在页面底部,仅加载一次)
修改函数逻辑,通过按钮的父元素定位对应下拉菜单,避免ID冲突:
function myFunction(btn) { // 通过按钮找到父容器内的下拉菜单 const dropdownContent = btn.parentElement.querySelector('.dropdown-content'); dropdownContent.classList.toggle('show'); } window.onclick = function(event) { if (!event.target.matches('.dropbtn')) { const dropdowns = document.getElementsByClassName('dropdown-content'); for (let i = 0; i < dropdowns.length; i++) { const openDropdown = dropdowns[i]; if (openDropdown.classList.contains('show')) { openDropdown.classList.remove('show'); } } } }
3. CSS无需修改,保留原样式即可
效果说明
- 点击任意帖子的下拉按钮时,
this会把当前按钮的DOM对象传给函数,再通过parentElement找到帖子对应的.dropdown容器,最终定位到专属的下拉菜单,彻底解决菜单错位问题。 - JS代码仅加载一次,避免重复绑定事件,提升页面性能。
内容的提问来源于stack exchange,提问作者adamcapjones
相关产品推荐
相关产品推荐

