【问题标题】:onclick for Bootstrap .btn-group checkbox works in JSFiddle but not browseronclick for Bootstrap .btn-group 复选框适用于 JSFiddle 但不适用于浏览器
【发布时间】: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; 设置复选框输入的样式,这可能是导致点击处理程序在浏览器中无响应的原因吗?设置为initialinherit似乎没有效果。


编辑:我投票结束这个问题,因为这个问题是我的错误。在发帖时,我没有意识到我在浏览器中运行的脚本使用的是 Bootstrap 3.4.1,而 JSFiddle 使用的是更新的 4.4.1 版本。

我可能是错的,但我认为 click 处理程序没有在浏览器脚本中触发的原因是由于 Boostrap 3.4.1 的 source codeButton 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 之外复制问题。例如,如果您只复制了iframebody 的内容,那么您没有加载 jQuery,因此 jQuery 代码将无法工作。 (您应该会看到一个错误。)如果我复制整个body,然后转到head 并将所有scriptlink 元素(除了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


【解决方案1】:

我已尽力解释您的问题。这是我的 jsfiddle:https://jsfiddle.net/wqse25vj/ 我希望它有所帮助。

作为程序员最难的部分是提问。 “一个问题说得好,问题就解决了一半。”成立。如果这不是您要寻找的答案,请完善您的问题并确保再次提问。作为一般说明:记住将您的 jQuery 代码封装在 $(document).ready() 中,并继续试验和学习 HTML、CSS 和 Bootstrap。例如,我注意到您的 HTML 标签缺少 for 属性,并且在您的 div 和输入字段上重复了类名(提示:仅 div 需要 Bootstrap 类。)。祝你一切顺利!

我使用的资源:

【讨论】:

  • 对不起!我已经大胆地提出了我的问题,希望现在更清楚了吗?我使用了$(document).ready() 的简写($(function() { ... })),所以这不是问题。我曾尝试设置for,但没有帮助。我可能错了,但我的示例中的每个标签标记都只包含一个输入控件,因此即使没有 for 属性 (see here),它也会自动与该输入控件关联。
  • 对于类,它们是根据 Bootstrap 的示例分配的 here
【解决方案2】:

我无法解释为什么它在 JSFiddle 中工作,但是看起来复选框基本上隐藏在按钮后面。您是要提交此表单,还是仅根据选择对页面执行一些 jquery?如果是我并且你想保留按钮,你可以这样做:

<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" data-value="a">
          a
        </label>
        <label class="btn btn-primary" data-value="b">
          b
        </label>
        <label class="btn btn-primary" data-value="c">
          c
        </label>
      </div>
    </div>
  </div>
</form>
        <script>
        $(function() {
    
  $('#fname label').click(function() {
    console.log('you clicked '+$(this).data('value'))
  });

});
        </script>

【讨论】:

  • 表单将被验证,我正在使用的插件需要将验证规则附加到输入标签,所以很遗憾我无法取消它们。
猜你喜欢
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多