141 votes

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

La manière standard de traiter les situations où le navigateur ne prend pas en charge le code HTML5. <canvas> est d'incorporer un contenu de remplacement, par exemple :

<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. J'aimerais pouvoir détecter la non-prise en charge de la toile afin de présenter le reste de ma page en conséquence. Que me conseillez-vous ?

218voto

Paul Irish Points 17507

C'est la technique utilisée par Modernizr et par toutes les autres bibliothèques qui travaillent avec des canevas :

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

Puisque votre question était pour la détection quand c'est no soutenu, je recommande de l'utiliser comme ça :

if (!isCanvasSupported()){ ...

15 votes

A quoi sert la double négation ( !!)?

16 votes

Si Canvas n'est pas là, elem.getContext == undefined . !undefined = true y !true = false Cela nous permet donc de retourner un bool, plutôt qu'undefined ou le contexte.

1 votes

@2astalavista La double négation ( !!) est comme le casting. Elle transforme une déclaration vraie ou fausse en un booléen. Par exemple : var i = 0 . i est évalué à false, mais typeof i renvoie "nombre". typeof !!i renvoie "booléen".

104voto

Andy E Points 132925

Il existe deux méthodes populaires pour détecter la prise en charge des canevas dans les navigateurs :

  1. La suggestion de Matt de vérifier l'existence de getContext qui est également utilisé de manière similaire par la bibliothèque Modernizr :

    var canvasSupported = !!document.createElement("canvas").getContext;
  2. Vérifier l'existence de la HTMLCanvasElement tel que défini par l'interface WebIDL y HTML Cette approche a également été recommandée dans un billet de blog de l'équipe IE 9 .

    var canvasSupported = !!window.HTMLCanvasElement;

Je recommande une variante de cette dernière (cf. Notes supplémentaires ), pour plusieurs raisons :

  • Tous les navigateurs connus supportant le canvas, y compris IE 9, implémentent cette interface ;
  • C'est plus concis et on voit tout de suite ce que fait le code ;
  • El getContext l'approche est sensiblement plus lent sur tous les navigateurs Ce n'est pas l'idéal lorsqu'il s'agit de réduire au maximum les performances (dans une bibliothèque comme Modernizr, par exemple).

La première méthode ne présente pas d'avantages notables. Les deux approches peuvent être détournées, mais cela ne risque pas d'arriver par accident.

Notes supplé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 retourner null para .getContext('2d') C'est pourquoi Modernizr vérifie également le résultat de l'opération suivante .getContext('2d') . Cependant, WebIDL & HTML nous offre encore une fois une meilleure solution, plus rapide option :

var canvas2DSupported = !!window.CanvasRenderingContext2D;

Remarquez que nous pouvons ignorer complètement la vérification de l'élément canvas et passer directement à la vérification de la prise en charge du rendu 2D. Le site CanvasRenderingContext2D fait également partie de la spécification HTML.

Vous doit utiliser le getContext approche pour détecter WebGL car, même si le navigateur prend en charge l'option WebGLRenderingContext , getContext() peut revenir null si le navigateur est incapable de s'interfacer avec le GPU en raison de problèmes de pilote et qu'il n'y a pas d'implémentation logicielle. Dans ce cas, la vérification de l'interface en premier lieu vous permet de ne pas vérifier la présence 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 des performances Performances du getContext L'approche est 85-90% plus lente dans Firefox 11 et Opera 11 et environ 55% plus lente dans Chromium 18.

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

10 votes

Le Nokia S60 et le Blackberry Storm font partie des appareils qui donneront de faux positifs à vos détections de canevas 2D proposées. Malheureusement, les mobiles deviennent très difficiles et les fournisseurs ne suivent pas les règles :( Nous nous retrouvons donc avec des tests plus complets (c'est-à-dire plus lents) pour garantir des résultats précis.

0 votes

@Paul : c'est intéressant, j'ai testé les émulateurs de BlackBerry Storm, ils ont tous renvoyés false pour votre exemple comme pour le mien, il semble qu'ils ne fournissent pas la CanvasRenderingContext2D l'interface. Je n'ai pas pu tester le S60 pour l'instant, mais je suis toujours très curieux et je le ferai peut-être bientôt.

1 votes

C'est intéressant, mais tant que le test est inférieur à une centaine de millis, n'est-ce pas parfait ? J'imagine qu'ils sont tous beaucoup plus rapides que ça de toute façon. Si vous mémorisez une fonction qui teste cela, vous ne devez payer le coût qu'une seule fois.

13voto

Matt Points 21690

J'ai l'habitude de faire une vérification pour getContext lorsque je crée mon objet canevas.

(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 supporté, alors vous pouvez continuer la configuration du canevas et l'ajouter au DOM. Voici un exemple simple de Amélioration progressive que je préfère (personnellement) à la dégradation gracieuse.

0 votes

Est-ce que c'est un vagabond , context sur la deuxième ligne ?

7 votes

@brainjam - Non, j'utilise cette variable vers la fin du code. J'essaie de suivre le JSLint des "recommandations" (dans ce cas seulement 1 var par fonction).

6voto

Frozenskys Points 2203

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

Citation :

Avez-vous déjà voulu faire des déclarations if dans votre CSS pour la disponibilité de fonctionnalités cool comme border-radius ? Eh bien, avec Modernizr vous pouvez faire exactement cela !

2 votes

Le test que nous utilisons dans modernizr est le suivant : return !!document.createElement('canvas').getContext C'est certainement la meilleure façon de tester.

4 votes

Modernizr est une bibliothèque utile, mais ce serait un peu du gaspillage de faire appel à toute la bibliothèque juste pour détecter le support des canevas. Si vous avez besoin de détecter d'autres fonctionnalités, je vous le recommande.

5voto

Sheikh Ali Points 426
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.");
}

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