Reputation: 2607
I have a button that is a rectangle and text and an invisible rectangle on top. The invisible rectangle helps make sure that a user can click anywhere on the button, including over the word PLAY
.
The invisible rectangle is preventing my .on("mouseover")
effect from working, which changes the color of the button.
This is my code -
// svg element
var ticker = d3.select("#ticker").select("svg")
.attr("width", 300)
.attr("height", 50);
// group for button elements
ticker = d3.select("#ticker").select("svg")
.attr("class", "ticker")
.attr("transform", "translate(0,0)")
.append("g")
// button with color
ticker.append("rect")
.attr("class", "pauseplay")
.attr("x", "120")
.attr("y", "0")
.attr("height","30")
.attr("width","100")
.attr("rx","5")
.style("fill","#FF5960")
.on("mouseover", function() { d3.select(this).style("fill", "#ff7b7b"); })
.on("mouseout", function() { d3.select(this).style("fill", "#FF5960"); })
// button text
ticker.append("text")
.attr("class","btn-text")
.attr("x","150")
.attr("y","20")
.text("PAUSE")
.style("fill","white")
// invisible button
ticker.append("rect")
.attr("class","play")
.attr("x", "120")
.attr("y", "0")
.attr("height","30")
.attr("width","100")
.style("opacity","0")
.on("click", function() {
PAUSED = !PAUSED;
t.stop();
// Play it.
if (!PAUSED) {
ticker.selectAll(".btn-text").text("PAUSE")
timer(); }
// Pause it.
else {
ticker.selectAll(".btn-text").text("PLAY")
} })
I'd like for the user to be able to hover anywhere, but also have the color change on mouseover.
Upvotes: 1
Views: 192
Reputation: 138
I think the easiest way would be to create a hover function trigerred by the invisible button (you have to add IDs) like for example :
ticker.append("rect")
.attr("class", "pauseplay")
.attr("id","myID")
.attr("x", "120")
.attr("y", "0")
.attr("height","30")
.attr("width","100")
.attr("rx","5")
.style("fill","#FF5960")
.on("mouseout", function() { d3.select(this).style("fill", "#FF5960"); })
// invisible button
ticker.append("rect")
.attr("class","play")
.attr("x", "120")
.attr("y", "0")
.attr("height","30")
.attr("width","100")
.style("opacity","0")
.on("mouseover", function() { d3.select("#myID").style("fill", "#ff7b7b"); })
.on("click", function() {
PAUSED = !PAUSED;
t.stop();
// Play it.
if (!PAUSED) {
ticker.selectAll(".btn-text").text("PAUSE")
timer(); }
// Pause it.
else {
ticker.selectAll(".btn-text").text("PLAY")
} })
Upvotes: 1
Reputation: 102188
You're bending over backwards, you don't need that invisible rectangle. Just set the text's pointer-events
to none
and add the event listener to the visible rectangle.
Here is your code with that change:
// svg element
var ticker = d3.select("#ticker").select("svg")
.attr("width", 300)
.attr("height", 50);
// group for button elements
ticker = d3.select("#ticker").select("svg")
.attr("class", "ticker")
.attr("transform", "translate(0,0)")
.append("g")
// button with color
ticker.append("rect")
.attr("class", "pauseplay")
.attr("x", "120")
.attr("y", "0")
.attr("height", "30")
.attr("width", "100")
.attr("rx", "5")
.style("fill", "#FF5960")
.on("mouseover", function() {
d3.select(this).style("fill", "#ff7b7b");
})
.on("mouseout", function() {
d3.select(this).style("fill", "#FF5960");
})
.on("click", function() {
console.log("click")
})
// button text
ticker.append("text")
.attr("class", "btn-text")
.attr("x", "150")
.attr("y", "20")
.text("PAUSE")
.style("fill", "white")
.attr("pointer-events", "none");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="ticker">
<svg></svg>
</div>
Upvotes: 2