缩放时Safari中的jQuery UI问题

jQuery UI issues in Safari when zoomed

本文关键字:UI 问题 jQuery 中的 Safari 缩放      更新时间:2023-09-26

我在Safari中遇到了一些非常基本的jQueryUI功能问题当应用某些浏览器缩放时:

  • 启动第二次拖动时,可拖动元素会跳跃。在官方演示中观察
  • 带有revert选项的可拖动对象在启动revert时会跳转。在官方演示中观察
  • 具有"捕捉到图元"选项的可拖动图元在拖动图元后会错误地按位置捕捉。在官方演示中观察到

版本:

  • jQuery:1.11.1
  • Safari:7.1

jQueryUI对Chrome、Firefox和Internet Explorer 11浏览器缩放反应良好。如何让jQueryUI对Safari的浏览器缩放做出正确反应?

4年前报告了一个类似的错误,由于已通过迁移到Safari 5解决,该错误已被关闭。

不幸的是,在基于webkit的浏览器中缩放由于其实现方式而存在一些问题,这反映在缩放时可能出现的定位错误中。有人提议以更一致的方式统一这一点,但没有估计何时可以实施:http://trac.webkit.org/wiki/ScalesAndZooms

同时,恐怕你只能做一件事:缩放后刷新页面会固定元素的位置。

此问题是由WebKit中的一个错误引起的,该错误在Chrome中已修复,但在Safari:中未修复

https://bugs.webkit.org/show_bug.cgi?id=105979

描述:getComputedStyle()返回left、right、top和bottom等属性的缩放值(当元素的"position"为"relative"时)。这使得我们无法依赖这些价值观。

以下是错误报告中提供的测试用例:

https://bug-105979-attachments.webkit.org/attachment.cgi?id=181121

它可以通过monkey补丁getComputedStyle来解决。这是一种相当激进的方法,我只建议在对您的项目影响严重的情况下这样做。

这里有一个演示:

http://codepen.io/lampyridae/pen/PwZNdo

修复本身:

//Monkey-patching getComputedStyle to work around the following 
//WebKit Safari bug:
//https://bugs.webkit.org/show_bug.cgi?id=105979
(function() {
   //tolerate small variations caused by zoom scaling
   var delta = 0.05;
   function close_enough(x, y) {
      var diff = x - y;
      return delta > diff && diff > -delta;
   }
   //Set up a reference element to measure
   //undesired variations from browser zooming
   var expected_left = 100;
   var body = document.getElementsByTagName("body")[0];
   var ref_node = document.createElement("div");
   body.appendChild(ref_node);
   ref_node.style.position = "relative";
   ref_node.style.left = expected_left + "px";
   ref_node.style.height = "0";
   var native = window.getComputedStyle;
   window.getComputedStyle = function(elt) {
     //Bug only affects relative positioning.
     //Only intervene if the element is concerned.
     var styles = native(elt);
     if("relative" !== styles.position) {
        return styles;
     }
     //Measure undesired variation from reference element
     var ref_styles = native(ref_node);
     var ref_left = parseFloat(ref_styles.left);
     if(close_enough(expected_left, ref_left)) {
       return styles;
     }
     var proportion = ref_left / expected_left;
     //Copy styles
     //Use an object implementing the CSSStyleDeclaration interface.
     var cloned = document.createElement("div").style;
     var attr;
     for(var ii=0; ii < styles.length; ++ii){
       attr = styles[ii];
       cloned[attr] = styles[attr];
     }
     //correct styles
     var property_names = ["top", "right", "bottom", "left"];
     for(var ii = 0; ii < property_names.length; ++ii) {
         var prop_name = property_names[ii];
         if(prop_name in cloned) {
               cloned[prop_name] = (parseFloat(cloned[prop_name]) / proportion) + "px";
         }         
     }
     return cloned;
   }
})();