SVG元素在Chrome中未收到onclick [英] SVG element not receiving onclick in Chrome

查看:161
本文介绍了SVG元素在Chrome中未收到onclick的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为Chrome版本66.0.3359.139(最终可能还有其他版本)编写一个javascript应用程序.我正在尝试使可单击的SVG元素.也就是说,点击它们的onclick方法时应调用它们.

这是我的第一次尝试:

 <html><body style="margin:0;overflow:hidden">
<svg id="svg" width="100%" height="100%"></svg>
<script>

let svg  = document.getElementById("svg");

function clear()
{
    svg.innerHTML = '';
}

function circle(p, r)
{
    let e = document.createElementNS(svg.namespaceURI, 'circle');
    e.setAttribute('cx', p.x);
    e.setAttribute('cy', p.y);
    e.setAttribute('r', r);
    svg.appendChild(e);
    return e;
}


onresize = function()
{
    clear();
    let r = svg.getBoundingClientRect();
    c1 = circle({x: r.x + r.width/2, y:r.y + r.height - 20}, 10);
    c2 = circle({x: r.x + r.width/2, y:20}, 10);
    c1.onclick = function(){svg.removeChild(c1);}
    c2.onclick = function(){svg.removeChild(c2);}
}
onresize();

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

此代码在页面顶部创建一个圆圈,在页面底部创建一个圆圈.页面调整大小时,圆圈也会重新计算,因此它们始终可见.作为测试,我想在单击圆圈时将其删除.

有时上述代码有效.但是,当我全屏运行它时,在打开窗口底部的开发人员工具,然后关闭开发人员工具之后,将无法单击底部的圆圈,直到下一次我缩放或调整窗口大小./p>

我认为这可能是浏览器错误,因为如上所述,当我使用开发人员工具时会显示该错误,而在Firefox中根本不会出现.但是后来我注意到其他网站没有这个问题.此外,要找到浏览器错误并非易事,因为许多网站都可以在Chrome浏览器中工作.

有人看到我的Javascript代码有问题,可能导致最下面的圈子无法接收onclick事件吗?

更新

我无法在Chrome版本74.0.3729.169 Linux或Windows中重现此问题.它可能特定于Linux chrome版本66.0.3359.139.

但是,这仍然并不意味着它是浏览器错误……代码是否应该正常工作?

更新

在Linux Chrome版本66.0.3359.181中也可以重现该问题.我很难降级到66.0.3359.139(我找不到详细信息.谷歌可能会烦人).所以我现在的目标是66.0.3359.181.

更新

当前问题似乎是由

引起的

<body style="margin:0">

如果删除了该样式,则不会发生当前问题,但是

的唯一缺点是svg关闭了1个像素,并且出现了多余的滚动条.请注意:

<body style="margin:1;overflow:hidden">

删除滚动条并重新引入该错误.

因此overflow:hiddenmargin:0都会导致此问题.这些都将删除滚动条.因此,问题与没有滚动条(无论如何删除)有关.

解决方案

@kaiido是正确的,这里的问题与浏览器相关,因为原始代码发布功能可以实现现代浏览器中的功能.

建议OP查看 canIuse 可以确定其当前浏览器在使用svg时所支持的内容


在此留下我不正确的(针对此问题)和最终不必要的d3.js示例,以证明我愿意在错了并且完全误读了一个问题时才接受它.

let myCircles = [
   { "x_axis": 30, "y_axis": 30, "radius": 20, "color" : "green" },
   { "x_axis": 70, "y_axis": 70, "radius": 20, "color" : "purple"},
   { "x_axis": 110, "y_axis": 100, "radius": 20, "color" : "red"}];



function onresize()
{
    clear();
   let circles = d3.select("svg")
     .selectAll("circle")
     .data(myCircles).enter()
     .append("circle");

   let attributes = circles
     .attr("cx", function (d) { return d.x_axis; })
     .attr("cy", function (d) { return d.y_axis; })
     .attr("r", function (d) { return d.radius; })
     .attr("id", function(d, i){ return 'c' + i; })  
     .attr('onclick',function(d, i){ return 'c' + i; })   
     .style("fill", function(d) { return d.color; });  
}

onresize()


为清晰起见

可以说这是> D3:如何删除形状的副本发生点击事件?

但是我认为,被投票赞成的答案会以非d3规范的方式迭代项目名称.

属性中的回调是第一个输入是数据",第二个输入是位置索引,与使用外部声明的变量进行设置相比,该位置索引更忠实于d3的设计. .attr('onclick',function(d,i){return'c'+ i;})

