图片加载失败优化处理

第一部分:

   网站运营时间长了以后,或者引入的一些图片的连接失效了等等缘由,不可避免的会出现图片加载失败的状况。这样给用户的体验很是很差,而且若是前端开发人员在设置img的css属性不当时,对页面的总体布局也会形成极大的影响。css

  好比,一个图片链接失效,即便咱们添加了alt属性,让用户知道这是什么图片,可是显然体验也是极为糟糕的,以下所示:html

    那么有什么好的方法能够解决这个问题呢? 前端

  咱们能够利用图片的onerror属性,设置以下:vue

 <img src="'一个错误的连接" onerror="this.src='http://www.bianbiangou.cn/index/ICON2.png'" alt="picture">

  即当链接发生了错误以后,即会触发onerror中的函数,咱们就能够来从新设置src的属性值了,好比能够设置为公司、网站的商标等等,效果以下:node

     

  可是这种方法会出现这样的一个问题: 若是在onerror中设置的图片链接也是无效的,那么onerror的触发就构成了一个死循环,这样,图片就会一直不停地报错,不停的加载。。。jquery

  为了解决这一问题,咱们能够在第二次请求的时候中止请求,即便用jquer的one方法便可,先获取到元素,而后绑定一个方法。服务器

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>testError</title>
  <script
  src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
</head>
<body>
  <img src="fad"  alt="">
  <script>
    $("img").on('error',function () {
      $(this).attr('src', 'http://www.bianbiangou.cn/index/ICON2.png');
    });
  </script>
</body>
</html>

  如上所示,显然img的src是一个不可用的属性,若是出错了,咱们就能够用一个以前准备好的图片链接来替换,可是若是这个也出错了呢? 以下:ide

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>testError</title>
  <script
  src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
</head>
<body>
  <img src="fad"  alt="">
  <script>
    $("img").on('error',function () {
      $(this).attr('src', 'ht.png');
    });
  </script>
</body>
</html>

  那么控制台就会一直报错,以下所示:函数

 

  这时候就是咱们用到 jquery的one方法来解决问题的时候了,以下:布局

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>testError</title>
  <script
  src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
</head>
<body>
  <img src="fad"  alt="">
  <script>
    $("img").one('error',function () {
      $(this).attr('src', 'ht.png');
    });
  </script>
</body>
</html>

  这样即便是咱们备用的图片也出错了,也不用担忧一直报错的问题了。  

 

 

   上面说的是通常的图片的处理方法,在vue的项目中,咱们一样可使用vue提供的once方法,template内的代码以下:

<div class="item-img">
  <img id="errorImg" v-bind:src="'http://bbg-seller.oss-cn-qingdao.aliyuncs.com/test/gp/p1/' + item.picture" v-on:error.once="dosomething($event)" v-bind:alt="item.name">
</div>

  在methods下咱们的代码以下:

     dosomething: function (e) {
        e.currentTarget.src = "http://www.ianbiangou.cn/index/ICON2.png"
      }

  这样就能够保证即便咱们使用替换的图片也出错了,也不会一直请求服务器,而只是请求一次。 

   在vue项目中,若是可以使用vue的方式就不要使用jquery,实际上jquery能够实现的vue也能实现,可是对于DOM的处理,一些事件的处理,jquery确实很强。

    可是应当注意这样的一个问题:vue构建的是单页面应用,因此在不一样的路由切换时并无加载整个页面,那么once所致使的问题就是只在第一次进入页面时有效,一旦切换路由再切换回来就不能用了,因此这里使用once仍是有问题的,这样,咱们尽量的保证替换的图片的存在,毕竟就这一张图片,总得留下吧~~     因而最终咱们仍是应该在vue中使用v-on:error=""的形式,这样在不从新加载页面的状况下切换路由也能保证图片的正确替代了。

  固然,这只是最简单的一种解决方法,还有不少的方法值得咱们去学习和探索,而这也只是一个开头,咱们将由这个例子,对图片的加载等进行更深一步的认识。

 

 

 

