简体   繁体   English

jQuery click事件触发两次

[英]jQuery click event fires twice

I have a problem with a content overlay script I am developing. 我正在开发一个内容覆盖脚本的问题。 It seems that my closing event fires twice, but returns 'undefined' the first time (or second time, depending on which opening link you click). 似乎我的结束事件触发了两次,但第一次(或第二次,取决于你点击的开启链接)返回'undefined'。

You can find a stripped-down working example on JSFiddle: http://jsfiddle.net/UhSLy/2/ 你可以在JSFiddle上找到一个精简的工作示例: http//jsfiddle.net/UhSLy/2/

If you click on 1. Click and then on 2. Click it alerts undefined first, then Dummy . 如果单击1.单击然后再单击 2.单击它首先提示undefined ,然后单击 Dummy

When I delete one opening-link, everything works fine. 当我删除一个开放链接时,一切正常。 But I have to have multiple links since they open different overlays. 但是我必须有多个链接,因为它们打开了不同的叠加层。

What causes the problem and how can I avoid it? 导致问题的原因是什么,我该如何避免?

Edit: Code from JSFiddle follows: 编辑:来自JSFiddle的代码如下:

;(function ($, window, document, undefined) {

"use strict";

var pluginName = 'contentOverlay',
    defaults = {
        property:   'value'
    };

function Plugin(element, options) {
    this.element = element;
    this.$element = $(element);

    this.options = $.extend({}, defaults, options);

    this.init();
}

Plugin.prototype = {

    /**
     * Init
     */
    init: function () {
        var self = this;

        // Bind opening method
        this.$element.click(function() {
            self.open();
        });

        // Bind closing method
        $('#close').click(function() {
            self.close();
        });
    },

    /**
     * Open
     */
    open: function () {
        this.overlay = 'Dummy';
    },

    /**
     * Close
     */
    close: function () {
        alert(this.overlay); // <==== PROBLEM: fires twice. returns 'undefined' once
    },

};

$.fn[pluginName] = function (options) {
    return this.each(function () {
        if (!$.data(this, 'plugin_' + pluginName)) {
            $.data(this, 'plugin_' + pluginName,
                new Plugin(this, options));
        }
    });
}

$(function () {
    $('.open').contentOverlay();
});

})(jQuery, window, document);

$('#close').click(function() {
    self.close();
});

You're binding both objects close() methods to the close handler. 您将两个对象close()方法绑定到close处理程序。 Basically, when you click on the close button, it's running two functions, one for each of the overlay objects. 基本上,当您单击关闭按钮时,它会运行两个函数,每个函数对应一个覆盖对象。 Because one overlay object doesn't exist, it's returning undefined . 因为一个覆盖对象不存在,所以它返回undefined

You could get around this problem by: 您可以通过以下方式解决此问题:

close: function () {
    if(this.overlay != undefined){ // Skips over the undefined overlays
        alert(this.overlay);
    }
}

DEMO: http://jsfiddle.net/UhSLy/9/ 演示: http //jsfiddle.net/UhSLy/9/

If I may suggest look in here: http://jsfiddle.net/PgbfN/25/ 如果我建议你在这里查看: http//jsfiddle.net/PgbfN/25/

I reckon your this if condition which is to check if plugin is initialised is undefined hence runs through twice. 我认为你的这个if检查插件是否初始化是undefined因此会运行两次。

To resolve I added isApplied flag, once applied set the flag to true . 要解决我添加的isApplied标志,一旦应用将标志设置为true Rest hope demo will help :) 休息希望演示将有助于:)

Hope it helps 希望能帮助到你

$.fn[pluginName] = function(options) {
        return this.each(function() {
            alert('me ==> ' + (!$.data(this, 'plugin_' + pluginName)) + " ==== " + $.data(this, 'plugin_' + pluginName));
            if (!isApplied) {
                $.data(this, 'plugin_' + pluginName, new Plugin(this, options));

            }
        });
    }

full code 完整代码

var isApplied = false;

(function($, window, document, undefined) {

    "use strict";

    var pluginName = 'contentOverlay',
        defaults = {
            property: 'value'
        };

    function Plugin(element, options) {
        this.element = element;
        this.$element = $(element);

        this.options = $.extend({}, defaults, options);
        isApplied = true;
        this.init();
    }

    Plugin.prototype = {

        /**
         * Init
         */
        init: function() {
            var self = this;

            // Bind opening method
            this.$element.click(function() {
                self.open();
            });

            // Bind closing method
            $(document).on('click', '#close', function() {
                alert('Close is clicked');
                //self.close(); //<<== Is called
            });
        },

        /**
         * Open
         */
        open: function() {
            this.overlay = 'Dummy';
        },

        /**
         * Close
         */
        close: function() {
            alert(this.overlay); // <==== PROBLEM: fires twice. returns 'undefined' once
        },

    };

   $.fn[pluginName] = function(options) {
        return this.each(function() {
            alert('me ==> ' + (!$.data(this, 'plugin_' + pluginName)) + " ==== " + $.data(this, 'plugin_' + pluginName));
            if (!isApplied) {
                $.data(this, 'plugin_' + pluginName, new Plugin(this, options));

            }
        });
    }

    $(function() {
        $('.open').contentOverlay();
    });

})(jQuery, window, document);

I've came up with this (only the changes here) 我想出了这个(只有这里的变化)

open: function () {
        this.overlay = 'Dummy';
        this.opened=true;
},

$('#close').click(function() {
    if(self.opened) 
    {
        self.opened=false;
        self.close();
    }    
});

I think code explains everything. 我认为代码解释了一切。 The close event will never fire if an instance doesn't exist. 如果实例不存在,则close事件永远不会触发。

DEMO. DEMO。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM