以全局监听的方式处理img的error事件

http://www.ovaldi.org/2015/09/11/%E4%BB%A5%E5%85%A8%E5%B1%80%E7%9B%91%E5%90%AC%E7%9A%84%E6%96%B9%E5%BC%8F%E5%A4%84%E7%90%86img%E7%9A%84error%E4%BA%8B%E4%BB%B6/

在开发一些电商页面时,往往会有大量的商品图片信息,当图片加载失败时,我们希望以一种更加友好的的方式改善用户体验:比如,换成一张友好的提示图片。

img标签在加载失败时,会触发error事件,所以,我们可以这么做

$("img").on("error", function(){

this.src = "/img/hint.jpg";

});

无法监听到动态产生的img标签然而,这种处理方法存在两个问题:

  1. 给每一个img元素都绑定事件处理函数带来的页面性能损耗

那么,如何解决上面的问题呢?也许你会说利用事件冒泡的机制来监听,可惜error事件并不会冒泡!
(事实上,在W3C的DOM Level 2 Events中规定,error事件是会冒泡的,而在DOM Level 3 Events中规定,error事件是不会冒泡的。)

要解决上述两个问题,我们需要先了解一下DOM事件发生的三个阶段:

  1. 捕获阶段: 从根节点开始顺序而下,检测每个节点是否注册了事件处理函数。在标准浏览器中,我们可以通过指定addEventListener的第三个参数useCapture为true,以使事件处理函数在该阶段运行。(低版本IE中无法指定事件处理函数在该阶段执行)
  2. 目标阶段: 触发在目标对象本身注册的事件处理函数,也称正常事件派发阶段。
  3. 冒泡阶段: 从目标节点到根节点,检测每个节点是否注册了事件处理函数。在标准浏览器中,我们可以通过指定addEventListener的第三个参数useCapture为true,以使事件处理函数在该阶段运行。

通过了解以上三个阶段,我们就可以使用如下代码解决:

document.addEventListener("error", function(e){

var elem = e.target;

if(elem.tagName.toLowerCase() === ‘img‘){

elem.src = "/img/hint.jpg";

}

}, true /*指定事件处理函数在捕获阶段执行*/);

需要注意的是,由于低版本IE中attachEvent方法无法指定事件处理函数在捕获阶段执行,所以,该方案在低版本IE中不能适用。

时间: 2024-11-07 22:58:03

以全局监听的方式处理img的error事件的相关文章

全局监听SCREEN_ON和SCREEN_OFF的替代方法--监听屏幕解锁事件

在做一个程序的时候,需要时刻保持某一服务是启动的,因此想到了通过监听屏幕SCREEN_ON和SCREEN_OFF这两个action.奇怪的是,这两个action只能通过代码的形式注册,才能被监听到,使用AndroidManifest.xml 完全监听不到.查了一下,发现这是PowerManager那边在发这个广播的时候,做了限制,限制只能有register到代码中的receiver才能接收. view plain private void registerScreenActionReceiver

全局监听Crash

package com.example.crashcatch; import java.io.File; import java.io.IOException; import java.lang.Thread.UncaughtExceptionHandler; import java.lang.reflect.Field; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; imp

Unity3D研究之监听Hierachy、Project等视图结构变化的事件

以前就有人问我怎么监听Hierarchy视图中创建或删除变化的事件,当时因为有别的事情就没研究这块.刚好最近有这一类的需求我就学习学习.网上发现了一个日本人写的文档,实现的原理很有意思,内容不错我就翻译一下.本文参考了一个游戏编程网的资料在此注明下. 请注意一定把这两个监听的脚本放在Editor文件夹下. 先是基类. using System; using System.Collections; using System.Reflection; using UnityEditor; using

View实现事件监听DEMO(文本跟随触屏事件)

View 是一个显示的视图,内置的画布通过重写Ondraw(Canvas canvas);方法获得,同时提供图形绘制函数.触屏事件.按键事件等. 现在利用一个简单的demo演示一下几个重要的常用到的方法: import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.view.K

Xamarin.Forms 监听Button的按下、释放事件

Xamarin.Forms 监听Button的按下.释放事件 工作中遇到这样的一个需求,模仿微信发生语音功能,需要实现按钮按下开始录音,按钮释放录音结束, Xamarin.Forms中Button没有这样的事件,那么我们如何实现对Button按下,释放两个事件的监听呢? 当然这里我们再次用到了CustomRenderer,一旦遇到Xamrin.Forms无法实现的某些功能,我们就可以 通过CustomRenderer来处理. 首先:我们自定义一个VoiceRecordButton继承于Butto

Android Button监听的方式

Android Button的几种监听方式 1.一个Button对应一个监听 1)xml文件中绑定监听 <Button android:id="@+id/btn_test" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="test listener" android:onClick="t

Android事件监听(二)——点击鼠标事件

Button.ImageButton事件监听(setOnClickListener) 方法一:通过匿名内部类实现 代码如下: package com.note.demo2; import android.support.v7.app.ActionBarActivity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; import

angular指令监听ng-repeat渲染完成后执行自定义事件方法

今天工作中遇到需要用到ng-repeat遍历渲染完后执行某个操作,angular本身并没有提供监听ng-repeat渲染完成的指令,所以需要自己创建自定义指令. 在ng-repeat模板实例内部会暴露出一些特殊属性$index/$first/$middle/$last/$odd/$even,$index会随着每次遍历(从0开始)递增,当遍历到最后一个时,$last的值为true,所以可以通过判断$last的值来监听ng-repeat的执行状态, 怎么在遍历过程中拿到$last的值:自定义指令 v

android 通过监听edittext实现button的点击事件

如果你没有接第三方的输入设备,那么点击按钮只需找到你的button然后: button.performClick(); 就可以了 那么如果你用到第三方输入法,有些时候监听就没有这么好使了: 以下场景为: 外接输入服务,直接给我丢一串字符,我拿到字符后执行按钮事件 代码如下:   editText1.addTextChangedListener(new TextWatcher(){             @Override             public void afterTextCha