我在Bootstrap中创建了一个下拉菜单。我在下拉菜单图标上实现了一个jQuery toggleClass,它可以在单击时更改图标。通常,它应该在菜单关闭时显示汉堡包图标,然后在菜单打开时更改为X图标。但这里的问题是,如果菜单单击速度太快(双击),则会出现相反的情况(即菜单关闭时显示X图标,打开时显示汉堡包图标)。我不希望出现这种情况。以下是代码片段。第一个有什么办法可以防止这种情况发生吗?
toggleClass
b5buobof1#
如果您使用右选择器,您可以根据导航栏的状态(折叠或非折叠)设置切换器图标的样式。
<!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: "\58"; 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>
9lowa7mx2#
注意:我的回答更多的是给你关于什么问题和为什么问题发生的直觉。我认为@kmoser的建议是最好的建议。问题是JavaScript调用栈与渲染事件循环竞争,从而产生了一个竞争条件,渲染事件将 * 总是释放 *。但为什么呢?Render事件通过浏览器Event-Loop传递到JavaScript的调用堆栈。但是,按钮单击直接传递到调用堆栈,跳过事件循环。这意味着,按钮单击会立即执行(在大多数情况下:同步),而呈现事件是异步执行的(大多数情况下),因此呈现事件没有机会按预期的顺序追加到调用堆栈中。为什么呢?因为它们通常会执行动画!而动画总是在语法上用毫秒级的延迟来描述。CSS样式表语法示例:.5s.5s是一个异步的副作用。因此,它将自动被放到浏览器的事件循环中,并且每当JavaScript的调用堆栈说嘿,事件循环,我完成了所有这些按钮点击,我准备好了,动画你举行!然后通过将动画推送到调用栈来执行动画。在您的例子中,如果您深入了解Bootstrap CSS文件,您会发现我的示例中定义了毫秒运行时间的下拉列表的一些动画语法。解决的办法呢?
.5s
希望能有所帮助。
2条答案
按热度按时间b5buobof1#
如果您使用右选择器,您可以根据导航栏的状态(折叠或非折叠)设置切换器图标的样式。
9lowa7mx2#
注意:我的回答更多的是给你关于什么问题和为什么问题发生的直觉。我认为@kmoser的建议是最好的建议。
问题是JavaScript调用栈与渲染事件循环竞争,从而产生了一个竞争条件,渲染事件将 * 总是释放 *。但为什么呢?
Render事件通过浏览器Event-Loop传递到JavaScript的调用堆栈。但是,按钮单击直接传递到调用堆栈,跳过事件循环。这意味着,按钮单击会立即执行(在大多数情况下:同步),而呈现事件是异步执行的(大多数情况下),因此呈现事件没有机会按预期的顺序追加到调用堆栈中。
为什么呢?因为它们通常会执行动画!而动画总是在语法上用毫秒级的延迟来描述。
CSS样式表语法示例:
.5s
.5s
是一个异步的副作用。因此,它将自动被放到浏览器的事件循环中,并且每当JavaScript的调用堆栈说嘿,事件循环,我完成了所有这些按钮点击,我准备好了,动画你举行!
然后通过将动画推送到调用栈来执行动画。
在您的例子中,如果您深入了解Bootstrap CSS文件,您会发现我的示例中定义了毫秒运行时间的下拉列表的一些动画语法。
解决的办法呢?
希望能有所帮助。