SVG中的jQuery .offset()在Safari中不起作用

时间:2019-02-20 15:55:52

标签: jquery svg safari

我有一个带有一些互动要点的SVG地图。将鼠标悬停在该点上会显示一个HTML div,位于该点附近。

因此,我在SVG内部使用了 jQuery .offset()。它在 Chrome Firefox 中运行良好,但在 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,查看完整代码,欢迎您提供任何帮助

1 个答案:

答案 0 :(得分:0)

如果jQuery是针对SVG支持的库,那么我将其称为jQuery错误。但这不是,所以他们可以说这是Safari必须修复的上游错误。

发生的事情是jQuery代码的this part

    // 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)
    };
}