You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;}

问题原因

  1. 重复ID冲突:所有下拉菜单共用同一个id="myDropdown",getElementById只会返回页面中第一个匹配的元素,导致点击任何按钮都只操作顶部的菜单。
  2. 重复绑定事件:每个帖子都渲染一次<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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 10:45:28