jquery Bug:当表单中包含name为nodeType的input时jquery选择器失效的bug 与您分享我的快乐

一、发现bug的过程

今天同事在使用我做的js表单验证控件时,发现当表单中存在一个name为nodeType的input时,验证组件就不好用了。经简单测试发现$('form :input')根本选择不到一个元素,心想这肯定是jquery的bug了。

二、分析bug

然后就打开jquery的源码粗略看了一下,发现里里边好多好多的代码都关系着nodeType的属性,这让我如何下手呢?这可是将近一万行的代码。泪奔呀。。。

随便打几个断点试试吧,无效无效。。。。心中那个纠结那个郁闷。。。

无意间发现了代码里这样一行注释。

/*!
* Sizzle CSS Selector Engine v1.9.4-pre
* http://sizzlejs.com/
*
* Copyright 2013 jQuery Foundation, Inc. and other contributors
* Released under the MIT license
* http://jquery.org/license
*
* Date: 2013-05-27
*/

  

心想我的这个问题肯定就是css选择器的问题,从这里下手肯定是对的。

然后去这个地址下载了sizzle.js,发现这个选择器问题在这里也是存在的。心中窃喜。然后就一点点调试找到了问题的根源。

发现的问题是什么呢?

就是当form表单里如果有一个 nodeType这样的一个input时,$('form')[0].nodeType 不等于1了,他的值是这个input对象。

三、解决bug

最后修改代码 

if ( elem.nodeType === 1 || checkNonElements ) {

修改为

if ( (elem.nodeType === 1 || typeof elem.nodeType != "number") || checkNonElements ) {

(共有三处)

修改后发现Sizzle('form :input')好用了,对应地修改jquery里的 ,$('form :input')好用了。

但是悲催的是我的验证控件还是不好用。测试发现是因为$('form').find(':input')不好用造成的。心想难道还必须调试jquery的源码吗?心灰意冷了。真的想放弃了。刚才的喜悦与成就感没了。。。。。。

上网上又随便地查一些资料,查一些别人对jquery源码的剖析等,发现问题肯定还是出在Sizzle里,并悟出了find的方法应该就是Sizzle(':input',Sizzle( 'form ')[0])  ,测试发现我修改后的代码使用这种表达式依然不好用。(Sizzle中没有find的方法)

然后基于这个表达式进行测试,修改了另一处代码:

if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {

替换为:

if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 && (typeof context.nodeType === "number")) {

大功告成。

以上修改方案仅为个人修改意见,并不能保证不会引发其它bug, 如君真要使用,请慎重。

本文为作者原创,转载请注明出处,与你分享我的快乐
http://www.cnblogs.com/weirhp

原文地址:https://www.cnblogs.com/weirhp/p/3121688.html