第二次加载时,动作会多次触发

时间:2015-09-01 13:58:37

标签: javascript jquery twitter-bootstrap modal-dialog

问题

我有一个使用app wide的模态。此模式的内容和确认操作会根据所点击的内容而更改。

这个模态第一次发布时,一切都很好,花花公子,模态确认只发射一次。

任何时候,模态会三次触发确认动作。

我的代码

我的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();
}

我创建了fiddle that replicates this behaviour

问题

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

2 个答案:

答案 0 :(得分:0)

你打电话 每次调用showModal时都会调用setEventListeners()方法。

在setEventListeners方法

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

此行一次又一次地注册事件。如果您将事件的回调注册n次。当一个事件发生时,回调被触发n次。

快速解决方案;

从showModal()

中删除setEventListeners()方法调用

答案 1 :(得分:0)

所以我通过制作removePageListeners函数来修复它。

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

        $(this).off(theEvent);
    });
}

我在打开模态后立即调用它。

更新了fiddle here