I am in dire need of help. I've spent over a week trying to figure out why I can't get this to work. I have a map in d3 with points overlaid. I want the user to be able to click the points and bring up a popup that will be scrollable. Then when user clicks off (anywhere on the body) I want the popup to disappear. The same is true for mouseover - show popup on mouseover, hide on mouseout.
Here’s the website : https://shmoss.github.io/Town_Sounds/#
My issue:
My code works absolutely fine on desktop, as well as my iphone 11. However, when testing on other iphones, if I open a popup, click off, and then re-click on another one, the popup is frozen. It doesn't scroll, i.e. it appears pointer events are disabled. Video at bottom.
Here's my code, tried to make as concise as possible:
//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)
})
Videos documenting the behavior:
An iphone 11 (same exact code, but working as expected):
https://www.youtube.com/watch?v=_3MA4bJYiYM
Other iphone 11 (same exact code, not working:)
https://www.youtube.com/watch?v=OfbboDnIw1E
What I've tried:
For some reason, using transform scale(0) with a duration of 200 ms works. As an alternative to the current method of opacity, this work. But it looks unprofessional and I'm baffled why the above code doesn't work universally. Thanks in advance!
from d3.js hiding popups with opacity not working properly with pointer events
No comments:
Post a Comment