zepto 赋值时单位转换问题
zepto 的 animate 方法移动某个元素的位置时,例如修改某个绝对定位的元素的 left 值,要与修改前的值单位一致,修改前如果是像素值,修改后也要是像素值,否则android 手机上将不会出现动画效果,而是直接把元素放到修改后的位置。使用 jQuery 时会进行计算并最后赋值为像素值,zepto 省略了转换所以会有单位问题,需要注意。
transform:rotate 在 Safari 中渲染 bug
transform:rotateY, transform:rotateX 在Safari浏览器上bug,该bug会导致在执行动画元素层级之上的元素闪动。解决方案是在元素执行rotate的同时添加一个 translateZ(1000px),在动画执行到最后 translateZ(-1px),或者把 translateZ(-1px) 直接以css的方式写在该元素样式里。不过该元素在执行动画时会覆盖在其他元素之上,动画结束时才会回到原来的层级。
注意:元素添加 translate 时不能同时有prospect。否则 translateZ(1000px) 会正常渲染,即朝用户拉近了1000个像素(如果translateZ的值较小,例如楼主试过1px 10px,都没法修复该bug,暂时还未找到原因)。
jquery ui Draggable 对使用 transform:scale 缩放的元素进行脱拽时,元素在拖拽开始时会跳一下偏离起始位置。
先说解决方法, 1、2里选择一种(笔者使用了方法2):
1、在 jquery.ui.draggable.js 里把
//The element's absolute position on the page minus margins
this.offset = this.positionAbs = this.element.offset();
替换为
//The element's absolute position on the page minus margins
this.offset = this.positionAbs = { top: this.element[0].offsetTop,
left: this.element[0].offsetLeft };
2、如果不想修改 jquery.ui.draggable.js 就修改绑定拖拽的代码,如下:
var recoupLeft, recoupTop; $(element).draggable({ start: function (event, ui) { var left = parseInt($(this).css('left'),10); left = isNaN(left) ? 0 : left; var top = parseInt($(this).css('top'),10); top = isNaN(top) ? 0 : top; recoupLeft = left - ui.position.left; recoupTop = top - ui.position.top; }, drag: function (event, ui) { ui.position.left += recoupLeft; ui.position.top += recoupTop; } });
至于造成这种情况的原因,看到有人说是因为draggable依赖的jquery offset()方法里使用的js原生函数getBoundingClientRect,对于css3 transform后的元素在不同浏览器里获取的值会不同:
'This is a result of draggable's reliance on the jquery offset()
function and offset()
's use of the native js function getBoundingClientRect()
. Ultimately this is an issue with the jquery core not compensating for the inconsistencies associated with getBoundingClientRect()
. Firefox's version ofgetBoundingClientRect()
ignores the css3 transforms (rotation) whereas chrome/safari (webkit) don't.'
如图:
但是笔者用最新的chrome和ff里测试,调用该函数获取的值是一致的,即浏览器在底层已经统一了。但两者都有拖拽开始时,元素跳动的现象,因此可以推测不是该原因造成的上述问题,但是解决方法(笔者使用了方法2)是有效的。