问题提出

对于一个输入框, 如果其id中含有冒号(:),选择器使用需要有特殊写法,

例如 id为下

<input type="text" value="ddd" id="a:b">

使用$(selector)直接使用#id值, 找不到DOM

console.log("#a:b")
console.log($("#a:b").length) // output 0

经过探索可以使用以下两个方法选择到DOM:

$("#a\\:b");

$("[id^='a:b']");

其中第一种, 需要在冒号(:)前添加一个反斜杠(\), 某些同学要问了,命名是两个反斜杠, 忽悠我?

请看下节介绍。

JS转义

js中的字符串语法需要占用一些元字符, 对于这些元字符如果需要想要在字符串中出现就需要使用转移:

转义表: FROM http://www.w3school.com.cn/js/js_special_characters.asp

代码 输出
\' 单引号
\" 双引号
\& 和号
\\ 反斜杠
\n 换行符
\r 回车符
\t 制表符
\b 退格符
\f 换页符

事实上,从上表中看以看出,不仅仅是元字符需要显示才转义(" -> \"), 还有使用转移后可以将特定字符转义为另外含义的情况, 例如 n -> \n 变为换行符。

从学习上可以按照如下逻辑整体理解js转义:

1、 js字符串使用 单引号 或者 双引号 作为字符串的”括号”, 表示一个整体字符串, 引号内部为字符串内容,

2、 那么问题来了, 字符串内容中要想包括 引号, 怎么办?

3、 js设计者(Brendan Eich)考虑, 类似c语言中转义方法, 使用\x 方式来表示x, 即转义规则 \x == x, 这里x包括引号(‘ “)。

4、 既然使用了\x格式执行转义, 那字符串内容中要想包含\怎么办? 如果直接使用\, 则很可能跟其后面一个正常字符意外的转义。

5、 既然转义规则已定  \x == x, 那么\在字符串内容中存在的场景,正符合此规则, 规则应用效果为 \\ == \ 、

6、 最后还有一种场景, 存在很多控制字符(包括格式控制字符,例如\n、 和不可打印字符), 这些字符本身没有可打印字符的表现形式,即没有在ascii中[32, 126]出现。

但是字符只能书写[32, 126]之间的字符, 所以这种情况下需要定义一种新的转义, 为不增加转义元字符, 转义字符还为\,

转义规则为 \x == y,  x in [32, 126], y in [0, 31] or 127

说明: 如果对[32, 126]之间的非3 和 6中使用字符进行转义,即应用规则(\x), 则得到还是x, 符合转义规则。

总结如下图:

demo代码:

            console.log('---- \\x present x (x is printable character) ----');console.log('slash + slash='+"\\"); // \ is part of transfer encoding syntaxconsole.log('slash + "='+"\""); // " is collision with string syntax double quotation, eg "xx" wrapped by "
            console.log('---- \\x present control character ----');console.log('slash + n='+"\n"); // \n present line break
console.log('---- \\x equal x when x is not needed transfer concoding ----');console.log('slash + 8='+"\8"); // \8 == 8console.log('slash + o='+"\o"); // \o == oconsole.log('slash + :='+"\:"); // \: == :

JQuery执行顺序跟踪

经过分析JQuery源代码, $("")的调用次序

1、 $ === jQuery.fn.init

2、 走到 jQuery.fn.init 中  return ( context || rootjQuery ).find( selector );

3、 find == jQuery.find == Sizzle

4、Sizzle 调用 newContext.querySelectorAll( newSelector )

而 querySelectorAll 为 最新浏览器都实现的 选择器查询接口,

各个DOM上都实现了 此接口, 详情见 http://www.cnblogs.com/snandy/archive/2011/03/30/1999388.html

所以查看到这里, 说明jquery 和 sizzle 未对选择器做处理。完全是 浏览器实现 的 querySelectorAll接口行为。

CSS Selector规则

W3C对选择器有一套规范:

http://www.w3.org/TR/css3-selectors/#selectors

其中有对 id选择器的说明, 可见选择器的中 : 为选择器的元字符, 即保留字符, 做伪类使用,其他情况不能与之冲突。

所以读到此处,看官明白 $("#a\\:b"); 为什么要对冒号添加转义了吧!

对于此选择器 即 "#a\\:b"  由于其本身是js字符串, \\表示\, 那么这个字符串在内存中的存储为

可以猜测 querySelectorAll 的实现, 首先会同js对selector字符串 做解析, 首先分析 : 前面不带\ 的冒号, 将其前后内容拆分, 前面为 选择器主体部分, 后面为伪类部分,

然后对 前面主题部分, 执行js字符串转义解析, 类似eval接口执行行为 :

eval("var evalselector = '#a\\:b';")
console.log(evalselector); // output  #a:b

将 转义表写 还原为

运行如下js:

console.log("#a:b")
console.log("#a\:b")
console.log(document.querySelectorAll("#a\\:b").length)
console.log("[id^='a:b']")
console.log(document.querySelectorAll("[id^='a:b']").length)

打印如下:

结论 :

1、冒号(:)属于js中不用转义的普通可见字符, "#a:b" === "#a\:b"

2、 "#a\\:b" 为避免css selector伪类标识符号冲突的解法, 经过 js字符串转义,需要两个反斜杠\, 最后在 querySelectorAll接口中,将\:转换为:

3、 对于id中含有冒号的情况, 可以使用"[id^='a:b']"的表写方式, 这种不需要对冒号转义, 因为这种格式不存在冲突的可能。

建议 id可变的情况,都使用"[id^='a:b']"方式。

demo code

<html>
<head> <script type="text/javascript" src="./jquery.js"></script><style></style>
</head>
<body><input type="text" value="ddd" id="a:b"><script>console.log('---- \\x present x (x is printable character) ----');console.log('slash + slash='+"\\"); // \ is part of transfer encoding syntax
            console.log('slash + "='+"\""); // " is collision with string syntax double quotation, eg "xx" wrapped by "
            console.log('---- \\x present control character ----');console.log('slash + n='+"\n"); // \n present line break
console.log('---- \\x equal x when x is not needed transfer concoding ----');console.log('slash + 8='+"\8"); // \8 == 8
            console.log('slash + o='+"\o"); // \o == o
            console.log('slash + :='+"\:"); // \: == :
console.log('#a+slash+slash+:b='+"#a\\:b"); // #a\\:b == #a\:b
            console.log('jquery length='+$("#a\\:b").length); // length == 1 with selector #a\\:b
            console.log('jquery length='+$("[id^='a:b']").length); // length == 1 with selector [id^='a:b']
console.log("#a:b") //output #a:bconsole.log("#a\:b") //output #a:bconsole.log(document.querySelectorAll("#a\\:b").length)//output 1console.log("[id^='a:b']") //: do not need transfer codingconsole.log(document.querySelectorAll("[id^='a:b']").length) //output 1</script>
</body>
</html>

JQuery选择器中含有冒号的ID处理差异的分析相关推荐

  1. jquery选择器中含有不含有空格的问题

    在<jquery权威指南>中看到一个很有趣的例子,在jQuery中,含有或不含有空格的DOM对象是不一样的 书中源码 js $(function(){var $objTmp0=$(&quo ...

  2. jQuery选择器中的特殊符号和关键字

    一般情况下,在jQuery选择器中,我们很少会用到诸如"."."#"."("."["等特殊字符,因为根据W3C规定,HT ...

  3. jQuery选择器中的通配符[id*='id']及jquery选择器总结

    1.选择器 (1)通配符: $("input[id^='code']");//id属性以code开始的所有input标签 $("input[id$='code']&quo ...

  4. JQuery选择器中的属性筛选

    属性选择器让你可以基于属性来定位一个元素.可以只指定该元素的某个属性,这样所有使用该属性而不管它的值,这个元素都将被定位,也可以更加明确并定位在这些属性上使用特定值的元素,这就是属性选择器展示它们的威 ...

  5. JQuery选择器中的子元素选择器

    子元素筛选选择器不常使用,其筛选规则比起其它的选择器稍微要复杂点,其实博主感觉并不怎么难啦,因为单词so easy,哈哈. 我们来看看都有哪些吧: 注意: 1. :first只匹配一个单独的元素,但是 ...

  6. JQuery选择器中的可见性筛选

    元素有显示状态与隐藏状态,jQuery根据元素的状态扩展了可见性筛选选择器:visible与:hidden 下面用表格大致了解一下,就两个选择器: 这2个选择器都是 jQuery 延伸出来的,看起来比 ...

  7. jQuery 选择器中的空格问题

    直接来看例子: 1 <html> 2 <head> 3 <title>选择器空格的tips</title> 4 <script type=&quo ...

  8. jquery选择器找到含有href属性的所有a标签

    案例: 当页面上含有href属性的a标签被点击的时候,增加加载动画效果. $(function (){ $("a[href]").click(function (){ //load ...

  9. 【新手向】jQuery Mobile中动态加载或执行脚本的分析

    jQuery Mobile是我新的项目中要用到的移动端框架,之所以要使用它,仅仅是因为它的兼容性很好,页面之间的轮转及其优雅.但是jQuery Mobile的UI我并不喜欢,因此又引入bootstra ...

最新文章

  1. cuSPARSELt开发NVIDIA Ampere结构化稀疏性
  2. linux下free源码,linux命令free源码解读:Procps free.c
  3. 点击切换属性html,jQuery_$方法、属性、点击切换
  4. MySQL EXPLAIN Extra列的信息
  5. MyEclipse下Tomcat启动变慢的解决方法
  6. Orleans解决并发之痛(三):集群
  7. Mac OS 查看系统版本信息/硬件信息的命令
  8. 最后2天,错过等1年,这7本计算机经典图书竟然打折了!
  9. HTML5 Canvas 图形组合
  10. 2dpsk调制解调实验matlab_ila抓取数据,matlab分析,调试AD9361信号通路
  11. IntelliJ IDEA中怎么创建xml文件?
  12. weblogic启动项目失败查看_weblogic启动报错常见错误解决办法
  13. 如何将苹方字体写入html,html苹方字体
  14. EDEM 2020的安装
  15. tftp negotiation
  16. 英语口语收集(十九)
  17. 树莓派外接扩展板的的测试
  18. matlab命令行窗口显示长度设置_设置命令行窗口输出显示格式 | MATLAB format| MathWork...
  19. postgresql模糊查询不区分大小写
  20. java怎么样实现反射_Rust如何实现反射?

热门文章

  1. pip更新后怎么还是旧版本_微信号不能修改第二次怎么办?微信更新后还是不能修改微信号怎么办?...
  2. 计算机理论python字符串作业_[Python基础 ] Day_07_作业参考答案
  3. 单线程和多线程的区别
  4. hibernate mysql longblob_为什么不能将JPA / hibernate映射到MySQL blob类型?
  5. 微信小程序php java_PHP实现微信小程序用户授权的工具类示例
  6. oracle面试题关于课程表获取最高分和名字并且去掉重复,oracle复杂查询练习题
  7. python初学者必背函数_新手必看python vlog 1: 函数
  8. connection timed out是什么意思_为什么Java中1000==1000为false而100==100为true?
  9. easyUI中datagrid中getSelected和getSelections的用法
  10. Maven 项目中配置私服