網站運營時間長了以後,或者引入的一些圖片的連接失效了等等緣由,不可避免的會出現圖片加載失敗的狀況。這樣給用戶的體驗很是很差,而且若是前端開發人員在設置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標籤的事件:
能夠看出其中的不少事件都是通用的事件,而針對於圖片下面幾種事件是比較重要的:
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"); }
// 一般不會再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