自定义事件没有触发器

时间:2013-12-20 16:50:55

标签: javascript jquery

我有以下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中的元素才能做到这一点 - 我不知道。

任何人都可以至少指出我如何做到这一点(如果可以的话)?

修改

我开始尝试覆盖现有的on()函数,其方式与KevinB在下面的建议类似。他提供的代码涵盖了我的版本中的几个问题,所以我将两者合并在一起,并提出了一个可用的版本....

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库,每当我创建一些我认为应该添加的东西时,我都会添加它。

1 个答案:

答案 0 :(得分:3)

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

$.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自动导致插件在没有monkeypatching .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;
};
相关问题