Shopify移动端点击图片显示Div的JavaScript实现问题求助
Shopify移动端点击图片显示文本模块修复方案
问题背景
在Shopify开发功能模块时,PC端已实现鼠标悬停图片时显示带文本的div,但移动端无悬停操作,需改为点击图片显示div。编写JS代码时出现icon.addEventListener is not a function错误,控制台提示变量未定义。
错误原因
- NodeList集合操作错误:
document.querySelectorAll()返回的是多元素组成的NodeList集合,不能直接调用仅单个元素拥有的addEventListener、classList.contains等方法,必须遍历集合中的每个元素。 - 元素关联逻辑缺失:原代码直接操作所有
uspTextTwo元素,未将点击的图标与对应的文本div关联,会导致所有文本同时显示。 - 重复无效的事件绑定:原代码多次绑定点击事件,且部分逻辑(如判断
uspContainer是否含smallScreen类)错误,因为uspContainer是集合,无法直接调用classList.contains。
修复后的完整代码
HTML部分(无需修改)
<div class="uspContainer"> {% for block in section.blocks %} <div class="uspTextContainer bigScreen"> <div class="uspIcon"> {% if block.settings.image != blank %} <img src="{{ block.settings.image | img_url: '100x100'}}" alt="img" class="uspIconImg"> {% else %} {% capture current %}{% cycle 1,2 %}{% endcapture %} {% endif %} </div> <p class="uspText">{{ block.settings.text }}</p> </div> <div class="uspTextContainer smallScreen"> <div class="uspIcon"> {% if block.settings.image != blank %} <img src="{{ block.settings.image | img_url: '100x100'}}" alt="img" class="uspIconImg"> {% else %} {% capture current %}{% cycle 1,2 %}{% endcapture %} {% endif %} </div> <p class="uspTextTwo hidden">{{ block.settings.text }}</p> </div> {% endfor %} </div>
CSS部分(无需修改)
@media only screen and (max-width: 800px) { .bigScreen { display: none !important; } } @media only screen and (min-width: 800px) { .smallScreen { display: none !important; } } .uspContainer { display: flex; } .uspTextContainer { display: flex; align-items: center; flex-direction: column; position: relative; width: 50%; margin: auto; margin-bottom: 2%; } .uspText { position: absolute; background: rgba(242, 242, 242, 0.72); color: black; visibility: hidden; opacity: 0; transition: opacity .2s, visibility .2s; min-width: 15%; max-width: 100%; display: flex; justify-content: center; border-radius: 1px; padding: 5px; top: 50%; transform: translateY(-50%); } .uspTextContainer:hover .uspText { visibility: visible; opacity: 1; } .uspTextTwo { position: absolute; background: rgba(242, 242, 242, 0.72); color: black; transition: opacity .2s, visibility .2s; min-width: 15%; max-width: 100%; display: flex; justify-content: center; border-radius: 1px; padding: 5px; top: 50%; transform: translateY(-50%); } .hidden { display: none; }
JavaScript部分(修复后)
// 获取所有图标元素 const icons = document.querySelectorAll(".uspIcon"); // 遍历每个图标,绑定点击事件 icons.forEach(icon => { icon.addEventListener("click", function() { // 找到当前图标所在容器下的对应文本div const textTwo = this.closest('.uspTextContainer').querySelector('.uspTextTwo'); // 切换hidden类,实现显示/隐藏切换 textTwo.classList.toggle('hidden'); }); });
关键修改说明
- 遍历NodeList集合:使用
forEach遍历所有uspIcon元素,给每个元素单独绑定点击事件,解决addEventListener is not a function错误。 - 关联对应文本元素:通过
closest('.uspTextContainer')找到当前图标所在的容器,再查找容器内的uspTextTwo,确保点击的图标只控制自己对应的文本div。 - 优化显示逻辑:使用
classList.toggle('hidden')实现点击切换显示/隐藏,提升用户体验。 - 移除无效代码:删除原代码中针对集合的错误操作和重复事件绑定,简化逻辑。
内容的提问来源于stack exchange,提问作者saidakl
相关产品推荐
相关产品推荐

