Javascript 无触发器的自定义事件
我有下面的javascript函数,用于为任何给定容器中加载的图像创建基本事件处理程序Javascript 无触发器的自定义事件,javascript,jquery,Javascript,Jquery,我有下面的javascript函数,用于为任何给定容器中加载的图像创建基本事件处理程序 function onImagesLoaded($container, callback) { var $images = $container.find("img"); var imgCount = $images.length; if (!imgCount) { callback(); } else { $images.each(functi
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");
});
这是很好的,它的工作,但我想能够附加到像这样的元素
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()
附加自定义事件处理程序,正如我在上面的问题中所说的那样
事后看来,问题的标题措词不当。它应该就是这样的-覆盖()上的
另一次编辑
经过进一步思考,我决定创建一个createEvent()
方法,这样我就可以毫不费力地将自定义事件添加到jQuery的on()
。如果有人看到这个页面并正在寻找它,你可以在这里找到它
该页面上还有一个指向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");
});
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;
};
或者您可以这样使用它:
$.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");
});
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;
};
甚至像这样:
$.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");
});
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;
};
这也有效:
$("div.image-container img").loadImages(function(){
console.log("Images loaded");
});
没有办法使.on自动导致插件在没有monkeypatching.on的情况下运行,这通常是个坏主意。它可能看起来像这样:
$.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");
});
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;
};
在您触发所述事件之前,仅将事件附加到元素不会起任何作用。必须激发onImagesLoaded方法,并使其触发事件。你可以把你的函数变成一个插件,像这样使用:
$(“someselector”).on(“imagesloaded”,handler.loadImages()
,这就是我的观点,@KevinB。在我上面给出的示例中,尝试为自定义事件创建触发器是愚蠢的,因为它可以附加到页面中可以包含子元素的每个元素。对不起-是的,我们都在同时键入:)这很难解释,但我真正想要的是以某种方式捕获.on(“imageloaded”)这一事实
已被使用,然后手动将我的功能分配给所选元素。我不确定您的示例与此有何关联。顺便说一句,我自己想出的唯一答案是使用$.fn.onImagesLoaded()
。我更想问的是,这是否可以按我喜欢的方式完成。您可能还需要考虑这样一个事实,即可能会在触发dom就绪事件之前加载映像。。。因此,load error
事件将不会触发。通过创建新图像并以这种方式预加载,我不想重写他所做的一切。我想这是我最终要走的路线,这是我所期望的。理想情况下,我想知道有一种方法可以在上使用,而无需“蒙基补丁”:实际上。。。他似乎确实考虑到了这一点。@ArunPJohny我确实检查了图像是否已加载-if(this.complete)$(this.load()代码>