【问题标题】:jQuery toggleClass breaks on fast clickjQuery toggleClass 在快速点击时中断
【发布时间】:2022-11-03 03:21:24
【问题描述】:

我有一个用 Bootstrap 制作的下拉菜单。我在下拉菜单图标上实现了一个 jQuery toggleClass,它改变了点击时的图标。通常,它应该在菜单关闭时显示汉堡图标,然后在菜单打开时变为 X 图标。但这里的问题是,如果菜单点击得太快(双击),情况就会相反(即菜单在关闭时显示 X 图标,在打开时显示汉堡图标)。我不想那样。这是代码sn-p。

$("span.toggler").click(function() {

                    $("#toggler-icon").toggleClass("fa-bars fa-times");
            })
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css" integrity="sha512-xh6O/CkQoPOWDdYTDqeRdPCVd1SpvCA9XXcUnZS2FmJNp1coAFzvtCN9BmamE+4aHK8yyUHUSCcJHgXloTyT2A==" crossorigin="anonymous" referrerpolicy="no-referrer" />
 
   
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
    <div class="container-fluid">
        <a class="navbar-brand" href="#">Hi</a>
        <span class="toggler">
            <span id="toggler-icon" class="fa-solid navbar-toggler fa-bars fa-2x text-white" data-bs-toggle="collapse"
                data-bs-target="#navbarSupportedContent"></span>
        </span>
        <div class="collapse text-white navbar-collapse" id="navbarSupportedContent">
            <ul class="navbar-nav me-auto mb-2 mb-lg-0">
                <li class="nav-item">
                    <a class="nav-link active" aria-current="page" href="#">
                        <span class="fa-solid fa-home"></span> Dashboard </a>
                </li>

               
                    </ul>
                
        </div>
    </div>
</nav>

<script src="https://code.jquery.com/jquery-3.6.1.min.js"
        integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" crossorigin="anonymous"></script>
         <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js"></script>

有什么办法可以防止这种情况发生吗?

【问题讨论】:

  • 为什么要添加自己的点击处理程序,而不是使用 Bootstrap 的内置导航处理程序?
  • Bootstrap 的处理程序不会切换图标。

标签: javascript html jquery twitter-bootstrap


【解决方案1】:

如果您使用正确的选择器,您可以根据导航栏的状态(折叠与否)设置切换器图标的样式。

<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Bootstrap demo</title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css" integrity="sha512-xh6O/CkQoPOWDdYTDqeRdPCVd1SpvCA9XXcUnZS2FmJNp1coAFzvtCN9BmamE+4aHK8yyUHUSCcJHgXloTyT2A==" crossorigin="anonymous" referrerpolicy="no-referrer" />

  <style>
    button.navbar-toggler[aria-expanded="true"] .navbar-toggler-icon {
      background-image: none;
    }

    button.navbar-toggler[aria-expanded="true"] .navbar-toggler-icon::before {
      content: "8";
      line-height: 2rem;
    }
  </style>
</head>

<body>
  <nav class="navbar navbar-expand-lg bg-light">
    <div class="container-fluid">
      <a class="navbar-brand" href="#">Navbar</a>
      <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
        <span class="fa navbar-toggler-icon"></span>
      </button>
      <div class="collapse navbar-collapse" id="navbarNavAltMarkup">
        <div class="navbar-nav">
          <a class="nav-link active" aria-current="page" href="#">Home</a>
          <a class="nav-link" href="#">Features</a>
          <a class="nav-link" href="#">Pricing</a>
          <a class="nav-link disabled">Disabled</a>
        </div>
      </div>
    </div>
  </nav>
  <h1>Hello, world!</h1>
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3" crossorigin="anonymous"></script>
</body>

</html>

【讨论】:

  • 这确实是一个绝妙的答案。谢谢!
  • 一个问题,我想你使用了 Bootstrap 字形图标?对于content: "/58"
  • 我从 Fontawesome 代码中复制了 .fa-x::before 规则,该代码显示 content: "8";
  • 我懂了。那好吧。
【解决方案2】:

注意:我的答案更多的是让您对什么问题是和为什么正在发生。我认为@kmoser 的建议是最好的建议。

问题是 JavaScript 调用堆栈正在与渲染事件循环竞争,创建渲染事件将总是松散.但为什么?

通过浏览器渲染事件的旅行事件循环到 JavaScript 的调用堆栈.但是,按钮点击直接到达调用堆栈,跳过事件循环。这意味着,按钮单击会立即执行(在大多数情况下:同步),而渲染事件是异步执行的(大部分时间),因此渲染事件没有机会按照您想要的顺序附加到调用堆栈.

为什么?因为他们通常会执行动画!并且动画总是在语法上用一些毫秒延迟运行时间来描述。

CSS 样式表语法示例: animation: .5s linear 1s infinite alternate slidein;

.5s 是异步的副作用。因此它会自动被放到浏览器事件循环中,并且每当 JavaScript 的调用堆栈说

嘿,事件循环,我已经完成了所有这些按钮点击,我准备好了你拿着的那个动画!

然后它通过将动画推送到调用堆栈来执行动画。

在您的情况下,如果您深入了解 Bootstraps CSS 文件,您会在我的示例中找到一些动画语法,用于定义毫秒运行时的下拉菜单。

解决方案?

  • 正如@kmoser 所指出的,完成所需任务的预期方法是基于css 操作(动画:下拉菜单打开,下拉菜单关闭)而不是用户操作来触发css 图标更改(汉堡到X)。

希望有帮助。

【讨论】:

  • 感谢您提供足够的信息!
猜你喜欢
  • 1970-01-01
  • 2014-06-18
  • 1970-01-01
  • 1970-01-01
  • 2020-09-07
  • 1970-01-01
  • 1970-01-01
  • 2020-11-15
  • 1970-01-01
相关资源
最近更新 更多