117

Javascript を介した WebP のサポートを検出するにはどうすればよいですか? 可能であれば、ブラウザー検出ではなく機能検出を使用したいのですが、その方法が見つかりません。Modernizr ( www.modernizr.com ) はそれをチェックしません。

4

21 に答える 21

56

このようなものがうまくいくと思います:

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';
})();

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();
}

次に、次のように記述できます。

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");
});
于 2011-04-06T21:52:55.537 に答える
21

これは古い質問ですが、Modernizr は Webp 検出をサポートするようになりました。

http://modernizr.com/download/

img-webp非コア検出の下を探します。

于 2014-06-23T22:05:53.157 に答える
11

画像をリクエストする必要のないコードを次に示します。qwerty の新しいフィドルで更新されました。

http://jsfiddle.net/z6kH9/

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';
});
于 2012-06-07T10:58:13.210 に答える
5

ページの JavaScript が重い場合、webp サポート機能の検出には 300 ミリ秒以上かかることがわかりました。そこで、キャッシュ機能を備えたスクリプトを作成しました。

  • スクリプト キャッシュ
  • ローカル ストレージ キャッシュ

ユーザーが最初にページにアクセスしたときに一度だけ検出されます。

/**
 * @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();
    });
  };

})();
于 2013-04-09T09:25:47.787 に答える
5

WebPJS は、外部画像を必要としない、よりスマートな WebP サポート検出を使用します: http://webpjs.appspot.com/

于 2011-11-20T07:35:09.380 に答える
2

これは、Pointy の応答に基づく Promise を使用した単純な関数です。

let webpSupport = undefined // so we won't have to create the image multiple times
const webp1Px = 'data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA'

function isWebpSupported () {
  if (webpSupport !== undefined) {
    return Promise.resolve(webpSupport)
  }

  return new Promise((resolve, _reject) => {
    const img = new Image()
    img.onload = () => {
      webpSupport = !!(img.height > 0 && img.width > 0);
      resolve(webpSupport)
    }
    img.onerror = () => {
      webpSupport = false
      resolve(webpSupport)
    }
    img.src = webp1Px
  })
}
于 2018-08-05T13:27:15.937 に答える
1

素晴らしいニュース。Safariで動作します。

document.addEventListener('DOMContentLoaded', function() {
  testWebP(document.body)
})

function testWebP(elem) {
  const webP = new Image();
  webP.src = 'data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA';
  webP.onload = webP.onerror = function () {
    webP.height === 2 ? elem.classList.add('webp-true') : elem.classList.add('webp-false')
  }
  console.log(webP)
}

ソース: https://gist.github.com/Protoff/d6643387f03d47b44b2d7c3cf7b3e0a0

于 2021-09-02T10:25:38.730 に答える