【发布时间】:2020-11-06 18:36:29
【问题描述】:
下面的表单包含一个使用复选框的 Bootstrap 切换按钮组。 我需要监听复选框输入的点击事件。
<html>
<head>
<title>Example: Bootstrap toggle button group</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://code.jquery.com/jquery-3.4.1.slim.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.css">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.js"></script>
</head>
<body>
<form role="form" id="form">
<div class="form-group">
<div>
<div>
<label for="fname">Name:</label>
</div>
<div id="fname" class="btn-group btn-group-toggle" data-toggle="buttons">
<label class="btn btn-primary">
a
<input type="checkbox" value="a" name="fname">
</label>
<label class="btn btn-primary">
b
<input type="checkbox" value="b" name="fname">
</label>
<label class="btn btn-primary">
c
<input type="checkbox" value="c" name="fname">
</label>
</div>
</div>
</div>
</form>
<script type="text/javascript">//<![CDATA[
$(function() {
$('#fname input').click(function() {
console.log('you clicked '+$(this).attr('value'))
});
});
//]]></script>
</body>
</html>
出于本示例的目的,我注册了以下处理程序,该处理程序在单击时打印复选框的值:
$(function() {
$('#fname input').click(function() {
console.log('you clicked '+$(this).attr('value'))
});
});
这在 (JSFiddle) 中运行良好 - 当您在按钮组中选择一个选项时,处理程序会按预期将底层复选框的值打印到控制台。
但是当我在浏览器中运行页面并进行选择时,处理程序不会触发,即控制台不会打印任何内容。为什么会这样?我已经完全按照 JSFiddle iframe 中的样子复制了该文档,并且还尝试在 Chrome (v85) 和 Firefox (v78.0.2) 上运行它,但均无济于事。
注意:result-light.css 样式表在页面最初在浏览器中加载时会出现 404 错误,但它看起来只是一个 Fiddle 样式表,删除它没有任何效果。
另外,我需要专门监听点击事件,所以on('change' 无济于事。
注意:我注意到 Bootstrap 使用属性 pointer-events: none; 设置复选框输入的样式,这可能是导致点击处理程序在浏览器中无响应的原因吗?设置为initial或inherit似乎没有效果。
编辑:我投票结束这个问题,因为这个问题是我的错误。在发帖时,我没有意识到我在浏览器中运行的脚本使用的是 Bootstrap 3.4.1,而 JSFiddle 使用的是更新的 4.4.1 版本。
我可能是错的,但我认为 click 处理程序没有在浏览器脚本中触发的原因是由于 Boostrap 3.4.1 的 source code 的 Button data-API 部分:
// BUTTON DATA-API
// ===============
if (!($(e.target).is('input[type="radio"], input[type="checkbox"]'))) {
// Prevent double click on radios, and the double selections (so cancellation) on checkboxes
e.preventDefault()
// The target component still receive the focus
if ($btn.is('input,button')) $btn.trigger('focus')
else $btn.find('input:visible,button:visible').first().trigger('focus')
}
此部分可防止双击收音机和双选复选框,并且在 v4.4.1 中被排除在外。从 v3.4.1 的源代码中手动省略它会使 click 处理程序按预期响应。
如果我必须按原样使用 v3.4.1,我可以将 click 替换为 focus,因为收音机和复选框仍会获得焦点。看到这个JSFiddle。
【问题讨论】:
-
请显示一个minimal reproducible example,它可以在 jsFiddle 之外复制问题。例如,如果您只复制了
iframe的body的内容,那么您没有加载 jQuery,因此 jQuery 代码将无法工作。 (您应该会看到一个错误。)如果我复制整个body,然后转到head并将所有script和link元素(除了jsFiddle cruft)复制到我的新的head文档,并删除body(???)中的两个jsfiddle脚本,它在本地工作正常。 pastebin.com/rWRUAgU7 -
@T.J.Crowder,非常感谢您回来。我正在完整复制 JSFiddle iframe 的内容,但不确定要省略哪些脚本,因此为简洁起见,我的帖子中没有包含
head标签。我也在 R 中工作,并没有意识到它加载的依赖项会干扰我的工作。当我运行您的 pastebin 代码时,它完全按预期工作。 -
它也帮助我隔离了这个问题(我认为)。 R 使用的是旧版本的 Bootstrap (3.4.1),我已经修改了我帖子中的代码以反映这一点 - 你能否确认该错误现在是否可重现?
-
问题中的更新代码在 JavaScript 中有语法错误:单引号前面的反斜杠不应该存在。如果我修复了这些,单击复选框不会触发任何 console.log 调用。删除引导程序,就会发生调用。我希望这会有所帮助。
-
糟糕,我需要那些来逃避 R 中的
'。我已经把它们拿出来了。我仍在试图弄清楚为什么在使用旧版本的 Bootstrap 时不会发生调用。感谢您的帮助!
标签: javascript jquery css twitter-bootstrap bootstrap-4