Maison >interface Web >js tutoriel >Lorsque la détection des fonctionnalités JavaScript échoue

Lorsque la détection des fonctionnalités JavaScript échoue

尊渡假赌尊渡假赌尊渡假赌
尊渡假赌尊渡假赌尊渡假赌original
2025-02-22 09:57:12809parcourir

When JavaScript Feature Detection Fails

Points clés

  • La détection des fonctionnalités JavaScript (les fonctionnalités de test que les programmeurs souhaitent utiliser) n'est pas toujours fiable. Par exemple, testez ActiveXObject dans Internet Explorer pour les demandes AJAX, les attributs HTML mappés aux propriétés DOM, les hypothèses sur le comportement de l'utilisateur (comme la détection des appareils tactiles), etc.
  • Lorsque la détection des fonctionnalités échoue, la détection du navigateur est parfois requise. Cependant, il est recommandé d'utiliser des tests d'objets propriétaires au lieu des informations de navigateur et de les utiliser pour exclure les navigateurs plutôt que de les inclure.
  • Soyez extrêmement prudent lors de la mise en œuvre de la détection du navigateur. Supposons toujours qu'il est entièrement cohérent avec les tests de fonctionnalités et ne recherchez pas la détection du navigateur que si vous savez qu'une fonctionnalité ne fonctionne pas comme prévu. De plus, la syntaxe utilisée pour les tests d'objets et de fonctionnalités peut affecter le taux de réussite de détection, donc le choix de la bonne syntaxe est crucial.

Il était une fois, la détection du navigateur était la meilleure compétence des programmeurs JavaScript. Si nous savons que certaines fonctionnalités fonctionnent dans IE5 mais pas dans Netscape 4, nous testerons le navigateur et modifierons le code en conséquence. Par exemple:

<code class="language-javascript">if (navigator.userAgent.indexOf('MSIE 5') != -1) {
  // 我们认为此浏览器是 IE5
}</code>

Mais quand j'ai rejoint l'industrie pour la première fois, la course aux armements avait déjà commencé! Les fournisseurs ajoutent des valeurs supplémentaires aux chaînes d'agent utilisateur, ils ressemblent donc aux navigateurs de leurs concurrents et aux leurs. Par exemple, c'est Safari 5 pour Mac:

<code>Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/534.59.10 (KHTML, like Gecko) Version/5.1.9 Safari/534.59.10</code>

Cela correspondra aux tests pour "safari", "webkit" et "khtml" (la base de code Konqueror que WebKit est basée) mais il correspond également à "Gecko" (qui est le moteur de rendu de Firefox), et bien sûr " Mozilla "" (pour des raisons historiques, presque tous les navigateurs prétendent être Mozilla).

Le but d'ajouter toutes ces valeurs est de contourner la détection du navigateur. Si le script suppose que seul Firefox peut gérer des fonctionnalités spécifiques, Safari peut être exclu, même si elle peut fonctionner. N'oubliez pas que les utilisateurs peuvent modifier eux-mêmes leur agent utilisateur - j'avais l'habitude de définir mon navigateur pour reconnaître "Googlebot / 1.0" afin que je puisse accéder à ce que le propriétaire du site pense être pour ramper uniquement!

Ainsi, au fil du temps, ce type de détection du navigateur est devenu un gâchis impossible et est largement hors d'usage, remplacé par quelque chose de mieux: la détection de la fonction.

