使用Stimulus.js实现动态搜索栏失效,请求技术排查
问题排查与修复方案
直接说两个核心问题,是导致功能失效的关键:
1. CSS选择器错误
你当前的CSS写法:
.menu-card .hidden { display: none; }
这个选择器是匹配.menu-card内部带.hidden类的子元素,但实际你是给.menu-card本身添加.hidden类,所以必须改成无空格的组合选择器:
.menu-card.hidden { display: none; }
2. Stimulus控制器作用域不匹配
你把data-controller="search-bar"挂在了<input>元素上,但菜品卡片的data-search-bar-target="menuCard"并不是这个input的子元素。Stimulus要求控制器的target必须是控制器元素的后代节点,所以this.menuCardTargets根本拿不到任何卡片,过滤逻辑自然无法执行。
修复方式:
把控制器挂载到包含搜索框和所有菜品卡片的父容器上,示例结构:
<!-- 新增父容器,挂载控制器 --> <div data-controller="search-bar"> <div class="searchbar"> <i class="fa-solid fa-magnifying-glass"></i> <input type="search" id="search" placeholder="Search menu" data-action="input->search-bar#search"> </div> <!-- 所有菜品卡片都放在控制器容器内 --> <div class="menu-card" data-search-bar-target="menuCard"> <h4 class="item-name">Greek Village Salad with Feta</h4> <p class="item-details">Tomato, cucumber, green pepper, red onion, feta in a rich salad</p> <p class="item-price">£10.00</p> </div> <!-- 更多菜品卡片... --> </div>
可选优化
如果想让搜索同时匹配菜品描述,可以修改控制器逻辑:
search(event) { const searchInput = event.target.value.toLowerCase(); this.menuCardTargets.forEach((menuCard) => { const itemName = menuCard.querySelector(".item-name").textContent.toLowerCase(); const itemDetails = menuCard.querySelector(".item-details").textContent.toLowerCase(); const isMatch = itemName.includes(searchInput) || itemDetails.includes(searchInput); menuCard.classList.toggle("hidden", !isMatch); }); }
先修复前两个问题,功能就能正常运行。
内容的提问来源于stack exchange,提问作者NTM17
相关产品推荐
相关产品推荐

