如何实现点击删除按钮隐藏Fetch API渲染的页面元素?
问题:点击Delete按钮无法隐藏对应元素的解决方法
我正在完成一项编码任务:使用Fetch API、Bootstrap和jQuery从接口拉取数据,通过array.map()将数据渲染到div元素中。以下是已完成的原生版本代码,但点击Delete按钮隐藏对应元素的功能始终无法实现,尝试过回调函数和按钮onclick事件都无效,求解决方向。
现有HTML代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>UI Demo</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.min.js"> </script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"> </script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css" integrity="sha512-KfkfwYDsLkIlwQp6LFnl8zNdLGxu9YAA1QvwINks4PhcElQSvqcyVLLD9aMhXd13uQjoXtEKNosOWaZqXgel0g==" crossorigin="anonymous" referrerpolicy="no-referrer" /> <link rel="stylesheet" href="css/style.css"> </head> <body> <nav class="navbar navbar-expand-lg navbar-dark bg-primary"> <div class="container-fluid"> <span class="navbar-brand" href="#">Test App</span> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarSupportedContent"> <ul class="navbar-nav me-auto mb-2 mb-lg-0"> <li class="nav-item dropdown bg-light" > <a class="nav-link dropdown-toggle text-dark" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false"> Menu </a> <ul class="dropdown-menu" aria-labelledby="navbarDropdown"> <li><a class="dropdown-item" href="#">Menu 1</a></li> <li><a class="dropdown-item" href="#">Menu 2</a></li> <li><a class="dropdown-item" href="#">Menu 3</a></li> </ul> </li> </ul> </div> </div> </nav> <main> <div class="container" id="box"> <h3>Showing </h3> <div class="row"> <!-- Fetched data gets inserted here --> </div> </div> </main> </body> </html>
现有JS代码
<script> fetch('https://jsonplaceholder.typicode.com/users').then((data) => { return data.json(); }).then((jsondata) => { const names = jsondata.map((values)=> { return `<div class="col col-lg-4 col-md-4 gx-4 gy-4"> <div id="card" class="card p-2"> <h2 id="user">${values.name}</h2> <div class="card-body"> <p><strong>Street:</strong> ${values.address.street}</p> <p><strong>Suite:</strong> ${values.address.suite}</p> <p><strong>City:</strong> ${values.address.city}</p> <p><strong>Zip Code:</strong> ${values.address.zipcode} </p> <button class="btn btn-primary float-end"><span><i class="fa-solid fa-trash-can"></i> </span>Delete</button> </div> </div> </div>` }) document.querySelector('.row').innerHTML = names; }); </script>
解决思路与方案
问题根源:Delete按钮是通过innerHTML动态插入DOM的,页面初始化时这些按钮并不存在,直接绑定onclick或addEventListener会找不到元素,必须用事件委托实现。
方案1:原生JS事件委托
在渲染完数据后,给父元素(.row)绑定点击事件,通过事件冒泡判断点击目标:
修改JS代码,在document.querySelector('.row').innerHTML = names;后添加:
// 给父元素绑定事件,监听子元素点击 document.querySelector('.row').addEventListener('click', function(e) { // 确认点击的是Delete按钮 const deleteBtn = e.target.closest('.btn-primary'); if (deleteBtn) { // 找到对应卡片的外层col元素并隐藏 const targetCol = deleteBtn.closest('.col'); // 方式1:直接设置display隐藏 targetCol.style.display = 'none'; // 方式2:添加Bootstrap的d-none类(推荐,符合框架规范) // targetCol.classList.add('d-none'); } });
方案2:jQuery事件委托
利用jQuery的.on()方法实现事件委托,代码更简洁:
修改JS代码,在document.querySelector('.row').innerHTML = names;后添加:
// jQuery事件委托:监听.row下的.btn-primary点击 $('.row').on('click', '.btn-primary', function() { // 找到当前按钮所在的col元素并隐藏 $(this).closest('.col').hide(); // 或添加d-none类:$(this).closest('.col').addClass('d-none'); });
额外优化:修复重复ID问题
现有代码中每个卡片的id="card"和id="user"是重复的,不符合HTML规范,建议改为class:
// 将map返回内容中的id改为class return `<div class="col col-lg-4 col-md-4 gx-4 gy-4"> <div class="card p-2"> <h2 class="user">${values.name}</h2> <div class="card-body"> <p><strong>Street:</strong> ${values.address.street}</p> <p><strong>Suite:</strong> ${values.address.suite}</p> <p><strong>City:</strong> ${values.address.city}</p> <p><strong>Zip Code:</strong> ${values.address.zipcode} </p> <button class="btn btn-primary float-end"><span><i class="fa-solid fa-trash-can"></i> </span>Delete</button> </div> </div> </div>`
内容的提问来源于stack exchange,提问作者BeauS
相关产品推荐
相关产品推荐

