SVG getIntersectionList returns null

2019-08-01 15:46发布

In the context of a SVG file, the following JavaScript:

var svg = document.rootElement, hitRect, hits;

hitRect = svg.createSVGRect();
hitRect.height = 1;
hitRect.width = 1;
hitRect.y = 100;
hitRect.x = 100;

hits = svg.getIntersectionList(hitRect, null);

always assigns null to hits, regardless if there were any intersections at all (in the case of no intersections, it should've been an empty NodeList).

Has anyone stumbled in to this problem? Is there a known workaround for hit-testing a SVG in Android?

Tested on: Android default browser on Android 4.0.3 (emulator), 4.0.3 (GALAXY Note SC-05D). (Google Chrome works)

Edit

I also tried looping through all elements (document.getElementsByTagName("*")), testing each one with svg.checkIntersection, to no avail. checkIntersection just returned true for every single element.

1条回答
甜甜的少女心
2楼-- · 2019-08-01 16:25

I also encounter the problem when test of iOS Safari <= 5.0, same like it's not support SVG 1.1, so after adding following attribute to the svg element, it's no effect:

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
   <rect id="r1" x="5" y="5" width="40" height="40"/>
   <rect id="r2" x="105" y="105" width="40" height="40"/>
   <rect id="r3" x="5" y="5" width="40" height="40"/>
   <rect id="rr" x="5" y="5" width="400" height="400" fill="red"/>
   <rect id="r4" x="5" y="5" width="40" height="40"/>
   <rect id="r5" x="5" y="5" width="40" height="40"/>
</svg>

<script type="text/javascript">

var isTouch = ('ontouchstart' in window) || ('DocumentTouch' in window && document instanceof DocumentTouch);
var downE = isTouch? 'touchstart' :'mousedown';
var moveE = isTouch? 'touchmove' :'mousemove';
var upE = isTouch? 'touchend' :'mouseup';

window.addEventListener(downE, startTest )
function startTest (evt) {
    setTimeout(function  () {

        var svg=document.querySelector('svg');
        var r = svg.createSVGRect();
        r.x = 20;
        r.y = 20;
        r.width = r.height = 44;
        var getIntersectionList = svg.getIntersectionList(r, null );
        var checkIntersection = svg.checkIntersection( document.querySelector('#r2'), r );
        var elementFromPoint = document.elementFromPoint(20,20);
        alert("getIntersectionList: "+getIntersectionList);
        alert("checkIntersection: "+checkIntersection);
        alert("elementFromPoint: "+elementFromPoint);

    },1000);

}
</script>
</body>
</html>

Above test code should alert:

getIntersectionList: [object NodeList]
checkIntersection: false
elementFromPoint: [object SVGRectElement]

But in iOS Safari <=5.0 and some android it's alert:

getIntersectionList: null
checkIntersection: true
elementFromPoint: [object SVGRectElement]

So, if you want to get better compatibility, only rely on the method:

var el = document.elementFromPoint(x,y);

it's get topmost element under the point (x,y), even support IE 5.5

You can test 5 points in a small rect area(center, 4 corner) (or more points), to workaround this.

查看更多
登录 后发表回答