La détection des fonctionnalités est simplement de tester les fonctionnalités que nous souhaitons utiliser. Par exemple, si nous avons besoin de getBoundingClientRect (obtenez la position d'un élément par rapport à la fenêtre), il est important de savoir si le navigateur le prend en charge, et non quel navigateur est donc; Pire que la fonction de test elle-même:

<code class="language-javascript">if (typeof document.documentElement.getBoundingClientRect != "undefined") {
  // 浏览器支持此函数
}</code>
Les navigateurs qui ne prennent pas en charge cette fonction renverront le type "non défini", de sorte que la condition ne sera pas transmise. Sans tester le script dans un navigateur particulier, nous savons qu'il fonctionne correctement ou échoue silencieusement.

ou nous…?

Mais la vérité est - la détection des fonctionnalités n'est pas entièrement fiable - parfois elle échoue. Voyons donc quelques exemples maintenant et voyons ce que nous pouvons faire pour résoudre chaque cas.

Objet ActiveX

Peut-être que l'exemple le plus célèbre de défaillance de détection des fonctionnalités est de tester ActiveXObject pour les demandes AJAX dans Internet Explorer.

ActiveX est un exemple d'objets en retard, et la signification pratique est que vous ne pouvez pas savoir s'il est pris en charge jusqu'à ce que vous essayiez de l'utiliser . Par conséquent, si l'utilisateur désactive ActiveX, le code suivant lancera une erreur:

<code class="language-javascript">if (navigator.userAgent.indexOf('MSIE 5') != -1) {
  // 我们认为此浏览器是 IE5
}</code>
Pour résoudre ce problème, nous devons utiliser la manipulation des exceptions -

essayez Instancier l'objet, Catch toute échec et le gérer en conséquence:

<code>Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/534.59.10 (KHTML, like Gecko) Version/5.1.9 Safari/534.59.10</code>
Attribut html mappé à l'attribut DOM

Le mappage d'attributs est souvent utilisé pour tester le support des API utilisés avec les propriétés HTML5. Par exemple, vérifiez si un élément avec

prend en charge l'API Draggable en recherchant des propriétés draggables: [draggable="true"]

<code class="language-javascript">if (typeof document.documentElement.getBoundingClientRect != "undefined") {
  // 浏览器支持此函数
}</code>
Le problème ici est que IE8 ou antérieure mappera automatiquement toutes les propriétés HTML

HTML aux propriétés DOM. C'est pourquoi est si déroutant dans ces anciennes versions, car elle ne renvoie pas du tout les propriétés, mais les propriétés DOM. getAttribute Cela signifie que si nous utilisons un élément qui a déjà l'attribut

:

Ensuite, même s'ils ne sont pas pris en charge, IE8 ou précédent retournera

pour
<code class="language-javascript">if (typeof window.ActiveXObject != "undefined") {
  var request = new ActiveXObject("Microsoft.XMLHTTP");
}</code>
.

true L'attribut peut être n'importe quoi: ("draggable" in element)

mais le résultat sera le même - IE8 ou précédent retournera

pour
<code class="language-javascript">if (typeof window.ActiveXObject != "undefined") {
  try {
    var request = new ActiveXObject("Microsoft.XMLHTTP");
  } catch (ex) {
    request = null;
  }
  if (request !== null) {
    //... 我们有一个请求对象
  }
}</code>
.

true Dans ce cas, la solution consiste à utiliser un élément qui n'a pas cet attribut pour les tests, le moyen le plus sûr est d'utiliser l'élément créé: ("nonsense" in element)

Hypothèses sur le comportement des utilisateurs

<code class="language-javascript">if ("draggable" in element) {
  // 浏览器支持拖放
}</code>
Vous avez peut-être vu utiliser le code suivant pour détecter les appareils tactiles:

La plupart des périphériques tactiles implémentent les retards manuels avant de déclencher un événement de clic (généralement environ 300 millisecondes), c'est-à-dire pour éviter de cliquer sur les éléments tout en cliquant. Mais cela fait que l'application se sent lente et insensible, donc les développeurs utilisent parfois ce test de fonctionnalité pour débarquer l'événement:

<code class="language-html"><div draggable="true"> ... </div></code>

Cependant, cette condition provient d'une erreur

du
<code class="language-html"><div nonsense="true"> ... </div></code>
- Parce que l'appareil prend en charge le toucher, le toucher sera utilisé. Mais qu'en est-il des ordinateurs portables à écran tactile? L'utilisateur peut toucher l'écran ou utiliser une souris ou un trackpad;

Dans ce cas, la solution n'est pas du tout de la prise en charge des événements - liez plutôt deux événements

en même temps, puis utilisez

pour empêcher le contact de générer des clics:

<code class="language-javascript">if (navigator.userAgent.indexOf('MSIE 5') != -1) {
  // 我们认为此浏览器是 IE5
}</code>

des choses qui ne fonctionnent pas du tout

reconnaître cela est douloureux, mais parfois ce que nous n'avons pas besoin de tester n'est pas la fonctionnalité - mais le navigateur - parce qu'un navigateur particulier prétend soutenir quelque chose qui ne fonctionne pas. Un exemple récent est setDragImage() dans Opera 12 (qui est un moyen de faire glisser et déposer dataTransfer objets).

Le test des fonctionnalités échoue ici parce que Opera 12 prétend le soutenir; Cela ne fonctionne tout simplement pas:

<code>Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/534.59.10 (KHTML, like Gecko) Version/5.1.9 Safari/534.59.10</code>

Maintenant, si vous voulez juste essayer pour ajouter une image de glisser personnalisée et que vous êtes heureux de conserver la valeur par défaut sans support (ce qui se produira), alors cela peut être bien. Mais que se passe-t-il si votre application a besoin d'images personnalisées afin que les navigateurs qui ne le prennent pas en charge devraient utiliser une implémentation complètement différente (c'est-à-dire utiliser JavaScript personnalisé pour implémenter tout comportement de glisser)? ou si le navigateur implémente certaines fonctionnalités mais qu'il y a des erreurs de rendu inévitables? Parfois, nous n'avons pas d'autre choix que de détecter explicitement le navigateur problématique et de l'exclure des fonctionnalités qu'il aurait essayé de prendre en charge l'utilisation.

