sno*_*orm 68 html javascript image webp
如何通过Javascript检测对WebP的支持?如果可能的话,我想使用特征检测而不是浏览器检测,但我找不到这样做的方法.Modernizr(www.modernizr.com)没有检查它.
Rui*_*ues 82
这是我的解决方案 - 花费大约6毫秒,我正在考虑WebP只是现代浏览器的一项功能.使用canvas.toDataUrl()函数而不是image作为检测功能的方法使用不同的方法:
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;
}
// very old browser like IE 8, canvas not supported
return false;
}
Run Code Online (Sandbox Code Playgroud)
Poi*_*nty 52
我觉得这样的事情可能有用:
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 = 'http://www.gstatic.com/webp/gallery/1.webp';
})();
Run Code Online (Sandbox Code Playgroud)
在Firefox和IE中,如果无法理解图像,则根本不会调用"onload"处理程序,而是调用"onerror".
你没有提到jQuery,但作为如何处理该检查的异步性质的一个例子,你可以返回一个jQuery"Deferred"对象:
function hasWebP() {
var rv = $.Deferred();
var img = new Image();
img.onload = function() { rv.resolve(); };
img.onerror = function() { rv.reject(); };
img.src = 'http://www.gstatic.com/webp/gallery/1.webp';
return rv.promise();
}
Run Code Online (Sandbox Code Playgroud)
然后你可以写:
hasWebP().then(function() {
// ... code to take advantage of WebP ...
}, function() {
// ... code to deal with the lack of WebP ...
});
Run Code Online (Sandbox Code Playgroud)
一个更高级的检查器: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");
});
Run Code Online (Sandbox Code Playgroud)
And*_*ski 24
优选的解决方案 HTML5
<picture>
<source srcset="/path/to/image.webp" type="image/webp">
<img src="/path/to/image.jpg" alt="insert alt text here">
</picture>
Run Code Online (Sandbox Code Playgroud)
Jak*_*son 15
这是一个老问题,但Modernizr现在支持Webp检测.
http://modernizr.com/download/
寻找img-webp
非核心检测.
这是代码,无需请求图像.更新了qwerty的新小提琴.
function testWebP(callback) {
var webP = new Image();
webP.onload = webP.onerror = function () {
callback(webP.height == 2);
};
webP.src = 'data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA';
};
testWebP(function(support) {
document.body.innerHTML = support ? 'Yeah man!' : 'Nope';
});
Run Code Online (Sandbox Code Playgroud)
Google的官方方式:
由于某些旧的浏览器部分支持webp,因此最好更具体地说明您要使用哪种webp功能并检测该特定功能,这是Google对于如何检测特定webp功能的官方建议:
// check_webp_feature:
// 'feature' can be one of 'lossy', 'lossless', 'alpha' or 'animation'.
// 'callback(feature, isSupported)' will be passed back the detection result (in an asynchronous way!)
function check_webp_feature(feature, callback) {
var kTestImages = {
lossy: "UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA",
lossless: "UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==",
alpha: "UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",
animation: "UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA"
};
var img = new Image();
img.onload = function () {
var result = (img.width > 0) && (img.height > 0);
callback(feature, result);
};
img.onerror = function () {
callback(feature, false);
};
img.src = "data:image/webp;base64," + kTestImages[feature];
}
// Example Usage
check_webp_feature('lossy', function (feature, isSupported) {
if (isSupported) {
// webp is supported,
// you can cache the result here if you want
}
});
Run Code Online (Sandbox Code Playgroud)
请注意,图像加载是非阻塞且异步的。这意味着依赖于WebP支持的任何代码最好都应放在回调函数中。
另请注意,其他同步解决方案不适用于Firefox 65
小智 5
我发现当页面是 JavaScript 时,webp 支持功能检测需要 300+ms。所以我写了一个带有缓存功能的脚本:
它只会在用户第一次访问页面时检测一次。
/**
* @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();
});
};
})();
Run Code Online (Sandbox Code Playgroud)
这是James Westgate在ES6中答案的一个版本。
function testWebP() {
return new Promise(res => {
const webP = new Image();
webP.src = 'data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA';
webP.onload = webP.onerror = function () {
res(webP.height === 2);
};
})
};
testWebP().then(hasWebP => console.log(hasWebP));
Run Code Online (Sandbox Code Playgroud)
FF64:错误
FF65:是的
铬:真
我很喜欢Rui Marques的同步回答,但是不幸的是,尽管FF65能够显示WebP,但仍然返回false。
/* Here's a one-liner hack that works (without the use/need of any
externals...save bytes)...
Your CSS... */
body.no-webp .logo {
background-image: url('logo.png');
}
body.webp .logo {
background-image: url('logo.webp');
}
Run Code Online (Sandbox Code Playgroud)
...
<body>
<!--
The following img tag is the *webp* support checker. I'd advise you use any
(small-sized) image that would be utilized on the current page eventually
(probably an image common to all your pages, maybe a logo) so that when
it'll be (really) used on the page, it'll be loaded from cache by the
browser instead of making another call to the server (for some other image
that won't be).
Sidebar: Using 'display: none' so it's not detected by screen readers and
so it's also not displayed (obviously). :)
-->
<img
style='display: none'
src='/path/to/low-sized-image.webp'
onload="this.parentNode.classList.add('webp')"
onerror="this.parentNode.classList.add('no-webp')"
/>
...
</body>
<!-- PS. It's my first answer on SO. Thank you. :) -->
Run Code Online (Sandbox Code Playgroud)