簡體   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