如何用JavaScript实现共享类的动态按钮独立交互?
问题解决:独立控制密码框显示切换
问题
有两个共享password类的密码输入框,每个输入框对应一个带visor类的切换按钮。当前点击任意按钮时,两个按钮的图标都会切换,且仅改变一个输入框的显示类型。需要实现每个按钮仅控制对应输入框和自身图标的独立交互效果。
现有代码问题分析
visor函数未利用传入参数:点击事件里把按钮ID传给了visor,但函数本身未接收该参数,参数传递无效。- 元素选中范围错误:
document.querySelector(".password")只会选中页面第一个带password类的输入框,导致点击任意按钮都只修改第一个密码框。$('.icon')会选中页面所有带icon类的元素,造成点击一个按钮时所有图标同步切换。
修正后的代码
HTML(无需修改)
<div class="input-group"> <input autocomplete="new-password" rel="tooltip" data-bs-toggle="tooltip" data-bs-placement="top" title="La contraseña debe ser de 8 caracteres y tener al menos una letra minúscula, una letra mayúscula, un número y un caracter especial (#$%&*+-;.:=@!_?/)" class="form-control password" type="password" name="user[password]" id="user_password" aria-autocomplete="list"> <div class="btn btn-outline-dark visor" id="button" type="button"> <svg class="svg-inline--fa fa-eye-slash fa-w-20 icon" id="button" aria-hidden="true" focusable="false" data-prefix="fa" data-icon="eye-slash" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512" data-fa-i2svg=""><path fill="currentColor" d="M320 400c-75.85 0-137.25-58.71-142.9-133.11L72.2 185.82c-13.79 17.3-26.48 35.59-36.72 55.59a32.35 32.35 0 0 0 0 29.19C89.71 376.41 197.07 448 320 448c26.91 0 52.87-4 77.89-10.46L346 397.39a144.13 144.13 0 0 1-26 2.61zm313.82 58.1l-110.55-85.44a331.25 331.25 0 0 0 81.25-102.07 32.35 32.35 0 0 0 0-29.19C550.29 135.59 442.93 64 320 64a308.15 308.15 0 0 0-147.32 37.7L45.46 3.37A16 16 0 0 0 23 6.18L3.37 31.45A16 16 0 0 0 6.18 53.9l588.36 454.73a16 16 0 0 0 22.46-2.81l19.64-25.27a16 16 0 0 0-2.82-22.45zm-183.72-142l-39.3-30.38A94.75 94.75 0 0 0 416 256a94.76 94.76 0 0 0-121.31-92.21A47.65 47.65 0 0 1 304 192a46.64 46.64 0 0 1-1.54 10l-73.61-56.89A142.31 142.31 0 0 1 320 112a143.92 143.92 0 0 1 144 144c0 21.63-5.29 41.79-13.9 60.11z"></path></svg><!-- <div class="icon fa fa-eye-slash" id="button"></div> Font Awesome fontawesome.com --> </div> </div> <div class="input-group"> <input autocomplete="new-password" rel="tooltip" title="Debe coincidir con la contraseña" class="form-control password" type="password" name="user[password_confirmation]" id="user_password_confirmation"> <div class="btn btn-outline-dark visor" id="button2" type="button"> <svg class="svg-inline--fa fa-eye-slash fa-w-20 icon" id="button2" aria-hidden="true" focusable="false" data-prefix="fa" data-icon="eye-slash" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512" data-fa-i2svg=""><path fill="currentColor" d="M320 400c-75.85 0-137.25-58.71-142.9-133.11L72.2 185.82c-13.79 17.3-26.48 35.59-36.72 55.59a32.35 32.35 0 0 0 0 29.19C89.71 376.41 197.07 448 320 448c26.91 0 52.87-4 77.89-10.46L346 397.39a144.13 144.13 0 0 1-26 2.61zm313.82 58.1l-110.55-85.44a331.25 331.25 0 0 0 81.25-102.07 32.35 32.35 0 0 0 0-29.19C550.29 135.59 442.93 64 320 64a308.15 308.15 0 0 0-147.32 37.7L45.46 3.37A16 16 0 0 0 23 6.18L3.37 31.45A16 16 0 0 0 6.18 53.9l588.36 454.73a16 16 0 0 0 22.46-2.81l19.64-25.27a16 16 0 0 0-2.82-22.45zm-183.72-142l-39.3-30.38A94.75 94.75 0 0 0 416 256a94.76 94.76 0 0 0-121.31-92.21A47.65 47.65 0 0 1 304 192a46.64 46.64 0 0 1-1.54 10l-73.61-56.89A142.31 142.31 0 0 1 320 112a143.92 143.92 0 0 1 144 144c0 21.63-5.29 41.79-13.9 60.11z"></path></svg><!-- <div class="icon fa fa-eye-slash" id="button2"></div> Font Awesome fontawesome.com --> </div> </div>
JavaScript(修正版)
const input = () => { $(".visor").on('click', function() { // 直接传递当前点击的按钮元素 visor($(this)); }); } const visor = (button) => { // 定位当前按钮所在输入组内的密码框 const targetInput = button.closest('.input-group').find('.password'); // 定位当前按钮内的图标元素 const targetIcon = button.find('.icon'); if(targetInput.attr('type') === "password"){ targetInput.attr('type', 'text'); targetIcon.removeClass('fa-eye-slash').addClass('fa-eye'); }else{ targetInput.attr('type', 'password'); targetIcon.removeClass('fa-eye').addClass('fa-eye-slash'); } } // 初始化绑定事件 input();
修正逻辑说明
- 传递当前按钮元素:点击事件中直接将
$(this)(当前触发点击的按钮)传入visor函数,无需通过ID查找,逻辑更简洁灵活。 - 精准定位对应元素:
- 用
closest('.input-group')找到按钮所属的输入组,再通过find('.password')锁定组内对应的密码输入框,确保只操作当前按钮关联的输入框。 - 用
button.find('.icon')仅选中当前按钮内的图标,避免影响其他按钮的状态。
- 用
- 兼容修改输入框类型:使用jQuery的
attr方法修改输入框类型,比原生type属性修改兼容性更好。
内容的提问来源于stack exchange,提问作者Arturo Gabriel
相关产品推荐
相关产品推荐

