如何禁用Django Admin风格自动生成select标签的双击功能?
解决Django Admin风格多对多选择框双击功能无法禁用的问题
你遇到的核心问题是:Django Admin的SelectFilter组件会动态替换你初始的<select>元素,生成全新的DOM结构(也就是你看到的包含#id_settings-user_to的.selector-chosen容器)。你之前绑定的双击事件是针对原始的#id_settings-user,但实际触发双击操作的是组件生成后的新元素,所以你的代码完全没生效。
下面给你两个可行的解决方案:
方案1:用事件委托阻止双击(推荐)
因为新元素是动态生成的,我们可以把双击事件绑定到更高层级的元素(比如document),通过事件委托来拦截目标元素的双击操作:
$(document).ready(function(){ // 拦截可选区域和已选区域内选项的双击 $(document).on('dblclick', '#id_settings-user_from option, #id_settings-user_to option', function(e){ e.stopPropagation(); e.preventDefault(); return false; }); // 额外拦截整个选择框的双击,确保覆盖所有触发场景 $(document).on('dblclick', '.selector-available select, .selector-chosen select', function(e){ e.stopPropagation(); e.preventDefault(); return false; }); });
这里的#id_settings-user_from是左侧的可选用户列表,#id_settings-user_to是右侧的已选用户列表,双击这两个区域内的选项或选择框本身都会触发默认的移动操作,所以我们需要全部拦截。
方案2:直接覆盖SelectFilter的双击处理逻辑
如果你想从根源上禁用这个功能,可以直接覆盖SelectFilter组件内置的双击处理函数:
$(document).ready(function(){ // 延迟执行,确保SelectFilter组件已完成初始化 setTimeout(function(){ // 获取对应选择框的SelectBox实例 const selectBox = SelectBox.init('id_settings-user'); // 把双击处理函数替换为空函数,直接禁用功能 selectBox.dblclick = function() {}; // 同时移除左右选择框的原生双击事件绑定 $('#id_settings-user_from, #id_settings-user_to') .off('dblclick') .dblclick(function(e){ e.preventDefault(); }); }, 100); });
这个方法需要注意:你的自定义JS代码必须在SelectFilter2.js之后加载,这样才能获取到SelectBox对象。
关键提示
- 不要尝试禁用整个页面的双击,这会影响其他正常功能,只针对目标选择框做拦截即可。
- 事件委托的方式更稳定,无论组件何时生成动态元素,事件监听都会生效。
内容的提问来源于stack exchange,提问作者M.Izzat
相关产品推荐
相关产品推荐

