我的编程空间,编程开发者的网络收藏夹
学习永远不晚

jQueryv3.3.1的BUG如何解决

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

jQueryv3.3.1的BUG如何解决

这篇文章主要讲解了“jQueryv3.3.1的BUG如何解决”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“jQueryv3.3.1的BUG如何解决”吧!

发现问题

最新版的 FineUIPro v5.2.0 中,我们将内置的 jQuery v1.12.4 升级到 jQuery v3.3.1 ,可以看升级记录:

+升级到jQuery v3.3.1。
    -jQuery v3.x支持的浏览器:Chrome,Edge,Firefox,Safari,IE9+。
    -增加类型JSLibrary枚举值JQv1,用来引入jQuery v1.x。
    -如果需要支持IE8,请在Web.config中增加配置项JSLibrary=JQv1。
    -IE8有限支持并且复杂页面可能会有性能问题,建议大家积极引导用户使用现代浏览器。

之所以做这个升级,主要考虑如下因素:

IE8的市场份额逐渐萎缩,可以考虑将IE8的支持放到次要位置

通过全部配置参数 JSLibrary=JQv1 引入老版本的 jQuery v1.12.4,这样老客户仍然可以支持IE8

默认使用 jQuery v3.3.1,紧跟jQuery版本意味着较好的性能和安全性,以及遇到问题能够及时解决

考虑到 jQuery 这么多年的发展,稳定性应该不是问题

整个升级过程还是很平缓的,没有大的改动。

唯一让我头疼的时,好像表格中节点的位置总计算不对,比如在表格的单元格编辑时,如果表格没有滚动条,显示的编辑框是正确的:

jQueryv3.3.1的BUG如何解决

但是,表格的滚动条一出现,编辑框就错位了:

jQueryv3.3.1的BUG如何解决

而这个问题,在使用 jQuery v1.12.4 时是不存在的!

分析问题

经过一段时间的调试,最终确定这是最新版 jQuery v3.3.1 的一个BUG,出现这个问题需满足如下条件:

引用最新版 jQuery v3.3.1

计算表格 tr 或者 td 的相对位置时出错,比如:$('table tr:eq(1) td(0)').position()

为了更直观的演示这个问题,我写了个例子,其中HTML代码块:

<div class="container">  <table>    <tr>      <td>row-1</td>    </tr>    <tr>      <td id="theTD">row-2</td>    </tr>  </table></div><div id="result"></div>

CSS代码块:

