检测WebP支持
我怎样才能通过Javascript检测WebP的支持? 如果可能的话,我想使用function检测而不是浏览器检测,但是我找不到这样做的方法。 Modernizr( www.modernizr.com )不检查它。
我认为这样的事情可能会起作用:
var hasWebP = false; (function() { var img = new Image(); img.onload = function() { hasWebP = !!(img.height > 0 && img.width > 0); }; img.onerror = function() { hasWebP = false; }; img.src = 'webp/gallery/1.webp'; })();
在Firefox和IE中,如果图像无法被理解,“onload”处理程序根本不会被调用,而是调用“onerror”。
你没有提到jQuery,但作为一个例子来说明如何处理这个检查的asynchronous性质,你可以返回一个jQuery“Deferred”对象:
function hasWebP() { var rv = $.Deferred(); var img = new Image(); img.onload = function() { rv.resolve(); }; img.onerror = function() { rv.reject(); }; img.src = 'webp/gallery/1.webp'; return rv.promise(); }
然后你可以写:
hasWebP().then(function() { // ... code to take advantage of WebP ... }, function() { // ... code to deal with the lack of WebP ... });
这是一个jsfiddle的例子。
更高级的检查器: http : //jsfiddle.net/JMzj2/29/ 。 这一个从数据URL加载图像,并检查是否加载成功。 由于WebP现在还支持无损图像,因此您可以检查当前浏览器是否支持有损WebP或无损WebP。 (注意:这隐含地也检查数据URL支持。)
var hasWebP = (function() { // some small (2x1 px) test images for each feature var images = { basic: "data:image/webp;base64,UklGRjIAAABXRUJQVlA4ICYAAACyAgCdASoCAAEALmk0mk0iIiIiIgBoSygABc6zbAAA/v56QAAAAA==", lossless: "data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAQAAAAfQ//73v/+BiOh/AAA=" }; return function(feature) { var deferred = $.Deferred(); $("<img>").on("load", function() { // the images should have these dimensions if(this.width === 2 && this.height === 1) { deferred.resolve(); } else { deferred.reject(); } }).on("error", function() { deferred.reject(); }).attr("src", images[feature || "basic"]); return deferred.promise(); } })(); var add = function(msg) { $("<p>").text(msg).appendTo("#x"); }; hasWebP().then(function() { add("Basic WebP available"); }, function() { add("Basic WebP *not* available"); }); hasWebP("lossless").then(function() { add("Lossless WebP available"); }, function() { add("Lossless WebP *not* available"); });
这是我的解决scheme – 大约需要6ms,我正在考虑WebP只是现代浏览器的一个function。 使用不同的方法,使用canvas.toDataUrl()函数而不是图像作为检测function的方式:
function canUseWebP() { var elem = document.createElement('canvas'); if (!!(elem.getContext && elem.getContext('2d'))) { // was able or not to get WebP representation return elem.toDataURL('image/webp').indexOf('data:image/webp') == 0; } else { // very old browser like IE 8, canvas not supported return false; } }
WebPJS使用更智能的WebP支持检测,无需外部映像: http ://webpjs.appspot.com/
这里是代码,而不必要求一个图像(部分来自webpjs.appspot.com)
的jsfiddle
function testWebP(callback) { var webP = new Image(); webP.src = 'data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA'; webP.onload = webP.onerror = function () { callback(webP.height === 2); }; }; function notify(supported) { console.log((supported) ? "webP supported!" : "webP not supported."); } testWebP(notify);
我发现当JavaScript页面很重时,webp支持function检测需要300 + ms。 所以我写了一个cachingfunction的脚本 :
- 脚本caching
- 本地存储caching
用户第一次访问页面时只会检测一次。
/** * @fileOverview WebP Support Detect. * @author ChenCheng<sorrycc@gmail.com> */ (function() { if (this.WebP) return; this.WebP = {}; WebP._cb = function(isSupport, _cb) { this.isSupport = function(cb) { cb(isSupport); }; _cb(isSupport); if (window.chrome || window.opera && window.localStorage) { window.localStorage.setItem("webpsupport", isSupport); } }; WebP.isSupport = function(cb) { if (!cb) return; if (!window.chrome && !window.opera) return WebP._cb(false, cb); if (window.localStorage && window.localStorage.getItem("webpsupport") !== null) { var val = window.localStorage.getItem("webpsupport"); WebP._cb(val === "true", cb); return; } var img = new Image(); img.src = "data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA"; img.onload = img.onerror = function() { WebP._cb(img.width === 2 && img.height === 2, cb); }; }; WebP.run = function(cb) { this.isSupport(function(isSupport) { if (isSupport) cb(); }); }; })();
WebP图像与htaccess
将以下内容放在.htaccess
文件中,如果在相同的文件夹中find,则将使用WebP图像replacejpg / png图像。
<IfModule mod_rewrite.c> RewriteEngine On # Check if browser support WebP images RewriteCond %{HTTP_ACCEPT} image/webp # Check if WebP replacement image exists RewriteCond %{DOCUMENT_ROOT}/$1.webp -f # Serve WebP image instead RewriteRule (.+)\.(jpe?g|png)$ $1.webp [T=image/webp,E=accept:1] </IfModule> <IfModule mod_headers.c> Header append Vary Accept env=REDIRECT_accept </IfModule> <IfModule mod_mime.c> AddType image/webp .webp </IfModule>
在这里阅读更多
HTML5
首选解决scheme
<picture> <source srcset="/path/to/image.webp" type="image/webp"> <img src="/path/to/image.jpg" alt="insert alt text here"> </picture>