Safari不会在溢出SVG内容时发出指针事件 [英] Safari doesn't emit pointer events on overflowing SVG contents

查看:121
本文介绍了Safari不会在溢出SVG内容时发出指针事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试将点击事件添加到SVG元素中,该元素具有可见的溢出和其中的一个形状元素(圆形/路径),这些元素溢出SVG。

在Safari(9,10,11)上,点击事件在形状元素(圆/路径)溢出的区域不起作用,而在SVG中存在的区域中可以正常工作。



  var count = 0; function clickMe(){console.log计数++; document.getElementById(counter)。innerHTML = count;}  

#counter {font-size:2em;}#starSvg {pointer-events:auto;溢出:可见;位置:绝对; left:200px;顶部:250px; border:1px solid red;}#starPolygon {overflow:visible;填写:rgba(0,153,219,1); pointer-events:visiblePainted;笔画宽度:4; stroke-linecap:square; stroke-linejoin:round; round; stroke:rgba(219,0,153,1);光标:指针; shape-rendering:geometricPrecision} p {margin:10px 0;}

< DIV> < p>在Chrome& amp; amp; amp;狩猎< / p为H. < p>在Chrome上:点击星星的所有四只手上的工作。< / p> < p>在Safari上:单击仅在红色区域内的手上工作(SVG bounding Rect)。< / p> < p style =position:absolute; top:100px; left:200px;>点击事件计数器:< span id =counter> 0< / span> < / p为H. < div class =containter> < svg onclick =clickMe()id =starSvgwidth =100%height =100%> < g width =100%height =100%transform =style =overflow:visible; transform:rotate(45deg)translate(0,0);> < polygon id =starPolygonshape-rendering =geometricPrecisionpoints =0 -90,15 -15,90 0,15 15,0 15,0 90,-15 15,-90 0,-15 -15> < /多边形> < / g取代; < / SVG> < / div>< / div>

Safari中的错误?点击事件在包括IE在内的所有浏览器中都能正常工作。

解决方案

这反映了Webkit错误报告#140723: https://bugs.webkit.org/show_bug.cgi?id=140723



该错误报告链接到此codepen示例,以再现您找到的完全相同的结果:
https://codepen.io/anon/pen/pvPQqY



以下适用于此处:



https:// codepen .io / anon / pen / YeOmGW



===========



为清晰起见进行了编辑:有证据表明,初始剪裁在最外面的视口(svg)边界处起作用,同时溢出属性允许该剪辑外部的形状可见性ped区域。实际上,渲染指针事件是无效的。



换句话说,裁剪被应用的证据IAW第一句话: http://w3.org/TR/SVG11/masking.html#AutoClipAtViewportNotViewBox ,同时符合溢出规则(最后三个)在这里: http://w3.org/TR/SVG11/masking.html #OverflowAndClipProperties 是导致Safari出现此问题的原因;为了解决这个问题,OP必须创建一个包装视口来为由不一致的实现产生的困境创建一个(解决方法)解决方案。

b

这与添加可能需要包装所需内容的任何其他HTML结构类似。 (我真的专注于帮助解决问题)



希望这有助于。



  var count = 0; document.querySelector('svg')。addEventListener('click',clickMe); function clickMe(e){console.log(点击:+ e.target.id);计数++; document.getElementById(counter)。innerHTML = count;}  

#counter {font-size:2em;}#starSvg {pointer-events:auto;位置:绝对;宽度:100%;身高:100%;左:0; top:0;}#starPolygon {transform:translate(50%,50%)rotate(45deg);填写:rgba(0,153,219,1);笔画宽度:4; stroke-linecap:square; stroke-linejoin:round; round; stroke:rgba(219,0,153,1);光标:指针; shape-rendering:geometricPrecision} #starClip {width:100%;身高:100%;笔画宽度:1;中风:红色; fill:transparent;} p {margin:10px 0;}

< DIV> < p>在Chrome& amp; amp; amp;狩猎< / p为H. < p>在Chrome上:点击星星的所有四只手上的工作。< / p> < p>在Safari上:单击仅在红色区域内的手上工作(SVG bounding Rect)。< / p> < p style =position:absolute; top:100px; left:200px;>点击事件计数器:< span id =counter> 0< / span> < / p为H. < div class =containter> < svg id =starSvg> < rect id =starClipx =50%y =50%>< / rect> < g取代; < polygon id =starPolygonx =0y =0points =0 -90,15 -15,90 0,15 15,0 90,-15 15,-90 0,-15 -15 >< /多边形> < / g取代; < / SVG> < / div>< / div>