I am writing a javascript application for Chrome Version 66.0.3359.139 (and maybe other versions eventually). I am trying to make SVG elements that are clickable. I.e., their onclick methods should be called when they are clicked.

Here is my first attempt:

<html><body style="margin:0;overflow:hidden">
<svg id="svg" width="100%" height="100%"></svg>
<script>

let svg  = document.getElementById("svg");

function clear()
{
    svg.innerHTML = '';
}

function circle(p, r)
{
    let e = document.createElementNS(svg.namespaceURI, 'circle');
    e.setAttribute('cx', p.x);
    e.setAttribute('cy', p.y);
    e.setAttribute('r', r);
    svg.appendChild(e);
    return e;
}


onresize = function()
{
    clear();
    let r = svg.getBoundingClientRect();
    c1 = circle({x: r.x + r.width/2, y:r.y + r.height - 20}, 10);
    c2 = circle({x: r.x + r.width/2, y:20}, 10);
    c1.onclick = function(){svg.removeChild(c1);}
    c2.onclick = function(){svg.removeChild(c2);}
}
onresize();

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

This code creates one circle at the top of the page, and one at the bottom. The circles are also recalculated when the page resizes, so that they are always visible. As a test, I want to delete the circle when it is clicked.

Sometimes the above code works. However, when I run it full screen, after opening developer tools at the bottom of the window, and then closing the developer tools, then the bottom circle cannot be clicked -- until after the next time I either zoom or resize the window.

I thought maybe it was a browser bug because it shows up when I use developer tools as described above, and does not occur at all in Firefox. However then I noticed that other websites do not have this problem. Besides it can't be that easy to find a browser bug, as so many sites work in Chrome.

Does anyone see a problem with my Javascript code that could be making the bottom circle fail to receive onclick events?

update

I cannot reproduce this problem in Chrome Version 74.0.3729.169 Linux or Windows. It may be specific to Linux chrome Version 66.0.3359.139.

However, that still doesn't mean it's a browser bug... should the code work or not?

update

The problem is also reproducible in Linux Chrome Version 66.0.3359.181. I am having difficulty downgrading to 66.0.3359.139 (I can't find the deb. Google can be annoying that way). So I am now targeting 66.0.3359.181.

update

The present problem seems to be caused by

<body style="margin:0">

If that style is removed, then the present problem does not occur, but another problem occurs. The present problem occurs equally with:

<style>
html, body, * { 
     margin: 0; 
     padding: 0; 
}
</style>

This is the case both in my version and the D3 version posted by Dataminion.

So we really have a lump under the rug here... we can step on it but it causes a lump somewhere else. Solve the events, but then SVG can't fill the page. Solve both of the above, but upgrade browser (and deal with a new set of bugs).

update

It works with

<body style="margin:1">

with the only drawbacks being the svg is 1 pixel off, and there is an unwanted scrollbar. Note that:

<body style="margin:1;overflow:hidden">

removes the scrollbar and reintroduces the bug.

So either overflow:hidden or margin:0 causes the problem. Either of these removes the scrollbar. So the problem is related to there not being a scrollbar (regardless of how it is removed).

解决方案

@kaiido is correct the issue here is browser related as the original code posted functions as expected in modern browsers.

Suggest OP look at canIuse do identify what their current browser supports when it comes to svg


Leaving my incorrect(for this question) and ultimately unnecessary d3.js example here as proof that I am willing to admit it when I am wrong and totally misread a question.

let myCircles = [
   { "x_axis": 30, "y_axis": 30, "radius": 20, "color" : "green" },
   { "x_axis": 70, "y_axis": 70, "radius": 20, "color" : "purple"},
   { "x_axis": 110, "y_axis": 100, "radius": 20, "color" : "red"}];



function onresize()
{
    clear();
   let circles = d3.select("svg")
     .selectAll("circle")
     .data(myCircles).enter()
     .append("circle");

   let attributes = circles
     .attr("cx", function (d) { return d.x_axis; })
     .attr("cy", function (d) { return d.y_axis; })
     .attr("r", function (d) { return d.radius; })
     .attr("id", function(d, i){ return 'c' + i; })  
     .attr('onclick',function(d, i){ return 'c' + i; })   
     .style("fill", function(d) { return d.color; });  
}

onresize()


Edit for clarity

It could be said that this is a duplicate of D3: How delete shape on click event?

However I would argue that the upvoted answer iterates the item name in a non d3 canonical way.

A callback in an attribute is the where the first input is the "data" and the second is the positional index is more faithful to the design of d3 than to use an externally declared variable to set it. .attr('onclick',function(d, i){ return 'c' + i; })

这篇关于SVG元素在Chrome中未收到onclick的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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