Donc, le problème devient - quel est le moyen le plus sûr d'atteindre la détection du navigateur?

J'ai deux suggestions:

préfèrent les tests d'objets propriétaires sur les informations de navigateur.
  1. Utilisez-le pour exclure les navigateurs plutôt que de les inclure.
  2. Par exemple, vous pouvez utiliser
OBJET DE DÉTECTION D'OBJET 12 ou plus tôt, afin que nous puissions utiliser cette exclusion pour tester la prise en charge dragable:

window.opera

Il est préférable d'utiliser des objets propriétaires au lieu d'objets standard, car lorsqu'un nouveau navigateur est libéré, il est peu probable que les résultats des tests changent. Voici quelques-uns de mes exemples préférés:
<code class="language-javascript">if (typeof document.documentElement.getBoundingClientRect != "undefined") {
  // 浏览器支持此函数
}</code>

Les tests d'objets peuvent également être utilisés en conjonction avec les tests de fonctionnalité
<code class="language-javascript">if (typeof window.ActiveXObject != "undefined") {
  var request = new ActiveXObject("Microsoft.XMLHTTP");
}</code>
pour déterminer la prise en charge de fonctionnalités spécifiques dans un navigateur spécifique, ou en cas d'urgence, définissez des conditions de navigateur plus précises:

Nous avons remarqué que les chaînes d'agent utilisateur sont un gâchis peu fiable, mais les chaînes de fournisseurs sont en fait assez prévisibles et peuvent être utilisées pour tester de manière fiable Chrome ou Safari:

<code class="language-javascript">if (typeof window.ActiveXObject != "undefined") {
  try {
    var request = new ActiveXObject("Microsoft.XMLHTTP");
  } catch (ex) {
    request = null;
  }
  if (request !== null) {
    //... 我们有一个请求对象
  }
}</code>

La règle d'or pour tout cela est extrêmement prudent. Assurez-vous de tester les conditions dans autant de navigateurs que possible et de considérer attentivement leur

compatibilité vers l'avant
<code class="language-javascript">if ("draggable" in element) {
  // 浏览器支持拖放
}</code>
- L'objectif est d'utiliser des conditions de navigateur pour exclure les navigateurs

