简体   繁体   中英

jQuery plugin custom event trigger not firing

It's been a while since I've done a jQuery plugin and I'm working off a pretty common boilerplate with options and internal events. In one of the internal methods I need to trigger a custom event so that other pages can capture the event and work with it. More specifically in this usage, at the end of drawing on a canvas element I want to be able to capture the event outside of the plugin in order to grab the canvas content for sending elsewhere agnostic of the plugin itself.

However, it doesn't appear that the trigger call is either firing or finding the bound event from the other page. None of the console messages show up in Firebug.

Here's my sample plugin (simplified):

; (function ($, window, document, undefined) {
    "use strict";

    var $canvas,
        context,
        defaults = {
            capStyle: "round",
            lineJoin: "round",
            lineWidth: 5,
            strokeStyle: "black"
        },
        imgElement,
        options,
        pluginName = "myPlugin";

    function MyPlugin(element, opts) {
        this.imgElement = element;
        this.options = $.extend({}, defaults, opts);
        this._defaults = defaults;
        this._name = pluginName;
        this.init();
    }

    $.extend(MyPlugin.prototype, {
        init: function () {
            var $imgElement = $(this.imgElement);
            $canvas = $(document.createElement("canvas")).addClass("myPluginInstances");

            $imgElement.after($canvas);

            context = $canvas[0].getContext("2d");

            $canvas.on("mousedown touchstart", inputStart);
            $canvas.on("mousemove touchmove", inputMove);
            $canvas.on("mouseup touchend", inputEnd);
        }
    });

    $.fn.myPlugin = function (opts) {
        return this.each(function () {
            if (!$.data(this, "plugin_" + pluginName)) {
                $.data(this, "plugin_" + pluginName, new MyPlugin(this, opts));
            }
        });
    };

    function inputStart(event) {
        //...processing code
    }

    function inputMove(event) {
         //...processing code
    }

    function inputEnd(event) {
        //...processing code

        // Trigger custom event
        $(this.imgElement).trigger("mydrawevent", [this.toDataURL()]);
    }
}(jQuery, window, document));

Then from a separate page in the document.ready the event is bound:

$(".myPluginInstances").myPlugin().on("mydrawevent", function (e, data) {
    console.log("mydrawevent");
    console.log(data);
});

From Firebug I am seeing that the imgElement does have the listener bound:

mydrawevent
    -> function(a)
        -> function(e, data)

I've tried quite a few things such as calling the trigger on different DOM elements, passing the event parameter data in and out of the array, defining a callback method instead (which had its own issues), and more. I have a feeling the problem is something dumb and right in front of me but I could use more sets of eyes to double check my sanity.

As further explanation for my response to Vikk above, the problem was indeed scoping and understanding which objects were bound to what parts of the plugin. In my case, the internal methods that are private event handlers were bound to my canvas element but the plugin itself was being instantiated on the img element which is at least a temporary requirement of this particular implementation.

Based on this, from the internal event handler the use of $(this) meant that it was trying to use trigger on my canvas element and not the img element which had the mydrawevent listener attached to it from outside the plugin.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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