122 votes

Détection du support WebP

Comment puis-je détecter la prise en charge de WebP via Javascript ? J'aimerais utiliser la détection des fonctionnalités plutôt que celle du navigateur si possible, mais je ne trouve pas de moyen de le faire. Modernizr ( www.modernizr.com ) ne le vérifie pas.

2 votes

Si vous chargez une telle image dans un élément Image, et que vous vérifiez ensuite la largeur et la hauteur dans un navigateur qui n'a pas supporte le format, est-ce que vous obtenez quelque chose ?

0 votes

(Je voulais dire "Image objet ", pas élément ; comme, "nouvelle Image()" ... )

0 votes

Ça a l'air bien. Je peux obtenir un "Je supporte WebP" de cette façon, mais je ne peux pas obtenir un "Je ne supporte pas WebP".

56voto

Pointy Points 172438

Je pense que quelque chose comme ça pourrait marcher :

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

Dans Firefox et IE, le gestionnaire "onload" n'est pas appelé du tout si l'image ne peut pas être comprise, et le gestionnaire "onerror" est appelé à la place.

Vous n'avez pas mentionné jQuery, mais à titre d'exemple pour gérer la nature asynchrone de cette vérification, vous pourriez renvoyer un objet 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();
}

Alors vous pourriez écrire :

hasWebP().then(function() {
  // ... code to take advantage of WebP ...
}, function() {
  // ... code to deal with the lack of WebP ...
});

Voici un exemple de jsfiddle.


Un vérificateur plus avancé : http://jsfiddle.net/JMzj2/29/ . Celui-ci charge les images à partir d'une URL de données et vérifie si le chargement est réussi. Étant donné que WebP prend également en charge les images sans perte, vous pouvez vérifier si le navigateur actuel prend en charge uniquement WebP avec perte ou également WebP sans perte. (Remarque : cette vérification porte aussi implicitement sur la prise en charge des URL de données).

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

0 votes

Génial ! Cela fonctionne dans FF, Chrome, et IE 9. Pour une raison quelconque, il ne fonctionne pas dans IE8 ou IE7.

0 votes

Cela fonctionne pour moi dans IE7 - essayez le jsFiddle que je viens de lier à la fin de la réponse.

0 votes

Ma réponse originale contenait juste le "onload" - je ne savais pas qu'il existait un "onerror" pour les objets Image :-)

22voto

Jakobud Points 14581

C'est une vieille question, mais Modernizr prend désormais en charge la détection Webp.

http://modernizr.com/download/

Cherchez img-webp sous la rubrique Détecteurs non essentiels.

3 votes

La source est utile pour voir ce qu'ils ont fait github.com/Modernizr/Modernizr/blob/

0 votes

Pour moi, il a fonctionné de manière assez fiable et vous permet de travailler avec des classes css .webp et .no-webp pour plus de flexibilité.

12voto

James Westgate Points 6789

Voici le code sans avoir à demander une image. Mis à jour avec le nouveau fiddle de 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';
});

5 votes

C'était complètement cassé pour moi. J'ai bifurqué et l'ai fait fonctionner : jsfiddle.net/z6kH9

0 votes

Cela fonctionnera-t-il dans tous les navigateurs ? Je fais référence aux problèmes des autres solutions dans Safari + FF65+.

0 votes

Je pense que celle-ci est la meilleure solution. J'aimerais quand même voir les tests sur les navigateurs plus anciens, et les navigateurs qui ne supportent pas le webp.

5voto

unxed Points 91

WebPJS utilise une détection plus intelligente du support WebP, sans qu'aucune image externe ne soit nécessaire : http://webpjs.appspot.com/

0 votes

Le script qu'ils utilisent pour charger leur fichier peut être utilisé sans utiliser réellement leur fichier. Remplacez simplement l'intérieur par ce que vous souhaitez faire s'il n'y a pas de support WebP.

1 votes

Il semble qu'ils utilisent des urls de données, c'est ce que j'ai fini par utiliser.

5voto

sorrycc Points 31

J'ai trouvé la fonction de détection de support webp qui nécessite 300+ms lorsque la page est lourde en JavaScript. J'ai donc écrit un script avec des fonctions de mise en cache :

  • script cachette
  • cache de stockage local

Il ne sera détecté qu'une seule fois, lors du premier accès de l'utilisateur à la page.

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

})();

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X