Comment éviter les conflits de noms dans les widgets JavaScript

J'ai un widget JavaScript (un morceau de code JS et HTML intégré) intégré dans d'autres sites. Que dois-je faire pour m'assurer que les noms de variables ne se heurtent pas aux variables de la page d'hébergement?

J'aimerais que ce widget soit «inline» sur la même page que la page d'hébergement, pas dans un iframe, quelle est la meilleure façon d'éviter les conflits de noms avec la page d'hébergement ou d'affronter d'autres widgets?

Les affrontements de noms peuvent survenir de plusieurs façons:

  • Nom des variables JavaScript
  • Nom des fonctions JavaScript
  • Identificateurs d'éléments DOM
  • Nom de classe CSS
  • peut-être plus…

Je peux penser à plusieurs façons d'éviter les conflits de noms, mais je me demandais s'il y avait une meilleure pratique ou d'autres recommandations générales. Alors voici mon 2c:

  1. Utilisez simplement des noms longs et tenter d'être exclusifs. C'est moche et pas plein de preuve, mais est simple dans le concept.
  2. Utilisez un iframe. Mais comme mentionné, je ne veux pas utiliser un iframe pour plusieurs raisons. Je veux que le widget hérite des attributs de style de la page (par exemple, la police par défaut et la couleur d'arrière-plan) et, surtout, je ne sais pas à quel point le widget va être important. Cela dépend des données en temps réel et peut être de toute taille.
  3. Utilisez des fonctions anonymes pour une meilleure portée, p.ex. (function () {mon code ici}) (). Cette solution, tout en élégant, ne fonctionne toujours pas pour moi b / c d'abord, elle ne résout que le nom de JS entré en conflit, mais pas les ID de DOM ou les noms de classe CSS et deuxièmement, j'utilise également jsonp pour lequel je dois fournir une fonction de rappel Nom, qui doit finalement être dans la portée globale, donc il ne peut pas être imbriqué dans la portée de la fonction anonyme.
  4. Créez un mécanisme d'espace de noms en JavaScript qui fournira l'unicité des variables JS et de la fonction. Quelque chose de la fenêtre de style ['my_app'] [nom_fichier] ou fenêtre ['my_app'] nom_fichier. C'est un peu moche aussi, mais au moins j'ai le contrôle de l'espace de noms et je peux créer des espaces de noms uniques garantis.

Namespaces Javascript:

http://www.codeproject.com/KB/scripting/jsnamespaces.aspx

Il est fortement utilisé dans plusieurs frameworks / bibliothèques javascript, tels que YUI: http://developer.yahoo.com/yui/yahoo/

Dans mon projet précédent, j'avais un widget intégré sur d'autres sites et pour empêcher les conflits de noms, j'ai préfixé tous les noms qui seraient utilisés dans les sites d'intégration avec un préfixe à deux lettres (j'ai eu l'idée de Objective C, où toutes les classes commencent Avec un préfixe comme NS …).

Bien sûr, j'ai également utilisé des espaces de noms (p. Ex., Var Foo = {bar: function () {…}}) et "classes" (en utilisant l'implémentation de classe de John Resig), car je les utilise indépendamment de moi si j'ai un widget ou pas, mais Les noms des espaces de noms, des classes et des variables ou fonctions globales ont été préfixés – par ex. HMWidget, HMClass, hmDoSomething (), etc.

En ce qui concerne les ID de DOM et les classes CSS – d'abord, j'ai dû me débarrasser de la plupart des ID en raison de la possibilité d'avoir plusieurs widgets de mon service sur le même site. Donc, les seuls identifiants laissés étaient quelque chose comme "widget_12345" pour distinguer les widgets. Le reste des éléments ont été identifiés par des classes CSS et toutes les déclarations CSS ont été effectuées par rapport au conteneur de widget principal (par exemple, ".my_widget .left_column" au lieu de simplement ".left_column").