网站搜索

html - 如何在 JavaScript 小部件中避免名称冲突


我有一个 JavaScript 小部件(一段嵌入的 JS 和 HTML 代码),它被嵌入到其他网站上。我应该怎么做才能确保它的变量名不会与宿主页面的变量冲突?

我希望这个小部件是“内联”的,意思是在与承载页面相同的页面上,不是在iframe中,避免与承载页面或其他小部件发生名称冲突的最佳方法是什么?

名称冲突可以通过几种方式发生:

  • JavaScript 变量名
  • JavaScript 函数名称
  • DOM 元素标识符
  • CSS 类名
  • 也许更多...

我能想到几种避免命名冲突的方法,但我想知道是否有最佳实践或其他一般建议。所以这是我的一点看法:

  1. 只要使用长且尽量独特的名字。这很难看,也不是万无一失,但概念上很简单。
  2. 使用 iframe。但如前所述,我不想使用 iframe,有几个原因。我希望小部件能够继承页面的样式属性(例如默认字体和背景颜色),最重要的是,我不知道小部件的大小会是多少。它取决于实时数据,可能有任何大小。
  3. 使用匿名函数以获得更好的作用域,例如 (function(){my code here})()。这个解决方案虽然很优雅,但对我来说仍然不可行,因为首先,它只解决了 JS 名称冲突的问题,而不能解决 DOM ID 或 CSS 类名的冲突;其次,我还使用了 jsonp,这需要我提供一个回调函数名,而这个函数名最终需要在全局作用域中,因此不能嵌套在匿名函数的作用域中。
  4. 在 JavaScript 中创建一个命名空间机制,它可以提供 JS 变量和函数的唯一性。类似于 window['my_app'][variable_name] 或 window['my_app']function_name 的风格。这有点丑,但至少我可以控制命名空间,并且可以生成保证唯一的命名空间。

答案#1

Javascript 命名空间:

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

它在几个 JavaScript 框架/库中被广泛使用,例如 YUI:http://developer.yahoo.com/yui/yahoo/

答案#2

在我之前的项目中,我有一个小部件被嵌入在其他网站上,为了防止名称冲突,我给所有将在嵌入网站中使用的名称加了两个字母的前缀(我这个想法来自 Objective C,在那里所有类的名称都以像 NS 这样的前缀开头……)。

当然,我也使用了命名空间(例如 var Foo={ bar: function() { ... } })和“类”(使用 John Resig 的类实现),因为无论是否有小部件我都会使用它们,但命名空间、类以及全局变量或函数的名称都有前缀——例如 HMWidget、HMClass、hmDoSomething() 等。

关于 DOM ID 和 CSS 类——首先,我不得不去掉大多数 ID,因为同一网站上可能会出现来自我服务的多个小部件。所以剩下的唯一 ID 是类似于“widget_12345”这样的,用来区分不同的小部件。其他元素都是通过 CSS 类来标识的,所有 CSS 声明都是相对于主小部件容器进行的(例如“.my_widget .left_column”而不是单独使用“.left_column”)。