- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在项目中使用 Require.js。如果您正在定义一个模块,变量 define
将被添加到全局命名空间。
最近我有一个变量名冲突[但奇怪的是,只在 Safari 中],因为有一个 ID 为 define
的 HTML 标签,并且根据 HTML5 specification :
The Window interface supports named properties. The supported property names at any moment consist of the following:
- …
- …
- the value of the id content attribute of any HTML element in the active document with a non-empty id content attribute.
我认为用每个具有 ID 的 HTML 元素污染 JS 全局命名空间是一个糟糕的想法,但我的观点本身并不足以改变浏览器的行为方式。
在我的特定实例中,我找到了 this answer这将包装 Require.js;但从更一般的意义上讲:有没有办法在规范中防范这个细节?有没有一种技术可以防止这种 GNS 污染(没有明显的答案:“不要使用 ID”)?至少可以通过 JS 控制台让开发人员(可能不是我)明白冲突吗?
最佳答案
HTML5 的这种行为对 RequireJS 本身没有影响。我在 Firefox 和 Chrome 中运行了以下命令。正如预期的那样,全局空间中的 define
符号是 RequireJS 的 define 函数。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/xhtml; charset=utf-8"/>
</head>
<body>
<p id="define">Paragraph.</p>
<button id="redefine">Redefine</button>
<script type="text/javascript">
console.log("before requirejs:", typeof window.define);
</script>
<script type="text/javascript" src="js/require.js"></script>
<script>
require.config({
baseUrl: "./js",
paths: {
jquery: 'jquery-1.10.2'
},
});
console.log("requirejs loaded:", typeof window.define);
require(["jquery"], function ($) {
$("#redefine").click(function () {
$("#define").replaceWith("<p id='define'>New paragraph.</p>");
console.log("redefined:", typeof window.define);
require(["foo"], function (foo) {
console.log(foo);
});
});
});
</script>
</body>
</html>
我使用 typeof
来避免转储函数的整个源代码。对于我们的目的来说已经足够了。 “重新定义”按钮用于模拟对 DOM 树的更改,人们可能认为这会覆盖 window.define
的值。 (模块 foo
是一个简单的模块,它只返回值 "foo"
。)点击处理程序中的 require
表明 RequireJS 仍然是功能性的。使用上面的代码,控制台的输出显示:
即使最初 window.define
是 DOM 元素,RequireJS 也会将 define
重新定义为它自己的值。
一旦 RequireJS 定义了 define
,对 DOM 树的更改不会改变它。
因此 RequireJS 不需要对其进行保护。
但是坚持使用 window.define
访问 id 为“define”的元素的代码呢?这样的代码有缺陷,应该修复。这个所以question很好地涵盖了这个问题。即使 RequireJS 是为了避免接触全局 define
,依赖 window.define
作为 DOM 元素的代码仍然很脆弱。
Is there a technique for preventing this GNS pollution (without the obvious answer: “Don’t use IDs”)?
除了显而易见的答案,没有。 (我认为“使用 ID 以外的东西”等同于“不使用 ID”。)
Could the conflict at least be made obvious to the developer (which might not be me), through the JS console?
JS 虚拟机可能会检测到冲突,但我不知道有任何虚拟机会这样做。
这是 Safari 在 JavaScript 中处理全局变量的方式中的一个错误。没有其他浏览器的行为像 Safari 那样。
This repository包含一组说明问题的文件。如果在 Safari 中加载,index.html
文件将在控制台上显示失败。它在 Firefox、Chrome、IE 和 Opera 中加载良好。 test.html
文件指出了问题所在。除 Safari 之外的所有浏览器都将 JavaScript 中的变量声明(如 var foo
)在顶级范围内视为隐藏由于具有 id
的元素而创建的任何同名变量属性集。在除 Safari 之外的任何浏览器中加载,输出 start of redefine:
的 console.log
将显示 undefined undefined
变量的值。在 Safari 中,它显示 p#define p#define
。
一个问题 has been filed使用 RequireJS 来建议一个可以处理这种情况的更改。
如果建议的更改没有通过,则解决方法是在加载 RequireJS 之前执行 define = undefined
。无需再做任何事情。
关于javascript - 防范 JS 全局命名空间中的 HTML ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21362298/
我正在使用 MongoDB作为我的数据库,并且作为新手后端开发人员,删除整个数据库/集合的轻松程度确实困扰着我。 只需输入 db.collection.remove()从该集合中删除所有记录! 我知道
我在项目中使用 Require.js。如果您正在定义一个模块,变量 define 将被添加到全局命名空间。 最近我有一个变量名冲突[但奇怪的是,只在 Safari 中],因为有一个 ID 为 defi
我是一名优秀的程序员,十分优秀!