.container {  background-color: lightgreen;  padding: 50px;  position: relative;}table {  width: 100%;  border-collapse: collapse;  border-spacing: 0;  background-color: green;}table td {  padding: 0;  height: 50px;  color: #fff;  vertical-align: top;}

为了更直观的描述问题,我们用不同的背景色标识外层的容器(.container)和内部的表格(table)。

JavaScript代码块:

$(function() {    var tdPosition = $('#theTD').position();    $('#result').html('top:' + tdPosition.top + ' left:' + tdPosition.left);});

按照正常的思维模式,上面的 theTD 的相对位置应该是相对 .container 的偏移量(因为 .container 是 td 的第一个遇到的相对定位的父元素)。 

因为 .container 设置了 50px 的内边距,表格每行的高度为 50px,所以 theTD 距离 .container 的垂直高度应该是 100px。

所以我们期望的输出结果应该是:

top:100 left:50

但是结果真的如此吗?我创建了两个示例,分别是 引用 jQuery v1.9.1 的示例 和 引用 jQuery v3.3.1 的示例,得到的结果如下所示:

jQueryv3.3.1的BUG如何解决

jQueryv3.3.1的BUG如何解决

可见,在 jQuery v3.3.1 中,获取表格中 td 节点的相对位置(position)得到的结果并不是我们想要的。那这个值到底是什么?

top: 50 left:0

解决问题

经过认真分析,我认为这个值是 td 相对外部 table 节点的偏移量,而不是相对于第一个浮动父节点的位置(position: relative / absolute)。

曾经一度我对 position() 和 offset() 的确切含义产生了怀疑,难道是我理解错了?后来发现我的理解没有问题:

.offsetParent() is supposed to return the nearest positioned element, where "positioned" means it has a css position attribute of "relative", "absolute", or "fixed".

我在很多地方依赖于 position 的计算解决,难道是 jQuery 计算 offsetParent 节点时出了差错:

打开浏览器的调试窗口,我输入如下代码:

$('#theTD').offsetParent()

jQueryv3.3.1的BUG如何解决

可见,通过 jQuery 获取到的依然是 .container, 这个方法返回的没问题。

没办法,既然出了问题,只好先在自己的代码中修正了。

第一次尝试

既然 td 的相对位置是相对于 table,那不如用 table 做个中转,计算出 table 的 position 加上去不就行了,如下所示:

$(function() {    var tdPosition = $('#theTD').position();   var tablePosition = $('#theTD').parents('table').position();      $('#result').html('top:' +       (tdPosition.top + tablePosition.top) + ' left:' +       (tdPosition.left + tablePosition.left));    });

jQueryv3.3.1的BUG如何解决

看着好像是正确的,后来测试发现遇到嵌套表格就不行了,如下示例:

<div class="container"><table class="table-outer">  <tr>    <td>table1-row1</td>  </tr>  <tr>      <td>        <table>          <tr>            <td>row-1</td>          </tr>          <tr>            <td id="theTD">row-2</td>          </tr>        </table>    </td>   </tr> </table></div><div id="result"></div>
.container {  background-color: lightgreen;  padding: 50px;  position: relative;}.table-outer {  background-color: blue;}table {  width: 100%;  border-collapse: collapse;  border-spacing: 0;  background-color: green;}table td {  padding: 0;  height: 50px;  color: #fff;  vertical-align: top;}

jQueryv3.3.1的BUG如何解决

第二次尝试

一计不成,再生一计。既然 table 的 position 出问题,那么 div 的 position 应该是正常的吧。这次我就来在 td 里面动态创建一个 div 节点怎么样?

$(function() {  var tmpDiv = $('<div />').prependTo($('#theTD'));  var tdPosition = tmpDiv.position();  tmpDiv.remove();      $('#result').html('top:' + tdPosition.top + ' left:' + tdPosition.left);});

jQueryv3.3.1的BUG如何解决

看着好像没有问题,可以问题依旧,当设置 td 的 vertical-align: middle 时,问题暴露出来了,因为此时 td 内的 div 是居中显示的:

jQueryv3.3.1的BUG如何解决

第三次尝试

就在我一筹莫展时,我忽然想到前面的 offsetParent() 函数,这个函数能获取正确的父节点。既然 position() 函数有问题,我何不尝试 offset() 函数。

jQuery.position(): 获取元素相对于父元素的偏移量(position: relative / absolute)

jQuery.offset(): 获取元素相对于视口的偏移量

$(function() {    var tdOffset = $('#theTD').offset();    var tdParentOffset = $('#theTD').offsetParent().offset();    $('#result').html('top:' + (tdOffset.top  - tdParentOffset.top) + ' left:' + (tdOffset.left - tdParentOffset.left));});

这次使用当前元素和相对父元素的 offset 相减,得到的结果是否我们所需要的呢?

jQueryv3.3.1的BUG如何解决

不错,正是我们所需要的。因为这个逻辑判断很简单,和是否表格嵌套没关系,所以测试下第一次尝试失败的情况:

jQueryv3.3.1的BUG如何解决

 Bingo! 一切正常。此问题圆满解决!

真是的jQuery的BUG吗?

想想就不可思议,一个被全球用户使用的公共JavaScript居然有这样的BUG,难道就没人发现么?

网上搜索了一圈,看起来我多虑了,早就有用户提出这个问题:

https://github.com/jquery/api.jquery.com/issues/1081

 Per the spec, an offsetParent is defined as an element with a position that is non-static or is a table, th, or td element. Since 3.3.0, position started using the native offsetParent property which started respected table, th, and td as offset parents, but the .offsetParent() method was left unchanged. We'll fix this in an upcoming release, but we'll need to note the special behavior for those 3 elements in the docs.

这个是 jQuery 核心开发团队给出的答案,大意是说 offsetParent 这个节点属性指的是这样一个父节点:

节点是非静态的,也就是拥有 position: relative / absolute / fixed 样式

节点是 table, th 或者 td

哈,这么多年过去了,我居然第一次听说 offsetParent 还有相对于 td,th,table这个说法,尽管这个td,th,table节点是 position:static,下面使用代码来验证一下:

$(function() { var tdPosition = $('#theTD').position(); var offsetParent = $('#theTD').offsetParent()[0].tagName; var nativeOffsetParent = $('#theTD')[0].offsetParent.tagName; $('#result').html('top:' + tdPosition.top + ' left:' + tdPosition.left + '<br>offsetParent():' + offsetParent + '<br>Native offsetParent:' + nativeOffsetParent);});

分别在不同浏览器中查看结果。

Chrome:

jQueryv3.3.1的BUG如何解决

Firefox:

jQueryv3.3.1的BUG如何解决

Edge:

jQueryv3.3.1的BUG如何解决

IE11(由于IE11打不开jsfiddle网站,我们单独创建了一个页面):

jQueryv3.3.1的BUG如何解决

甚至IE9也是这样的:

jQueryv3.3.1的BUG如何解决

好吧,看来我真是孤陋而寡闻了。

jQuery 是在 v3.3.0 开始考虑到第二种情况的,但是 jQuery.offsetParent() 的定义没有改变。这种不一致性本身就是一个BUG。

而不和之前的 jQuery v1.x, v2.x 乃至于 v3.3.0 之前的版本兼容,对于一个广泛使用的公共库而言,更应该算是一个BUG,或者至少提供兼容之间的方法。

考虑另一个更现实的问题:在实际应用中,我们为什么要获取 td ,table 的 position() 呢?

不是为了拿获取到的值去更新其他 td 或者 table 的 top/left 属性!

而是为了拿获取的值去更新其他相关 div 节点的 top/left 属性,而 div 节点的 position() 是相对于 position: relative / absolute / fixed 父节点的,而非 td ,table 节点,这就一定会出问题。

所以,我们还是认定这是一个BUG。

但是 jQuery 官方貌似没有修正这个问题的意思,而是可能在将来版本修改  jQuery.offsetParent() 的定义:

jQueryv3.3.1的BUG如何解决

但是jQuery你这样做真的好么,都10多年了你都没遵守标准,突然来个小版本号称支持标准,搞的和之前的代码不兼容,你让之前的代码情何以堪!

不管怎样,我们有了自己的解决办法。

感谢各位的阅读,以上就是“jQueryv3.3.1的BUG如何解决”的内容了,经过本文的学习后,相信大家对jQueryv3.3.1的BUG如何解决这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

jQueryv3.3.1的BUG如何解决

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

jQueryv3.3.1的BUG如何解决

这篇文章主要讲解了“jQueryv3.3.1的BUG如何解决”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“jQueryv3.3.1的BUG如何解决”吧!发现问题最新版的 FineUIPro
2023-07-05

如何解决jquery-multiselect在ie6里的bug

本篇内容主要讲解“如何解决jquery-multiselect在ie6里的bug”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何解决jquery-multiselect在ie6里的bug”吧!
2023-06-08

如何解决React.memo引起的bug问题

这篇文章主要介绍如何解决React.memo引起的bug问题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!与PureComponent不同的是PureComponent只是进行浅对比props来决定是否跳过更新数据这
2023-06-29

Java中如何解决null值引起的Bug

这篇文章主要讲解了“Java中如何解决null值引起的Bug”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java中如何解决null值引起的Bug”吧!业务中的空值场景存在一个 UserSe
2023-06-16

如何解决mysql删除用户的bug问题

这篇文章将为大家详细讲解有关如何解决mysql删除用户的bug问题,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。删除了user的用户之后 无法再次创造相同的用户名在mysql 数据库中有一张user表,可
2023-06-14

如何解决微软vs2015 gitHub插件bug

本篇内容主要讲解“如何解决微软vs2015 gitHub插件bug”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何解决微软vs2015 gitHub插件bug”吧!    为了方便开发人员在V
2023-06-13

JDK序列化Bug难题如何解决

这篇文章主要讲解了“JDK序列化Bug难题如何解决”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JDK序列化Bug难题如何解决”吧!1、背景最近查看应用的崩溃记录的时候遇到了一个跟 Java
2023-07-05

如何解决Linux硬盘满了造成的bug

这篇文章主要介绍了如何解决Linux硬盘满了造成的bug,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。前段时间公司的一个项目出现了一个 bug,使用 ajax 上传大文件时会
2023-06-12

滥用@PathVariable导致出现bug如何解决

这篇“滥用@PathVariable导致出现bug如何解决”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“滥用@PathVar
2023-07-04

win10系统夜间模式bug如何解决

这篇“win10系统夜间模式bug如何解决”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“win10系统夜间模式bug如何解决
2023-07-01

如何解决idea中默认equals和hashcode引起的bug

小编给大家分享一下如何解决idea中默认equals和hashcode引起的bug,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!idea默认带的equals和ha
2023-06-20

如何解决ie6中select无法被div遮盖的bug

这篇文章主要介绍如何解决ie6中select无法被div遮盖的bug,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!使用div制作蒙版或模拟弹出窗口,但在IE6下,当div下方有下拉列表框select元素的时候,下拉列
2023-06-08

mybatisplus+pgsql查询bug的解决

本文主要介绍了mybatisplus+pgsql查询bug的解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
2023-03-19

不规范使用ThreadLocal导致bug如何解决

这篇文章主要讲解了“不规范使用ThreadLocal导致bug如何解决”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“不规范使用ThreadLocal导致bug如何解决”吧!因为线程重用导致的
2023-07-04

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录