解决jQuery动态生成下拉按钮点击事件失效问题
解决动态添加MDL下拉组件点击无响应的问题
嘿,我来帮你搞定这个问题!你遇到的核心问题是:动态生成的Material Design Lite(MDL)组件没有被初始化,而且菜单选择的事件绑定也没适配动态元素。毕竟MDL只会在页面首次加载时自动初始化所有组件,后来动态加的元素它可不会主动处理,得咱们手动来~
下面是修复后的完整代码,我给你拆解下改动点:
关键改动说明
- 给新添加的MDL按钮和菜单手动调用
componentHandler.upgradeElement()完成初始化,让MDL给它们绑定交互逻辑 - 用事件委托来绑定菜单选项的点击事件,这样不管是一开始就有的还是后来加的菜单,点击选项都能生效
- 去掉了重复引入的jQuery(你之前同时加了2.1.1和3.3.1,这会导致冲突,留一个就行)
完整修复代码
HTML部分
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"> <link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.indigo-pink.min.css"> <script defer src="https://code.getmdl.io/1.3.0/material.min.js"></script> <title>Page Title</title> </head> <body> <div class="btn btn-success js-add"> Add Content </div> <div class="main"> <div class="form-control-group"> <h3>Content No. 1</h3> <div class="form-control"> <label for="volume">Item</label> <button type="button" id="volume-menu" class="mdl-button js-custom-select mdl-js-button mdl-button--raised mdl-js-ripple-effect"> Choose the item </button> <ul class="mdl-menu mdl-js-menu" for="volume-menu"> <li class="mdl-menu__item" data-value="10">10</li> <li class="mdl-menu__item" data-value="20">20</li> <li class="mdl-menu__item" data-value="30">30</li> </ul> </div> </div> <br> </div> </body>
JavaScript部分
var count = 1; // 用事件委托处理所有菜单选项的点击,包括动态生成的 $(document).on('click', '.mdl-menu__item', function() { // 找到对应的按钮,更新按钮文本为选中的值 var targetButtonId = $(this).closest('.mdl-menu').attr('for'); $('#' + targetButtonId).text($(this).text()); }); $('.js-add').click(function() { count++; var content = ` <div class="form-control-group"> <h3>Content No. `+count+`</h3> <div class="form-control"> <label for="volume">Item</label> <button type="button" id="volume-menu`+count+`" class="mdl-button js-custom-select mdl-js-button mdl-button--raised mdl-js-ripple-effect"> Choose the item </button> <ul class="mdl-menu mdl-js-menu" for="volume-menu`+count+`"> <li class="mdl-menu__item" data-value="10">10</li> <li class="mdl-menu__item" data-value="20">20</li> <li class="mdl-menu__item" data-value="30">30</li> </ul> </div> </div> <br>`; $('.main').append(content); // 手动初始化新添加的MDL组件 var newButton = document.getElementById('volume-menu' + count); var newMenu = newButton.nextElementSibling; componentHandler.upgradeElement(newButton); componentHandler.upgradeElement(newMenu); });
为啥这样改就好使?
- MDL组件初始化:MDL在页面加载完只会扫一遍DOM初始化组件,后来动态加的元素得咱们手动调用
componentHandler.upgradeElement(),让MDL给它们加上点击事件和样式效果。 - 事件委托:直接给
.mdl-menu__item绑定事件的话,只有页面一开始就有的元素能触发,用$(document).on()把事件绑定在文档上,就能监听所有现在和未来的该类元素的点击了。 - jQuery版本冲突:同时引入两个不同版本的jQuery会导致很多奇怪的bug,比如方法失效,所以只留一个最新的就行。
内容的提问来源于stack exchange,提问作者crazydev
相关产品推荐
相关产品推荐

