Javascript 每次打开新模式时,引导模式内部代码都会成倍增加

Javascript 每次打开新模式时,引导模式内部代码都会成倍增加,javascript,jquery,bootstrap-4,modal-dialog,bootstrap-modal,Javascript,Jquery,Bootstrap 4,Modal Dialog,Bootstrap Modal,你好,所以我为我构建的聊天室创建了一个房间密码验证,并使用Bootstrap的4模式向用户显示密码输入 我使用jQuery打开模式,如so$(“#密码验证”).modal()。它工作得很好。但是,在关闭模式、重新打开并提交输入后,“如果用户单击enter按钮”中的代码将执行多次而不是打开 // #room-password-btn is the enter button $("#room-password-btn").click(function(){ console

你好,所以我为我构建的聊天室创建了一个房间密码验证,并使用Bootstrap的4模式向用户显示密码输入

我使用jQuery打开模式,如so
$(“#密码验证”).modal()。它工作得很好。但是,在关闭模式、重新打开并提交输入后,“如果用户单击enter按钮”中的代码将执行多次而不是打开

// #room-password-btn is the enter button
$("#room-password-btn").click(function(){ 
  console.log("Execute")
}); 
例如:如果您(打开模式按钮并关闭模式)*3,然后单击控制台中的enter按钮:

// first open and close
// second open and close
Execute // third open, enter
Execute
Execute
问题的工作模型:(尝试关闭它,然后按enter键,您将看到多条消息,而不是一条,关闭越多,您将看到更多消息。我相信,如果我解决了这一问题,问题将得到解决)

模态:

<div class="modal fade" id="password-validation" tabindex="-1" role="dialog" aria-labelledby="room-password-val-aria" aria-hidden="true">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">Enter the room password</h4>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <label data-error="wrong" data-success="right">Room password</label>
          <input class="form-control" id="room-password-val">
        </div>
      </div>
      <div class="modal-footer d-flex justify-content-center">
        <button class="btn btn-default" id="room-password-btn">Enter</button>
      </div>
    </div>
  </div>
</div>

您已经检查了您的模式是否显示在这一行之后。
$(“#密码验证”).modal()执行以下操作:

console.log($('#密码验证').is(':visible')//false每次
console.log($('#密码验证').hasClass('in'))//每次都是false
所以这两行在显示模态之前先执行。此事件显示模式后,您可以检查此选项:

$(“#密码验证”).on('show.bs.modal',function(){
//仅在显示模式后才会进入
console.log($(“#密码验证”).is(“:visible”)//如果显示,则每次都为true
console.log($('#密码验证').hasClass('show'))//如果显示,则每次都为true
});
仔细查看,
$(“#密码验证”).hasClass('in')
这在
引导程序4中不起作用。因此,您可以通过我在事件中提到的这种方式检查是否显示模态。


我想这会解决您的问题。

您已经检查了您的模式是否显示在这一行后面。
$(“#密码验证”).modal()执行以下操作:

console.log($('#密码验证').is(':visible')//false每次
console.log($('#密码验证').hasClass('in'))//每次都是false
所以这两行在显示模态之前先执行。此事件显示模式后,您可以检查此选项:

$(“#密码验证”).on('show.bs.modal',function(){
//仅在显示模式后才会进入
console.log($(“#密码验证”).is(“:visible”)//如果显示,则每次都为true
console.log($('#密码验证').hasClass('show'))//如果显示,则每次都为true
});
仔细查看,
$(“#密码验证”).hasClass('in')
这在
引导程序4中不起作用。因此,您可以通过我在事件中提到的这种方式检查是否显示模态。

我想这会解决你的问题。

(我用简单的
alert()
s替换了你的
toastr
内容,并注释掉了
socket
内容)

问题是您正在基于可重复的用户活动添加事件侦听器。例如:

if(room_pass != "False"){ 
    // ...
    // Adding an event handler for the modal shown event based on 
    // previous user activity
    $('#password-validation').on('shown.bs.modal', function () {
        // ... 
        // Adding another event handler, inside a previous event handler
        $("#room-password-btn").mousedown(function(){
但是添加一个事件处理程序并不能替换之前已经连接的任何事件处理程序——它们会堆叠起来,即使对于完全相同的事件它是完全相同的处理程序。因此,如果您重复添加处理程序的条件,您将在旧处理程序的基础上添加一个新的处理程序。触发时,它们将一起运行

每次关闭模态时,都会在模态打开时添加另一个处理程序来执行某些操作,这反过来又会在
mousedown
上添加另一个处理程序来执行某些操作。当您第一次关闭它时,您有一组处理程序来处理这些事情。如果您打开并再次关闭它,则会添加一个新的集合,当事件触发时,这些集合将全部运行

只添加一次处理程序是一种更好的方法,与任何用户行为或条件无关。这样,您可以确保它们只连接一次。如果希望处理程序执行的操作取决于用户所做的操作,则应该测试处理程序中的状态,而不是相反

因此,在这种情况下:

// Add event handlers, independent of any other activity
$('#password-validation').on('hidden.bs.modal', function () {
    console.log("Closed")
    // ...
});

$('#password-validation').on('shown.bs.modal', function () {
    $('#room-password-val').trigger('focus');
});

$("#room-password-btn").mousedown(function(){
    // ...
});

// ... 

if (room_pass != "False") {
    $("#password-validation").modal('toggle');

} else{
    console.log("Joining a room")
    // ...
}
注意,如果需要,您也可以这样做,在某些复杂的情况下,这可能是一种方法——随着状态的变化添加和删除处理程序。但是这里没有必要有这么多的复杂情况

更新 从评论中可以看出,实际问题在于一些代码中没有显示,这些代码处理用户单击聊天室菜单的行为,该菜单是从数据库动态填充的。我描述了如何处理上述问题的一般情况—测试事件处理程序中的状态,以便采取适当的操作。这里有一个例子-不是基于你的实际HTML或代码,因为我没有

HTML示例:

<ul class="dropdown-menu">
    <li><a href="/rooms/chat1" data-room="room1">Chat 1</a></li>
    <li><a href="/rooms/chat2" data-room="room2">Chat 2</a></li>
    <li><a href="/rooms/chat3" data-room="room3">Chat 3</a></li>
</ul>
JS:

//密码将在下面的AJAX中设置
var room_pass;
//在.下拉菜单上注册处理程序,即使它没有元素
//在页面加载时。每次单击都将被过滤以检查是否正确
//在一条路上。通过这种方式,您可以动态地向菜单添加内容,
//并且仍然可以处理这些点击。
$('.下拉菜单')。在('单击','a',函数(e)上{
//不要真的跟随链接
e、 预防默认值();
//在处理程序中,“$(this)”是事件目标
//查找按如下方式单击的链接:
var href=$(this.attr('href');
//或其案文:
var text=$(this.text();
//或者它有数据属性
var room=$(this.data('room');
//我不确定我是否理解你的评论,但也许你想要点什么
//像这样,您将有关单击的链接的内容传递到
//AJAX查询
$.ajax({
类型:“POST”,
url:“/validate”,
资料室:,
成功:功能(通过){
房间通行证=通行证;
}
});
});
<ul class="dropdown-menu">
    <li><a href="/rooms/chat1" data-room="room1">Chat 1</a></li>
    <li><a href="/rooms/chat2" data-room="room2">Chat 2</a></li>
    <li><a href="/rooms/chat3" data-room="room3">Chat 3</a></li>
</ul>
// Password will be set in AJAX below
var room_pass;

// Register a handler on .dropdown-menu, even if it has no elements
// on page load.  Every click will be filtered to check it it was 
// on an <a>.  This way you can dynamically add contents to the menu,
// and still handle those clicks.
$('.dropdown-menu').on('click', 'a', function(e) {

    // Don't actually follow the link 
    e.preventDefault();

    // In the handler, "$(this)" is the event target.  So you can 
    // find which link was clicked like this:
    var href = $(this).attr('href');
    
    // Or its text:
    var text = $(this).text();

    // Or maybe it has data attributes
    var room = $(this).data('room');

    // Not sure I understand your comments but maybe you want something
    // like this, where you pass something about the clicked link to the
    // AJAX query
    $.ajax({
        type: "POST",
        url: "/validate",
        data: room,
        success: function(pass) {
            room_pass = pass;
        }
    });
});
$('#password-validation').on('shown.bs.modal', function () {
$('#room-password-val').trigger('focus');
$("#password-validation").off("shown.bs.modal");
$('#password-validation').one('shown.bs.modal', function () {
   $('#room-password-val').trigger('focus');
}