d3.js 隐藏不透明度的弹出窗口不能与指针事件一起正常工作
Posted
技术标签:
【中文标题】d3.js 隐藏不透明度的弹出窗口不能与指针事件一起正常工作【英文标题】:d3.js hiding popups with opacity not working properly with pointer events 【发布时间】:2021-10-15 10:36:16 【问题描述】:我在 d3 中有一张地图,上面覆盖了点。我希望用户能够单击这些点并弹出一个可滚动的弹出窗口。然后当用户点击关闭(身体上的任何地方)时,我希望弹出窗口消失。鼠标悬停也是如此 - 鼠标悬停时显示弹出窗口,鼠标悬停时隐藏。
这是网站:https://shmoss.github.io/Town_Sounds/#
我的问题:
我的代码在桌面以及我的 iPhone 11 上运行良好。但是,在 其他 iPhone 上测试时,如果我打开一个弹出窗口,请单击关闭,然后重新单击另一个,弹出窗口被冻结。它不滚动,即似乎指针事件被禁用。底部有视频。
这是我的代码,尽量简洁:
//build d3 events (circles)
var events = mapG.selectAll("circle")
.data(eventArray)
.enter().append("circle")
.style("class", 'events')
.on("mouseover", function(d)
//add popup - set opacity to make visible
LeafletDiv.transition()
.duration(200)
.style("opacity", .9)
.style("scrollTop", 0)
var popInfo = '<br>' + d.Venue + '<br>'
LeafletDiv
.html(popInfo)
.style("top", "1.5vh")
.style("text-align", 'left')
//on-click event
.on("click", function(d)
$('body').css(
overflow: 'hidden'
);
//disable hover event listeners
d3.selectAll(".events").on("mouseout", null);
d3.selectAll(".events").on("mouseover", null);
//add popup
var value2014 = currentMap.get(d.location);
LeafletDiv.transition()
.duration(200)
.style("opacity", .9);
selections = d3.selectAll(".events").filter(function(d)
return d.Date == this_date
)
//populate html for popup
var appendText = []
selections.each(function(d)
var popInfo = '<br>' + d.Venue + '<br>'
appendText.push(popInfo+ '<br/>' + '<br/>')
)
//append html to popup
LeafletDiv
.html( appendText.join(""))
.style("top", "1.5vh")
.style("text-align", 'left')
.style("pointer-events", 'auto')
$('.county2014Tooltip').scrollTop(0);
d3.event.stopPropagation();
// if user clicks a SECOND time, anywhere, make popup disappear
d3.select("body").on("click", function(d)
console.log("clicking off popup")
//hide popup
var elements = d3.select(LeafletDiv)
elements.scrollTop = 0
LeafletDiv.transition()
.duration(200)
.style("opacity", 0)
.style("pointer-events", 'none')
.attr("scrollTop", 0)
//revert back to hover, unless user clicks again!
d3.selectAll(".events").on("mouseout", true);
d3.selectAll(".events").on("mouseover", true);
d3.selectAll(".events").on("mouseout", function(d)
//mousing out, hide popup!
LeafletDiv.transition()
.duration(200)
.style("opacity", 0);
)
// mouseover event listers added back in
d3.selectAll(".events").on("mouseover", function(d)
LeafletDiv.transition()
.duration(200)
.style("opacity", .9);
LeafletDiv .html('<br>' + d.Venue + '<br>'
)
.style("top", "1.5vh")
.style("text-align", 'left')
)
)
)
//on mouseout, hide popup
.on("mouseout", function(d)
LeafletDiv.transition()
.duration(200)
.style("opacity", 0)
.style("scrollTop", 0)
)
记录行为的视频:
一部 iPhone 11(完全相同的代码,但按预期工作):
https://www.youtube.com/watch?v=_3MA4bJYiYM
其他 iPhone 11(完全相同的代码,不工作:)
https://www.youtube.com/watch?v=OfbboDnIw1E
我的尝试:
出于某种原因,使用持续时间为200 ms
的转换scale(0)
有效。作为当前不透明度方法的替代方法,这项工作。但它看起来不专业,我很困惑为什么上面的代码不能通用。
【问题讨论】:
【参考方案1】:如果您使用 Leaflet 并且只需要圆圈和弹出窗口,则可以使用来自传单本身的 circleMarker 和弹出窗口。它可能比 d3 更容易实现。
https://leafletjs.com/reference-1.7.1.html#circlemarker
https://leafletjs.com/reference-1.7.1.html#popup
您可以使用 css 获得所需的所有样式/过渡。
【讨论】:
以上是关于d3.js 隐藏不透明度的弹出窗口不能与指针事件一起正常工作的主要内容,如果未能解决你的问题,请参考以下文章