第二部分

  img标签的事件:

  • onabort
  • onbeforeunload
  • onblur
  • onclick
  • oncontextmenu
  • ondbclick
  • ondrag
  • ondragend
  • ondragleave
  • ondragover
  • ondragstart
  • onerror
  • onfocus
  • onkeydown
  • onkeypress
  • onkeyup
  • onload
  • onmessage
  • onmousedown
  • onmousemove
  • onmouseover
  • onmouseout
  • onmouseup
  • onmousewhell
  • onresize
  • onscroll
  • onselect
  • onsubmit
  • onunload

 能够看出其中的不少事件都是通用的事件,而针对于图片下面几种事件是比较重要的:

  • onerror  图片加载过程当中发生错误而触发
  • onabort  图片加载时用户点击中止加载时触发,一般这里触发一个提示:图片正在加载。
  • onload  图片加载完成以后触发

  

对图片进行监听onerror事件

html

<img src="someimage.png" onerror="imgError(this);" />

 

js

// 原生JS:
function imgError(image){
    // 方案一:隐藏图片
    image.style.display = 'none';
    // 方案二:替换为默认图片
    // document.getElementById("img").setAttribute("src", "images/demo.png");
}
 
// 使用jQuery处理:
function imgError(image){
   // 方案一: 隐藏图片 $(image).hide();
   // 方案二: 替换为默认图片
// $(this).attr("src", "images/demo.png"); }

 

 

 

使用jquery进行监听

// 一般不会再HTML里面内联js,可使用.error对图片进行监听处理
$('#test img').error(function() {
    $(this).hide();
    // $(this).attr("src", "images/demo.png");
});

 

 

 

 

使用函数处理

// 原生JS解决方案
function $id(id) {
    return !id || id.nodeType === 1 ? id : document.getElementById(id);
}
function isType(o, t) {
    return (typeof o).indexOf(t.charAt(0).toLowerCase()) === 0;
}
 
// 主要逻辑
function image(src, cfg) {
    var img, prop, target;
    cfg = cfg || (isType(src, 'o') ? src : {});
 
    img = $id(src);
    if (img) {
        src = cfg.src || img.src;
    } else {
        img = document.createElement('img');
        src = src || cfg.src;
    }
 
    if (!src) {
        return null;
    }
 
    prop = isType(img.naturalWidth,'u') ? 'width' : 'naturalWidth';
    img.alt = cfg.alt || img.alt;
 
    // Add the image and insert if requested (must be on DOM to load or
    // pull from cache)
    img.src = src;
 
    target = $id(cfg.target);
    if (target) {
        target.insertBefore(img, $id(cfg.insertBefore) || null);
    }
 
    // Loaded?
    if (img.complete) {
        if (img[prop]) {
            if (isType(cfg.success,'f')) {
                cfg.success.call(img);
            }
        } else {
            if (isType(cfg.failure,'f')) {
                cfg.failure.call(img);
            }
        }
    } else {
        if (isType(cfg.success,'f')) {
            img.onload = cfg.success;
        }
        if (isType(cfg.failure,'f')) {
            img.onerror = cfg.failure;
        }
    }
 
    return img;
}

 

 

以上函数有不少用处:

1. 获取图片信息:图片是否可下载,图片宽高

image('img',{
    success : function () { alert(this.width + "-" + this.height); },
    failure : function () { alert('image 404!'); },
});
 
// 验证资源是否下载
image('http://cdn.xuanfengge.com/wp-content/themes/lee2.0/images/banner/banner_2.jpg', {
    success : function () {console.log('sucess')},
    failure : function () {console.log('failure')},
    target : 'myContainerId',
    insertBefore : 'someChildOfmyContainerId'
});

 

 

2. 下载并插入图片

var report = $id('report'),
    callback = {
        success : function () {
            report.innerHTML += '<p>Success - ' + this.src + ' ('+this.offsetWidth+'x'+this.offsetHeight+')</p>';
        },
        failure : function () {
            report.innerHTML += '<p>Failure - ' + this.src + ' ('+this.offsetWidth+'x'+this.offsetHeight+')</p>';
        },
        target : 'target'
    };
 
image('img', callback);
image('http://cdn.xuanfengge.com/wp-content/themes/lee2.0/images/banner/banner_2.jpg', callback);

 

 

 

 

 参考文章: http://www.xuanfengge.com/js-image-loading-and-404.html

http://www.w“two”bc.com/article/170738

相关文章
相关标签/搜索