千家信息网

QWrap选择器tagName的大小写问题怎么解决

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这篇文章主要讲解了"QWrap选择器tagName的大小写问题怎么解决",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"QWrap选择器tagName的大
千家信息网最后更新 2026年11月02日QWrap选择器tagName的大小写问题怎么解决

这篇文章主要讲解了"QWrap选择器tagName的大小写问题怎么解决",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"QWrap选择器tagName的大小写问题怎么解决"吧!

对于现代Web前端来说,Selector是必备之物。对于标准浏览器,可用querySelector,而对于IE8标准模式以下,需要一个Selector引擎。

因为本项目会在代码里使用QWrap,所以虽然我写的部分代码并没有用QWrap,但既然怎样都需要一个Selector引擎,不如用QWrap。

结果发生一件悲剧的事情。

我使用html5-shim/shiv库来让IE正确解析新的HTML5标签。但是QWrap引擎居然不能正确选择出html5的元素。

尝试人肉选择,发现是可以的,那就是QWrap的Selector存在bug。

经过艰苦卓绝的斗争,最终发现问题出在这个函数的第2行:

function(a) {       sFun.push('el.tagName=="' + a.toUpperCase() + '"');      return '';  }).replace(/([\[(].*)|#([\w\-]+)|\.([\w\-]+)/g,//id缩略写法//className缩略写法

QWrap采用了代码生成技术,即为selector拼装出对应的函数。这是一项相当陷阱先进的技术。

不难看出这里会产生一个tag的匹配,对于匹配"nav"所生成的代码应该是:el.tagName=="nav".toUpperCase() 。

通常浏览器对于所有HTML元素,其调用tagName返回的都是全大写字母。

【号外】为什么是大写?

Hax答:这是从HTML的祖先SGML那里继承下来的习惯。对于早期写SGML/HTML的人,要区分标签和正文内容的最简单方法恐怕就是把标签用大写。

不过,据圈子里有名的那个纹身佬说,HTML用大写是因为那时候技术落后,存储太紧张,全大写比较省存储空间……(大意如此,详情我记不清了,请八卦人士咨询Winter)

【/号外】

然而不幸的是,html5-shim以及我所知差不多所有的类似库,都会使用全小写。这是因为现代Web标准的主流是采用全小写。

【号外】为什么换小写了涅?

Hax答:因为这样比较不伤眼,也不伤手。

【/号外】

而IE虽然对于它所能识别的HTML元素都是大小写不敏感的,但是对于通过createElement神经刀产生的新元素,它其实将其视作类XML元素,也就是大小写敏感的,所以其tagName属性将返回最初设定的大小写形式。

如何fix这个问题?

一个容易想到的方式是把html5-shim里的标签列表改为大写。不过这个方式并不管用。因为tagName返回的是最初设定的值,也就是,如果你写

...,返回的是SECTION,如果你写

...返回的就是SECtion(即start tag的大小写),如果你写document.createElement('sEcTion'),返回的就是sEcTion。

显然,QWrap Selector(或任何通用脚本库)不应依赖网页作者如何书写。所以这个问题必须由QW来解决。

此外,库也不应该假设tagName一定返回大写。虽然规范规定对于HTML元素tagName应该始终返回大写,但库必须考虑兼容性(即这里所提到的IE的问题)。

此外,通用脚本库也要有前瞻性,比如考虑Selector引擎用于选择XML元素。当前各种纯JS selector engine并非namespace-aware,所以本不能选择XML元素。但HTML规范已经允许直接在HTML里混合MathML、SVG。新的浏览器也都已经支持了。

比如你可以试着在FireFox里看下述代码:

  
x = − b ± b 2 − 4 ⁢ a ⁢ c 2 ⁢ a

你可以看到$('test').firstChild.tagName返回的是"math"而不是"MATH"。而document.querySelector('#test math')也可以正确选择到该元素。

但是QW Selector就不能选择到math元素了。

【扩展】

假如你在这个文档里插入document.createElement('math')会发生什么呢?

注意,你插入的不是一个MathML元素,那需要通过createElementNS,加上适当的namespace(http://www.w3.org/1998/Math/MathML)才可以。你插入的其实是一个名字恰好为"math"的HTML元素,该元素的tagName返回的是全大写的"MATH"。

此时,使用getElementsByTagName('math')或document.querySelectorAll('math')会返回这两个元素。而getElementsByTagName('MATH')或document.querySelectorAll('MATH')只会返回那个正好叫做"math"的HTML元素,而不会返回真正的MathML的math元素。注:FF行为如此,而目前Chrome是两者都返回的,这应该是WebKit的bug。

【/扩展】

尽管纯JS Selector引擎主要的目的是向前兼容,但若能做到向后兼容就更好了。而QW Selector由于这个小小的大小写问题,在两方面都失败了。

好在,修正它是很容易的。

sFun.push('el.tagName=="' + a.toUpperCase() + '"');

改为

sFun.push('el.tagName.toLowerCase()=="' + a.toLowerCase() + '"');

即可。

有人可能会问,为啥全换成toLowerCase()?

之前人家木有说过吗,UPPERCASE什么的最讨厌了!

说正经的,用toLowerCase()是因为标准所规定的行为就是这样的。尽管全换成toUpperCase()似乎也没有什么不一样的。

上述代码的结果和目前Chrome的行为较为一致,即即使是非HTML namespace的元素,也按照大小写不敏感的方式比较。如果要按照FF的行为,可以改为:

'isHTMLElement(el) ? tagName.toLowerCase() == "{a.toLowerCase()}" : tagName == "{a}"'

上述isHTMLElement检测一个元素是否是HTML元素,逻辑请自行查标准确定。{a}这里用模板语法,这是为了让大家看得更明白,我也省下打许多引号和加号的力气。

感谢各位的阅读,以上就是"QWrap选择器tagName的大小写问题怎么解决"的内容了,经过本文的学习后,相信大家对QWrap选择器tagName的大小写问题怎么解决这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

元素 大小 问题 选择 大写 代码 就是 引擎 标准 号外 标签 行为 这是 内容 小写 技术 方式 浏览器 学习 浏览 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 博彦科技互联网金融 互联网是第几次科技革命的成果 深圳九邦互联网科技有限公司 互联网科技行业发展 科技股互联网 互联网科技未来 朗涯互联网科技 赫美联合互联网科技 上游互联网科技 苏州大垚互联网科技 掌上梦互联网科技 互联网金融科技委员会 湖南洣水互联网科技有限公司扣款 受益于互联网科技的高速发展 宝灵互联网科技有限公司 速维有品互联网信息科技(苏州)有限公司 银行科技岗属于互联网吗 易租星互联网科技有限公司 求路客互联网科技电话 北京品多多互联网科技有限公司 手冲咖啡和咖啡机区别 互联网科技产业 成都玖崟互联网科技有限公司乐商圈怎么样 宁波青枫互联网科技有限公司 健康食品互联网创新科技园项目 晋城互联网科技 互联网科技包装股份有限公司上市 广州燕处互联网科技有限公司 承德科技产业互联网平台 重庆科技产业互联网有哪些
0