您知道吗?带有ID的DOM元素可在JavaScript中作为全局变量访问?这是一个存在已久的功能,但我才第一次深入研究它。
如果您第一次听说这个功能,请做好准备!只需在HTML中向元素添加ID,我们就可以看到它在实际中的应用:
<div id="cool"></div>
通常,我们会使用querySelector("#cool")
或getElementById("cool")
定义一个新变量来选择该元素:
var el = querySelector("#cool");
但实际上,我们无需这些繁琐的操作就能访问#cool
:
因此,HTML中的任何ID(或name属性)都可以在JavaScript中使用window[ELEMENT_ID]
访问。再次强调,这并非“新”功能,但很少见。
正如您可能猜到的那样,使用命名引用访问全局作用域并非最佳方案。有些人称其为“全局作用域污染者”。我们将探讨原因,但首先……
一些背景
这种方法在HTML规范中有所描述,其中将其描述为“Window对象的命名访问”。
Internet Explorer是第一个实现此功能的浏览器。其他浏览器也添加了此功能。当时,Gecko是唯一一个不直接在标准模式下支持它的浏览器,而是选择将其作为实验性功能。人们对是否实现它犹豫不决,但为了浏览器的兼容性,它最终得以推进(Gecko甚至试图说服WebKit将其从标准模式中移除),并最终在Firefox 14中进入标准模式。
可能鲜为人知的一点是,浏览器不得不采取一些预防措施(成功程度各不相同),以确保生成的全局变量不会破坏网页。其中一项措施是……
变量遮蔽
此功能最有趣的部分可能是命名元素引用不会遮蔽现有的全局变量。因此,如果DOM元素的ID已定义为全局变量,它不会覆盖现有的变量。例如:
window.foo = "bar";
<div id="foo">I won't override window.foo</div>
console.log(window.foo); // 输出 "bar"
反之亦然:
<div id="foo">I will be overridden :(</div>
window.foo = "bar"; console.log(window.foo); // 输出 "bar"
此行为至关重要,因为它可以消除危险的覆盖,例如<div id="alert"></div>
,否则它会通过使alert API失效而造成冲突。这种保护技术很可能是您(如果您像我一样)第一次了解它的原因。
反对命名全局变量的论据
前面我说过,使用命名全局元素作为引用可能并非最佳方案。有很多原因,TJ VanToll在他的博客中对此进行了很好的阐述,我将在此处总结:
- 如果DOM发生更改,则引用也会更改。 这使得代码非常“脆弱”(规范中的术语),HTML和JavaScript之间的关注点分离可能过于严格。
- 意外引用过于容易。 一个简单的错字很可能会引用一个命名全局变量,并给您带来意想不到的结果。
-
在不同的浏览器中实现方式不同。 例如,我们应该能够访问具有ID的锚点(例如
<a><code><a></a>
),但某些浏览器(即Safari和Firefox)会在控制台中返回ReferenceError。 -
它可能不会返回您认为的结果。 根据规范,当DOM中存在多个相同命名元素的实例时(例如,两个
<div><code><div>实例),浏览器应该返回一个包含这些实例数组的HTMLCollection。但是,Firefox只返回第一个实例。再说一次,规范指出我们应该在元素树中使用一个ID实例。但是这样做不会阻止页面工作或任何类似的事情。 <li> <strong>可能有性能成本?</strong> 我的意思是,浏览器必须创建该引用列表并维护它。一些人在StackOverflow线程中运行了测试,其中命名全局变量在一个测试中实际上性能更高,而在最近的测试中性能较低。</li> <h3 id="其他注意事项">其他注意事项</h3> <p>假设我们抛弃了反对使用命名全局变量的批评,并继续使用它们。一切顺利。但是,在您这样做时,您可能需要考虑一些事情。</p> <h4 id="polyfills">polyfills</h4> <p>听起来可能很极端,但这些类型的全局检查是polyfills的典型设置要求。查看以下示例,我们使用新的CookieStore API设置cookie,在尚不支持它的浏览器中对其进行polyfill:</p> <pre class="brush:php;toolbar:false"><div id="cool"></div></pre> <p>这段代码在Chrome中运行良好,但在Safari中会抛出以下错误:</p> <pre class="brush:php;toolbar:false">var el = querySelector("#cool");</pre> <p>在撰写本文时,Safari不支持CookieStore API。因此,polyfill不会应用,因为img元素ID会创建一个与cookieStore全局变量冲突的全局变量。</p> <h4 id="JavaScript-API更新">JavaScript API更新</h4> <p>我们可以改变情况,找到另一个问题,即浏览器JavaScript引擎的更新可能会破坏命名元素的全局引用。</p> <p>例如:</p> <pre class="brush:php;toolbar:false">window.foo = "bar";</pre> <p>该脚本获取对输入元素的引用,并在其上调用focus()。它可以正常工作。但是,我们不知道它还能工作多久。</p> <p>您会看到,我们用来引用输入元素的全局变量一旦浏览器开始支持BarcodeDetector API就会停止工作。那时,window.BarcodeDetector全局变量将不再是输入元素的引用,而.focus()将抛出“window.BarcodeDetector.focus is not a function”错误。</p> <h3 id="结论">结论</h3> <p>让我们总结一下我们是如何走到这一步的:</p> <ul> <li>所有主要浏览器都会自动创建对每个具有id(或在某些情况下为name属性)的DOM元素的全局引用。</li> <li>通过其全局引用访问这些元素是不可靠的,并且可能很危险。请改用<code>querySelector
或getElementById
。 - 由于全局引用是自动生成的,它们可能会对您的代码产生一些副作用。这是一个避免使用id属性的好理由,除非您确实需要它。
最终,最好避免在JavaScript中使用命名全局变量。我前面引用了规范中关于它会导致“脆弱”代码的内容,但以下是完整的文本,以强调这一点:
一般来说,依赖于此会导致脆弱的代码。随着时间的推移,哪些ID最终映射到此API可能会发生变化,例如,随着新功能添加到Web平台。不要这样做,请使用
document.getElementById()
或document.querySelector()
。
我认为HTML规范本身建议避免使用此功能就说明了一切。
以上是命名元素ID可以称为JavaScript Globals的详细内容。更多信息请关注PHP中文网其他相关文章!

ThebestmethodforincludingCSSdependsonprojectsizeandcomplexity:1)Forlargerprojects,useexternalCSSforbettermaintainabilityandperformance.2)Forsmallerprojects,internalCSSissuitabletoavoidextraHTTPrequests.Alwaysconsidermaintainabilityandperformancewhenc

@keyframesandCSSTransitionsdifferincomplexity:@keyframesallowsfordetailedanimationsequences,whileCSSTransitionshandlesimplestatechanges.UseCSSTransitionsforhovereffectslikebuttoncolorchanges,and@keyframesforintricateanimationslikerotatingspinners.

我知道,我知道:有大量的内容管理系统选项可用,而我进行了几个测试,但实际上没有一个是一个,y&#039;知道吗?怪异的定价模型,艰难的自定义,有些甚至最终成为整个&

链接CSS文件到HTML可以通过在HTML的部分使用元素实现。1)使用标签链接本地CSS文件。2)多个CSS文件可通过添加多个标签实现。3)外部CSS文件使用绝对URL链接,如。4)确保正确使用文件路径和CSS文件加载顺序,优化性能可使用CSS预处理器合并文件。

选择Flexbox还是Grid取决于布局需求:1)Flexbox适用于一维布局,如导航栏;2)Grid适合二维布局,如杂志式布局。两者在项目中可结合使用,提升布局效果。

包含CSS文件的最佳方法是使用标签在HTML的部分引入外部CSS文件。1.使用标签引入外部CSS文件,如。2.对于小型调整,可以使用内联CSS,但应谨慎使用。3.大型项目可使用CSS预处理器如Sass或Less,通过@import导入其他CSS文件。4.为了性能,应合并CSS文件并使用CDN,同时使用工具如CSSNano进行压缩。

是的,youshouldlearnbothflexboxandgrid.1)flexboxisidealforone-demensional,flexiblelayoutslikenavigationmenus.2)gridexcelstcelsintwo-dimensional,confffferDesignssignssuchasmagagazineLayouts.3)blosebothenHancesSunHanceSlineHancesLayOutflexibilitibilitibilitibilitibilityAnderibilitibilityAndresponScormentilial anderingStruction


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

安全考试浏览器
Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

SublimeText3 英文版
推荐:为Win版本,支持代码提示!

MinGW - 适用于 Windows 的极简 GNU
这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

Dreamweaver CS6
视觉化网页开发工具