简体   繁体   English

没有触发的自定义事件

[英]Custom events without trigger

I have the following javascript function that I use to create a basic event handler for images being loaded in any given container... 我具有以下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();
        });
    }
}

I currently call that with something like this... 我现在用这样的东西来称呼它...

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

This is fine and it works, but I want to be able to attach it to elements like this... 这很好并且可以工作,但是我希望能够将它附加到这样的元素上...

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

This isn't a "my code doesn't work - please fix it" type of question, because it does work and does exactly what I want, functionality-wise. 这不是“我的代码不起作用-请修复它”类型的问题,因为它确实可以工作,并且确实可以实现我想要的功能(就功能而言)。 I'm asking this question as I can't find any help relating to how to do it the way I want to do it and I'm trying to learn something new. 我问这个问题是因为我找不到与如何按照自己想做的方式做事有关的帮助,而且我正在尝试学习新的东西。 Everything I've read about jQuery custom events requires you to manually trigger them, and that's not what I'm trying to do here. 我所读到的有关jQuery自定义事件的所有内容都需要您手动触发它们,而这不是我要在此处进行的操作。

I'm saying that I want to attach an event handler to an element and then assign my function to that element because of that event handler. 我是说我想将事件处理程序附加到某个元素,然后由于该事件处理程序而将我的功能分配给该元素。 Maybe I need to parse the elements in the DOM manually to do this - I don't know. 也许我需要手动解析DOM中的元素才能做到这一点-我不知道。

Can anyone at least point me in the direction of how this can be done (if it can)? 至少有人可以指出我的方向(如果可以的话)吗?

Edit 编辑

I started working on overriding the existing on() function in a similar way to how KevinB suggested below. 我开始以类似于下面的KevinB建议的方式来覆盖现有的on()函数。 The code he supplied covered a couple of issues I had with my version so I merged the two together and came up with a working version.... 他提供的代码涵盖了我的版本存在的几个问题,因此我将两者合并在一起,并提出了一个有效的版本。

var $_on = $.fn.on

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

Using that I can now attach custom event handlers using .on() , just as I said I wanted in the question above. 像我在上面的问题中所说的那样,现在可以使用.on()附加自定义事件处理程序。

In hindsight, the question title was worded badly. 事后看来,问题标题措辞不佳。 It should have been about just that - overriding on() . 它应该只覆盖了on()

Another Edit 另一个编辑

After further thought on the matter I decided to create a createEvent() method so I could add custom events to jQuery's on() without hassle. 经过对此事的进一步思考,我决定创建一个createEvent()方法,以便可以轻松地向jQuery的on()添加自定义事件。 If anyone comes across this page and is looking for that, you can find it here... 如果有人浏览此页面并正在寻找该页面,则可以在这里找到...

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

There's also a link on that page to the jquery.extend library on GitHub, which I will add to whenever I make something that I think should be added. 该页面上还有一个指向GitHub上jquery.extend库的链接,每当我做出我认为应该添加的内容时,我都会添加到该链接。

I would turn it into a plugin and use it this way: 我会把它变成一个插件并以这种方式使用它:

$.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");
    });
};

Now you can use it like this: 现在您可以像这样使用它:

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

or you can use it like this: 或者您可以像这样使用它:

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

or even like this: 甚至像这样:

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

this works too: 这也适用:

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

There is no way of making .on automatically cause the plugin to run without monkeypatching .on, which is usually a bad idea. 没有办法使.on自动使插件运行而无需猴子补丁.on,这通常是一个坏主意。 It might look something like this: 它可能看起来像这样:

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