car il y a déjà des erreurs connues, ne les incluez pas à cause de fonctionnalités connues (c'est le but du test des fonctionnalités) Fondamentalement, supposons toujours que le test des fonctionnalités est entièrement conforme à - à moins que vous ne sachiez que ce n'est pas le cas, alors la fonction fonctionnera comme prévu. Sélectionnez Test Syntaxe

Avant de terminer, je souhaite consulter les différents types de syntaxe que nous pouvons utiliser pour les tests d'objets et de propriétés. Par exemple, ces dernières années, la syntaxe suivante est devenue courante:

<code class="language-javascript">if (navigator.userAgent.indexOf('MSIE 5') != -1) {
  // 我们认为此浏览器是 IE5
}</code>

Nous n'avons pas pu l'utiliser dans le passé car IE5 et ses produits similaires jettent des erreurs en raison de la syntaxe; mais maintenant nous n'avons plus à soutenir ces navigateurs, ce qui n'est plus un problème.

Essentiellement, c'est exactement la même chose que les suivants, mais c'est plus court à écrire:

<code>Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/534.59.10 (KHTML, like Gecko) Version/5.1.9 Safari/534.59.10</code>

Cependant, les conditions de test reposent généralement sur la conversion de type automatique:

<code class="language-javascript">if (typeof document.documentElement.getBoundingClientRect != "undefined") {
  // 浏览器支持此函数
}</code>

Nous avons utilisé cette syntaxe plus tôt dans certains tests d'objets de navigateur (par exemple window.opera tests), qui est sûr en raison de la façon dont les objets évaluent - tout objet ou fonction défini sera toujours évalué comme vrai, et s'il n'est pas défini, il sera être évalué comme faux.

Mais nous pouvons tester quelque chose qui renvoie efficacement les chaînes nulles ou vides, qui évaluent toutes deux en false. Par exemple, l'attribut style.maxWidth est parfois utilisé pour exclure IE6:

<code class="language-javascript">if (typeof window.ActiveXObject != "undefined") {
  var request = new ActiveXObject("Microsoft.XMLHTTP");
}</code>

Il n'évaluera que si l'attribut maxWidth est pris en charge et que le a la valeur définie par l'auteur, donc si nous écrivons le test comme celui-ci, il peut échouer:

<code class="language-javascript">if (typeof window.ActiveXObject != "undefined") {
  try {
    var request = new ActiveXObject("Microsoft.XMLHTTP");
  } catch (ex) {
    request = null;
  }
  if (request !== null) {
    //... 我们有一个请求对象
  }
}</code>

La règle générale est la suivante: s'appuyer sur la conversion de type automatique est sans danger pour les objets et les fonctions, mais pas nécessairement sans danger pour les chaînes et les nombres ou les valeurs qui peuvent être nuls.

Cela étant dit - si vous pouvez l'utiliser en toute sécurité, faites-le parce qu'il est généralement beaucoup plus rapide dans les navigateurs modernes (probablement parce qu'ils sont optimisés pour ce type de condition).

Pour plus d'informations à ce sujet, voir: Conversion de type automatique dans le monde réel.

Des questions fréquemment posées sur la détection des fonctionnalités JavaScript

Qu'est-ce que la détection des fonctionnalités JavaScript et pourquoi est-elle importante?

La détection des fonctionnalités JavaScript est une technologie utilisée par les développeurs pour déterminer si le navigateur d'un utilisateur prend en charge une fonctionnalité ou une API spécifique. Ceci est crucial car tous les navigateurs ne prennent pas en charge toutes les fonctionnalités de JavaScript. En utilisant la détection des fonctionnalités, les développeurs peuvent fournir des solutions ou des replies alternatives pour les fonctionnalités non pris en charge, garantissant que les sites Web ou les applications s'exécutent correctement sur différents navigateurs. Cela améliore l'expérience utilisateur et garantit la compatibilité.

Comment la détection des fonctionnalités JavaScript échoue-t-elle?

La détection des fonctionnalités JavaScript peut échouer pour un certain nombre de raisons. Une raison courante est que le code de détection des fonctionnalités est incorrectement implémenté. Par exemple, si le code vérifie les propriétés qui n'existent pas dans l'objet, il renverra indéfini, ce qui entraînera un faux négatif. Une autre raison pourrait être une bizarrerie ou une erreur de navigateur, ce qui pourrait entraîner la détection des fonctionnalités pour donner des résultats inexacts.

Quelle est la différence entre la détection des fonctionnalités et la détection du navigateur?

La détection des fonctionnalités consiste à vérifier si le navigateur d'un utilisateur prend en charge une fonctionnalité ou une API spécifique, tandis que la détection du navigateur reconnaît le navigateur et la version de l'utilisateur. Bien que les deux techniques soient conçues pour garantir la compatibilité et les fonctionnalités, la détection des fonctionnalités est souvent considérée comme une meilleure pratique car elle vérifie directement les fonctionnalités, plutôt que de supposer sa prise en charge en fonction du type ou de la version du navigateur.

Comment utiliser JavaScript pour détecter les appareils mobiles?

Vous pouvez utiliser l'attribut navigator.userAgent dans JavaScript pour détecter les appareils mobiles. Cette propriété renvoie une chaîne représentant l'en-tête de l'agent utilisateur du navigateur. En vérifiant des mots clés spécifiques dans cette chaîne (tels que "Android", "iPhone" ou "iPad"), vous pouvez déterminer si l'utilisateur est sur un appareil mobile.

Qu'est-ce que la fonctionnalité.js et comment cela aide-t-il à la détection des fonctionnalités?

Fonction.js est un utilitaire JavaScript léger, rapide et simple pour la détection des fonctionnalités. Il fournit une API facile à utiliser qui permet aux développeurs de tester si le navigateur prend en charge des fonctionnalités spécifiques. Cela permet de fournir une solution de sauvegarde ou une solution alternative pour les fonctionnalités non étayées, améliorant ainsi la compatibilité et la fonctionnalité du site Web ou de l'application.

Qu'est-ce que Modernizr et comment cela aide-t-il à la détection des fonctionnalités?

Modernizr est une bibliothèque JavaScript qui aide les développeurs à profiter des fonctionnalités HTML5 et CSS3 tout en maintenant la compatibilité avec les navigateurs plus anciens. Il utilise la détection des fonctionnalités pour vérifier si le navigateur prend en charge des fonctionnalités spécifiques et ajoute des classes aux éléments HTML, vous permettant de localiser des fonctionnalités de navigateur spécifiques dans Styleshets ou JavaScript.

Comment utiliser le package de périphérique-détecteur-js pour la détection des fonctionnalités?

Le package

Device-Detector-JS est un outil puissant pour la détection des périphériques. Il analyse les chaînes d'agent utilisateur et détecte les smartphones, tablettes, ordinateurs de bureau, téléviseurs et autres appareils. Il détecte également les navigateurs, les moteurs, les systèmes d'exploitation et d'autres informations utiles. Vous pouvez utiliser ce package pour ajuster le comportement d'un site Web ou d'une application en fonction des appareils détectés.

Quelles sont les meilleures pratiques pour implémenter la détection des fonctionnalités?

Certaines meilleures pratiques pour implémenter la détection des fonctionnalités incluent: l'utilisation de bibliothèques fiables et testées telles que Modernizr ou fonctionnalités. Basé sur le type ou la version du navigateur.

La détection des comptes peut-elle aider à améliorer les performances du site Web?

Oui, la détection des fonctionnalités peut aider à améliorer les performances du site Web. En détectant des fonctionnalités non soutenues et en fournissant des solutions alternatives ou des solutions de secours, vous pouvez empêcher le code inutile de fonctionner dans le navigateur. Cela réduit le temps de chargement et améliore les performances globales du site Web.

Comment comprendre les dernières fonctionnalités prises en charge par différents navigateurs?

En raison du développement rapide du développement Web, il peut être difficile de comprendre les dernières fonctionnalités prises en charge par différents navigateurs. Cependant, des ressources telles que Mozilla Developer Network (MDN), puis-je utiliser, et la documentation JavaScript peut fournir les dernières informations sur la prise en charge des fonctionnalités dans différents navigateurs.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn