繁体   English   中英

没有触发的自定义事件

[英]Custom events without trigger

我具有以下javascript函数,可用于为在任何给定容器中加载的图像创建基本的事件处理程序...

function onImagesLoaded($container, callback) {
    var $images = $container.find("img");
    var imgCount = $images.length;
    if (!imgCount) {
        callback();
    } else {
        $images.each(function () {
            $(this).one("load error", function () {
                imgCount--;
                if (imgCount == 0) {
                    callback();
                }
            });
            if (this.complete) $(this).load();
        });
    }
}

我现在用这样的东西来称呼它...

onImagesLoaded($("div.image-container"), function() {
    console.log("Images loaded");
});

这很好并且可以工作,但是我希望能够将它附加到这样的元素上...

$("div.image-container").on("imagesloaded", function() {
    console.log("Images loaded");
});

这不是“我的代码不起作用-请修复它”类型的问题,因为它确实可以工作,并且确实可以实现我想要的功能(就功能而言)。 我问这个问题是因为我找不到与如何按照自己想做的方式做事有关的帮助,而且我正在尝试学习新的东西。 我所读到的有关jQuery自定义事件的所有内容都需要您手动触发它们,而这不是我要在此处进行的操作。

我是说我想将事件处理程序附加到某个元素,然后由于该事件处理程序而将我的功能分配给该元素。 也许我需要手动解析DOM中的元素才能做到这一点-我不知道。

至少有人可以指出我的方向(如果可以的话)吗?

编辑

我开始以类似于下面的KevinB建议的方式来覆盖现有的on()函数。 他提供的代码涵盖了我的版本存在的几个问题,因此我将两者合并在一起,并提出了一个有效的版本。

var $_on = $.fn.on

$.fn.on = function () {
    switch (arguments[0]) {
        case "imagesloaded":
            onImagesLoaded(this, arguments[1]);
            break;
        default:
            return $_on.apply(this, arguments);
            break;
    }
};

像我在上面的问题中所说的那样,现在可以使用.on()附加自定义事件处理程序。

事后看来,问题标题措辞不佳。 它应该只覆盖了on()

另一个编辑

经过对此事的进一步思考,我决定创建一个createEvent()方法,以便可以轻松地向jQuery的on()添加自定义事件。 如果有人浏览此页面并正在寻找该页面,则可以在这里找到...

http://johncmolyneux.blogspot.co.uk/2013/12/how-to-override-jquery-on-and-add.html

该页面上还有一个指向GitHub上jquery.extend库的链接,每当我做出我认为应该添加的内容时,我都会添加到该链接。

我会把它变成一个插件并以这种方式使用它:

$.loadImages = function($images, callback) {        
    var imgCount = $images.length;
    if (!imgCount) {
        callback();
    } else {
        $images.each(function () {
            /*$(this).one("load error", function () {
                imgCount--;
                if (imgCount == 0) {
                    callback();
                }
            });
            if (this.complete) $(this).load();*/
            var img = new Image();
            $(img).on("load error", function(){
                imgCount--;
                if (imgCount == 0) {
                    callback();
                }
            });
            img.src = this.src;
        });
    }
};
$.fn.loadImages = function (callback) {
    var $images = this.find("img").addBack().filter("img");
    var self = this;
    $.loadImages($images,function(){
        if ($.isFunction(callback)) {
            callback();
        }
        self.trigger("imagesLoaded");
    });
};

现在您可以像这样使用它:

$.loadImages($("div.image-container").find("img"), function() {
    console.log("Images loaded");
});

或者您可以像这样使用它:

$("div.image-container").on("imagesLoaded",function(){
    console.log("Images loaded");
}).loadImages();

甚至像这样:

$("div.image-container").loadImages(function(){
    console.log("Images loaded");
});

这也适用:

$("div.image-container img").loadImages(function(){
    console.log("Images loaded");
});

没有办法使.on自动使插件运行而无需猴子补丁.on,这通常是一个坏主意。 它可能看起来像这样:

var oldOn = $.fn.on

$.fn.on = function() {
    var ret = oldOn.apply(this,arguments);
    if (arguments[0] == "imagesloaded") {
        var self = this;
        onImagesLoaded(this,function(){
            self.trigger("imagesloaded");
        });
    }
    return ret;
};

暂无
暂无

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

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