gpt4 book ai didi

javascript - 防范 JS 全局命名空间中的 HTML ID

转载 作者:行者123 更新时间:2023-11-29 15:39:45 27 4
gpt4 key购买 nike

我在项目中使用 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 仍然是功能性的。使用上面的代码,控制台的输出显示:

  1. 即使最初 window.define 是 DOM 元素,RequireJS 也会将 define 重新定义为它自己的值。

  2. 一旦 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 呢?

这是 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/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com