I'm trying to add click events to an SVG Element which has visible overflow and a shape element(circle/path) inside it which overflows the SVG.

On Safari(9,10,11), click event doesn't work in the area where the shape element(circle/path) overflows while it works fine in the area present within the SVG.

var count = 0;

function clickMe() {
  console.log("in click func");
  count++;
  document.getElementById("counter").innerHTML = count;
}

#counter {
  font-size: 2em;
}

#starSvg {
  pointer-events: auto;
  overflow: visible;
  position: absolute;
  left: 200px;
  top: 250px;
  border: 1px solid red;
}

#starPolygon {
  overflow: visible;
  fill: rgba(0, 153, 219, 1);
  pointer-events: visiblePainted;
  stroke-width: 4;
  stroke-linecap: square;
  stroke-linejoin: round;
  stroke: rgba(219, 0, 153, 1);
  cursor: pointer;
  shape-rendering: geometricPrecision
}

p {
  margin: 10px 0;
}

<div>
  <p>Open this webpage on Chrome &amp; safari</p>
  <p>On Chrome: Click work on all four hands of the star.</p>
  <p>On Safari: Click works only on the hands inside the red area(SVG bounding Rect).</p>

  <p style="position: absolute; top: 100px; left: 200px;">Click Event Counter:
    <span id="counter">0</span>
  </p>
  <div class="containter">
    <svg onclick="clickMe()" id="starSvg" width="100%" height="100%">
          <g width="100%" height="100%" transform="" style="overflow: visible; transform: rotate(45deg) translate(0, 0);">
            <polygon id="starPolygon" shape-rendering="geometricPrecision" points="0 -90,15 -15,90 0,15 15,0 90,-15 15,-90 0,-15 -15"></polygon>
          </g>
        </svg>
  </div>
</div>

Is this also a bug in Safari? The click event works fine in all browsers including IE.

解决方案

This mirrors Webkit bug report #140723 here: https://bugs.webkit.org/show_bug.cgi?id=140723

That bug report links to this codepen example reproducing the exact same results you've found: https://codepen.io/anon/pen/pvPQqY

And with the fix as I've described below applied here:

https://codepen.io/anon/pen/YeOmGW

===========

Edited for clarity: The evidence is clear that the initial clipping is taking effect at the outer most view port (svg) boundary, while at the same time the overflow property is allowing the visibility of the shape outside that clipped area. In effect rendering the pointer events void.

Said differently, evidence that clipping is applied IAW the first sentence here: http://w3.org/TR/SVG11/masking.html#AutoClipAtViewportNotViewBox , while at the same time conforming to the overflow rules (last three) here: http://w3.org/TR/SVG11/masking.html#OverflowAndClipProperties is the cause of this issue with Safari;

To overcome this issue, the OP must create a wrapper viewport to create a (workaround) solution to the dilemma created by the inconsistent implementations.

This is similar to adding any other HTML structure that might be required to wrap required content. (I'm really focused on helping solve the problem)

Hope this helps.

var count = 0;
document.querySelector('svg').addEventListener('click',clickMe);

function clickMe(e) {
  console.log("clicked on: " + e.target.id);
  count++;
  document.getElementById("counter").innerHTML = count;
}

#counter {
  font-size: 2em;
}

#starSvg {
  pointer-events: auto;
  position: absolute;
  width: 100%;
  height: 100%;
  left:0;
  top:0;
}

#starPolygon {
  transform: translate(50%, 50%) rotate(45deg);
  fill: rgba(0, 153, 219, 1);
  stroke-width: 4;
  stroke-linecap: square;
  stroke-linejoin: round;
  stroke: rgba(219, 0, 153, 1);
  cursor: pointer;
  shape-rendering: geometricPrecision
}
#starClip {
  width: 100%;
  height: 100%;
  stroke-width: 1;
  stroke: red;
  fill: transparent;
}

p {
  margin: 10px 0;
}

<div>
  <p>Open this webpage on Chrome &amp; safari</p>
  <p>On Chrome: Click work on all four hands of the star.</p>
  <p>On Safari: Click works only on the hands inside the red area(SVG bounding Rect).</p>

  <p style="position: absolute; top: 100px; left: 200px;">Click Event Counter:
    <span id="counter">0</span>
  </p>
  <div class="containter">
    <svg id="starSvg">
          <rect id="starClip" x="50%" y="50%"></rect>
          <g>
            <polygon id="starPolygon" x="0" y="0" points="0 -90,15 -15,90 0,15 15,0 90,-15 15,-90 0,-15 -15"></polygon>
          </g>
        </svg>
  </div>
</div>

这篇关于Safari不会在溢出SVG内容时发出指针事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