如何从子元素ID访问父div?优化单选按钮关联图片灰度切换
问题描述
我有2个单选按钮,每个按钮关联一张图片。初始状态下这些图片为黑白效果(filter:grayscale(1)),当选中其中一个按钮时,希望对应图片恢复彩色(filter:grayscale(0))。grayscale滤镜属性设置在<img>元素上,每个单选按钮与对应图片都包裹在独立的div中。
我已成功获取选中单选按钮的ID,但目前无法通过该ID访问其父div,尝试使用.parentElement()、.parent()、parent.Node()均未成功。现提出两个问题:
- 如何通过子元素ID访问父div?
- 有没有更简单的方法实现上述图片灰度切换功能?
现有代码
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <div class="row first-screen-row-avatar"> <div class="col select-avatar-col"> <label for="avatar1"> <img src="assets/images/avatars/hero-avatar-1.jpg" class="avatar-img-select" alt="Avatar 1"> <input type="radio" id="avatar1" name="hero-avatar" value="assets/images/avatars/hero-avatar-1.jpg" required> </label> </div> <div class="col select-avatar-col"> <label for="avatar2"> <img src="assets/images/avatars/hero-avatar-2.webp" class="avatar-img-select" alt="Avatar 2"> <input type="radio" id="avatar2" name="hero-avatar" value="assets/images/avatars/hero-avatar-2.webp" required> </label> </div> </div>
CSS
.avatar-img-select { height: 52px; filter: grayscale(1); }
JavaScript
$(document).ready(function() { /*Manages Radio buttons & images rendering when clicked*/ $('input[name="hero-avatar"]').change(function() { // Check if the radio button is checked if ($(this).is(':checked')) { // captures id of button that is checked let checkButton = $(this).attr('id'); // Log checked radio button id console.log(checkButton); //test to find parent div class console.log($(`#${checkButton}`).parent().attr('class')); //this works but doesnt reach the parent div class which contains grayscale property $(`#${checkButton}`.parentNode).css('filter', 'grayscale(0)') } }); //if radio button is checked //change colour of image attached to it });
解答
1. 通过子元素ID访问父div的正确方法
你现有代码的错误出在$(#${checkButton}.parentNode)这一行:parentNode是原生JS的属性,不能直接和jQuery选择器字符串拼接。正确写法分两种:
- jQuery方式:先选中元素,再调用
.parent()方法(你之前测试的console.log($(#${checkButton}).parent().attr('class'))是对的,只是后续代码写错了)。如果要找外层的.select-avatar-coldiv,需要用.closest()或者多级.parent():// 找到单选按钮的直接父元素label $(`#${checkButton}`).parent(); // 找到外层的.select-avatar-col div并修改对应图片的滤镜 $(`#${checkButton}`).closest('.select-avatar-col').find('.avatar-img-select').css('filter', 'grayscale(0)'); - 原生JS方式:先获取原生DOM元素,再使用
.parentNode:document.getElementById(checkButton).parentNode;
2. 更简单的实现方法
方案1:纯CSS实现(无JS)
利用CSS兄弟选择器,无需JS即可完成效果,代码更简洁性能更好。只需调整HTML结构(把input移到img前面),再修改CSS:
.avatar-img-select { height: 52px; filter: grayscale(1); } /* 选中单选按钮后,对应label内的图片恢复彩色 */ input[name="hero-avatar"]:checked + .avatar-img-select { filter: grayscale(0); }
调整后的HTML:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <div class="row first-screen-row-avatar"> <div class="col select-avatar-col"> <label for="avatar1"> <input type="radio" id="avatar1" name="hero-avatar" value="assets/images/avatars/hero-avatar-1.jpg" required> <img src="assets/images/avatars/hero-avatar-1.jpg" class="avatar-img-select" alt="Avatar 1"> </label> </div> <div class="col select-avatar-col"> <label for="avatar2"> <input type="radio" id="avatar2" name="hero-avatar" value="assets/images/avatars/hero-avatar-2.webp" required> <img src="assets/images/avatars/hero-avatar-2.webp" class="avatar-img-select" alt="Avatar 2"> </label> </div> </div>
方案2:简化JS实现
如果不想调整HTML结构,可以用jQuery简化代码,无需获取ID,直接通过当前元素定位对应图片:
$(document).ready(function() { $('input[name="hero-avatar"]').change(function() { // 先把所有图片重置为灰度 $('.avatar-img-select').css('filter', 'grayscale(1)'); // 再把当前选中按钮对应的图片恢复彩色 $(this).closest('label').find('.avatar-img-select').css('filter', 'grayscale(0)'); }); });
内容的提问来源于stack exchange,提问作者PhilM
相关产品推荐
相关产品推荐

