【问题标题】:jQuery .offset() inside SVG is not working in SafariSVG 中的 jQuery .offset() 在 Safari 中不起作用
【发布时间】:2019-07-14 09:10:58
【问题描述】:

我有一个带有一些交互点的地图 SVG。悬停该点会显示位于该点附近的 HTML div

所以我在 SVG 中使用 jQuery .offset()。它在 ChromeFirefox 中运行良好,但在 Safari 中似乎不起作用。它总是回来

{top: 0, left: 0}

HTML/SVG

<svg xmlns="http://www.w3.org/2000/svg" width="1211" height="1198">
    (...)
    <g data-city="amsterdam">
    <path/>
  </g>
    <g data-city="london">
    <path/>
  </g>
    <g data-city="paris">
    <path/>
  </g>
  (...)
</svg>

jQuery

    // -- Open infosbox --
  $('[data-city]').on('touchstart mouseover', function(){
    var city = $(this).attr('data-city');
    var cityEl = $('.city--'+city);
    var offset = setOffsetPosition($(this), cityEl);

    $('.city').removeClass('active');
    cityEl.offset(offset).addClass('active');
  });

  // -- Close infosbox --
  $('[data-city]').on('mouseleave', function(){
        $('.city').removeClass('active');
  });

    function setOffsetPosition($this, $el) {
        var offset = $this.offset();
        var elW = $el.width();
        var elH = $el.height();
        var marginB = 20;
        offset.top = offset.top - (elH + marginB);
        offset.left = offset.left - (elW/2);
        return offset;
    }

完整代码

这是我的codepen查看完整代码,欢迎任何帮助

【问题讨论】:

  • 谢谢@Pete!我刚刚更新了我的帖子。希望这样会更好

标签: jquery svg safari


【解决方案1】:

如果 jQuery 是一个旨在支持 SVG 的库,我会称之为 jQuery 错误。但事实并非如此,因此他们可以说这是 Safari 必须修复的上游错误。

发生的是this part的jQuery代码:

    // Return zeros for disconnected and hidden (display: none) elements (gh-2310)
    // Support: IE <=11 only
    // Running getBoundingClientRect on a
    // disconnected node in IE throws an error
    if ( !elem.getClientRects().length ) {
        return { top: 0, left: 0 };
    }

这被认为是 IE 的后备,以确保不为断开连接的 DOM 节点引发错误。但它使用接口Element.getClientRects(),如果元素在 SVG 命名空间中,Safari 会返回一个空列表。

解决此问题的方法是直接使用其余代码。您知道所选节点是文档的一部分,因此不会发生上述错误:

function setOffsetPosition($this, $el) {
    var rect = $this[0].getBoundingClientRect();
    var win = $this[0].ownerDocument.defaultView;

    var elW = $el.width();
    var elH = $el.height();
    var marginB = 20;
    return {
         top: rect.top + win.pageYOffset - (elH + marginB),
         left: rect.left + win.pageXOffset - (elW/2)
    };
}

【讨论】:

  • 嗨@ccprog!感谢您的帮助和解释。您的代码适用于 offset.left,但由于某种原因,offset.top 不正确。我尝试了一些操作和其他方法来获得正确的结果,但没有运气。我会继续努力让它发挥作用,但如果您有任何解决问题的想法,我们非常欢迎:) 再次感谢
  • 对不起,我走错了路。我认为.getScreenCTM() 不会考虑滚动,这将使其比getBoundingClientRect() 更易于使用。但事实并非如此,因此 jQuery 解决方案很好 - 您只需绕过错误条件。见编辑。
猜你喜欢
  • 2022-01-08
  • 1970-01-01
  • 2016-06-17
  • 2018-12-26
  • 2017-05-25
  • 2017-01-12
  • 1970-01-01
  • 2017-10-13
  • 2018-08-30
相关资源
最近更新 更多