动作在第二次加载时触发不止一次

Action fires more than once on second load

本文关键字:不止一次 加载 第二次      更新时间:2023-09-26

问题

我有一个应用程序范围内使用的模式。此模态的内容和确认操作会根据单击的内容而更改。

这个模态第一次启动时,一切都很好,模态的confirm只启动一次。

在任何其他时间,模态都会触发确认动作3次。

我的代码

我的HTML页面中的模式和按钮:

<div class="modal fade" tabindex="-1" role="dialog" id="confirmationModal">
    <div class="modal-dialog modal-sm">
        <div class="modal-content">
            <div class="modal-header"></div>
            <div class="modal-body"></div>
            <div class="modal-footer">
                <button class="btn btn-danger" data-event="click" data-action="closeModal">Cancel</button>
                <button class="btn btn-success" data-event="click">Confirm</button>
            </div>
        </div>
    </div>
</div>
<i class="fa fa-trash linked-fa red-fa" data-confirm="temDelete" data-event="click" data-id="template" data-header="Confirm Delete" data-body="Are you sure you want to delete Template?" data-action="showModal"></i>

我的Javascript(实际上是JQuery(

$(document).ready(function(e) {
    setEventListeners();
});
function setEventListeners() {
    // Find all elements with a data-action attribute
    $('[data-action]').each(function() {
        // Set the callback to the action
        // Link the event to the callback
        var theCallback = $(this).data('action');
        var theEvent = $(this).data('event');
        // If theEvent == 'load', do it immediately
        if(theEvent == 'load') {
            executeFunctionByName(theCallback,this,$(this));
        } else {
            // When the event fires, do the callback
            $(this).on(theEvent,function(e) {
                executeFunctionByName(theCallback,window,$(this),e)
            });
        }
    });
}
function executeFunctionByName(functionName,context) {
    // I actually have no freakin idea what this does
    // Google made me copy paste it.
    var args = [].slice.call(arguments).splice(2);
    var namespaces = functionName.split(".");
    var func = namespaces.pop();
    for(var i = 0; i < namespaces.length; i++) {
        context = context[namespaces[i]];
    }
    if(typeof context[func] !== 'undefined') {
        return context[func].apply(this, args);
    } else {
        console.log('Function not found.');
    }
}
function showModal(element) {
    // Get and set the body and header of the modal
    $('#confirmationModal .modal-header').html(element.data('header'));
    $('#confirmationModal .modal-body').html(element.data('body'));
    // Transfer all data fields from the clicked element to the confirm button in the Modal
    $.each(element.data(),function(i,v) {
        if(i != 'event') {
            if(i == 'confirm') { i = 'action'; } // If the data is confirm, change it to action, as this is the modal's action
            $('#confirmationModal .modal-footer .btn-success').attr('data-' + i,v);
        }
    });
    setEventListeners();
    // Set the page listeners and show the modal
    $('#confirmationModal').modal('show');
}
function closeModal() {
    $('#confirmationModal').modal('hide');
}
function temDelete() {
    $('.actionsfired').append('Delete Fired<br>');
    closeModal();
}

我创造了一把小提琴来复制这种行为。

问题

如何防止确认操作被触发3次?

您调用每次调用showModal时,setEventListeners((方法。

在setEventListeners方法中

$(this).on(theEvent,function(e) {
     executeFunctionByName(theCallback,window,$(this),e)
});

这一行一次又一次地注册事件。如果您对某个事件注册了n次回调。当一个事件发生时,会触发n次回调。

快速解决方案;

从showModal((中删除setEventListeners((方法调用

所以我通过生成removePageListeners函数来修复它。

function removePageListeners() {
    $('[data-action]').each(function() {
        var theEvent = $(this).data('event');
        $(this).off(theEvent);
    });
}

我打开模态后立即调用此命令。

此处更新了fiddle。