web-dev-qa-db-fra.com

Meilleure façon de détecter que HTML5 <canvas> n'est pas pris en charge

Le moyen standard de gérer les situations dans lesquelles le navigateur ne prend pas en charge la balise HTML5 <canvas> consiste à incorporer du contenu de secours tel que

<canvas>Your browser doesn't support "canvas".</canvas>

Mais le reste de la page reste le même, ce qui peut être inapproprié ou trompeur. Je voudrais un moyen de détecter le non support de la toile pour pouvoir présenter le reste de ma page en conséquence. Que recommanderais-tu?

136
brainjam

Ceci est la technique utilisée dans Modernizr et, fondamentalement, dans toutes les autres bibliothèques exécutant un travail sur toile:

function isCanvasSupported(){
  var elem = document.createElement('canvas');
  return !!(elem.getContext && elem.getContext('2d'));
}

Étant donné que votre question était destinée à être détectée lorsqu'elle est non prise en charge, je vous recommande de l'utiliser comme suit:

if (!isCanvasSupported()){ ...
211
Paul Irish

Il existe deux méthodes populaires de détection du support de canevas dans les navigateurs:

  1. Suggestion de Matt de vérifier l'existence de getContext, également utilisé de la même manière par la bibliothèque Modernizr: 

    var canvasSupported = !!document.createElement("canvas").getContext;
    
  2. Vérification de l'existence de l'interface HTMLCanvasElement, telle que définie par les spécifications WebIDL et HTML . Cette approche a également été recommandée dans un article de blog de l'équipe IE 9 .

    var canvasSupported = !!window.HTMLCanvasElement;
    

Ma recommandation est une variante de cette dernière (voir Notes complémentaires), pour plusieurs raisons:

  • Tous les navigateurs connus prenant en charge le canevas - y compris IE 9 - implémentent cette interface;
  • C'est plus concis et instantanément évident ce que le code fait;
  • L'approche getContext est considérablement plus lente dans tous les navigateurs , car elle implique la création d'un élément HTML. Ce n’est pas idéal lorsque vous devez exploiter le plus de performances possible (dans une bibliothèque telle que Modernizr, par exemple).

L'utilisation de la première méthode ne présente aucun avantage notable. Les deux approches peuvent être usurpées, mais il est peu probable que cela se produise par accident.

Notes complémentaires

Il peut encore être nécessaire de vérifier qu’un contexte 2D peut être récupéré. Il semblerait que certains navigateurs mobiles puissent renvoyer true pour les deux vérifications ci-dessus, mais renvoient null pour .getContext('2d'). C'est pourquoi Modernizr vérifie également le résultat de .getContext('2d'). Cependant, WebIDL & HTML - encore une fois - nous donne un autre meilleur, plus rapide option:

var canvas2DSupported = !!window.CanvasRenderingContext2D;

Notez que nous pouvons ignorer entièrement la vérification de l'élément de la toile et passer directement à la vérification du support du rendu 2D. L'interface CanvasRenderingContext2D fait également partie de la spécification HTML.

Vous devez utilisez l'approche getContextpour détecter la prise en charge de WebGL car, même si le navigateur prend en charge la WebGLRenderingContext, getContext() peut renvoyer null si le navigateur ne parvient pas à se connecter à la Le GPU est dû à des problèmes de pilote et il n’ya pas d’implémentation logicielle. Dans ce cas, la vérification préalable de l'interface vous permet d'ignorer la vérification de getContext:

var cvsEl, ctx;
if (!window.WebGLRenderingContext)
    window.location = "http://get.webgl.org";
else {
    cvsEl = document.createElement("canvas");
    ctx = cvsEl.getContext("webgl") || cvsEl.getContext("experimental-webgl");

    if (!ctx) {
        // Browser supports WebGL, but cannot create the context
    }
}

Comparaison de performance

Les performances de l'approche getContext sont 85 à 90% plus lentes dans Firefox 11 et Opera 11 et environ 55% plus lentes à Chrome 18.

 Simple comparison table, click to run a test in your browser

103
Andy E

Je lance habituellement un contrôle pour getContext lorsque je crée mon objet de travail.

(function () {
    var canvas = document.createElement('canvas'), context;
    if (!canvas.getContext) {
        // not supported
        return;
    }

    canvas.width = 800;
    canvas.height = 600;
    context = canvas.getContext('2d');
    document.body.appendChild(canvas);
}());

S'il est pris en charge, vous pouvez continuer la configuration de la toile et l'ajouter au DOM. Ceci est un exemple simple de amélioration progressive , que je préfère (personnellement) à la dégradation progressive.

13
Matt

Pourquoi ne pas essayer modernizr ? C'est une bibliothèque JS qui offre une capacité de détection.

Citation:

Avez-vous déjà eu envie de faire Si-déclarations dans votre CSS pour le disponibilité de fonctionnalités intéressantes comme border-radius? Eh bien, avec Modernizr vous pouvez accomplir cela!

6
Frozenskys
try {
    document.createElement("canvas").getContext("2d");
    alert("HTML5 Canvas is supported in your browser.");
} catch (e) {
    alert("HTML5 Canvas is not supported in your browser.");
}
5
Sheikh Ali

Il peut y avoir un piège ici - certains clients ne supportent pas les méthodes canvas all.

var hascanvas= (function(){
    var dc= document.createElement('canvas');
    if(!dc.getContext) return 0;
    var c= dc.getContext('2d');
    return typeof c.fillText== 'function'? 2: 1;
})();

alert(hascanvas)
2
kennebec

Vous pouvez utiliser canisuse.js script pour détecter si vos navigateurs prennent en charge le format de travail ou non. 

caniuse.canvas()
0
beka