Reputation: 15
This is my js code. I am trying to make a TicTacToe game. When a player hovers over a table cell, they will see either an "x" or an "o" marker in that cell with 50% opacity. When they click on the table cell, they will see a marker in that cell with 100% opacity. When I hover on a cell that has been clicked, it continues to apply the hover event. How can I turn the hover event off after I have clicked, while maintaining the cell's new opacity? The goal of my function is to be able to hover over a table cell and temporarily see a 50% opaque marker and to be able to click on a table cell and permanently see a 100% opaque marker. Pictures https://i.sstatic.net/MHWH6.jpg
Note: I tried including a .off function at the end of my click event.
$(this).off("mouseenter mouseleave);
This does not solve my issue.
$(".tableCell").hover(function(){
$(this).children(".tableCellMarker").attr("src", function(index, attr){
return attr.replace("", "images/X.png");
});
}, function(){
$(this).children(".tableCellMarker").attr("src", function(index, attr){
return attr.replace("images/X.png", "");
});
});
$(".tableCell").click(function(){
$(this).children(".tableCellMarker").attr("src", function(index, attr){
return attr.replace("","images/X.png");
});
$(this).children(".tableCellMarker").css("opacity",1);
$(this).addClass("marked");
});
Here is the css for .tableCellMarker
.marker {
cursor:pointer;
margin:-80px 0px 150px 50px;
opacity:0.5;
position:absolute;
}
Upvotes: 1
Views: 6184
Reputation: 10924
I think handling this through CSS specificity as suggested in epascarello's answer is probably the best approach. However, if you do want to handle the hover events in code rather than CSS, you can combine event delegation and the :not()
selector to dynamically control the display state.
$(".grid").on("click", ".tableCell", function() {
//when clicking, toggle selection state and remove hover state
$(this).removeClass("hovered");
$(this).toggleClass("selected");
}).on("mouseenter", ".tableCell:not(.selected)", function() {
//only if not selected, add hover state
$(this).addClass("hovered");
}).on("mouseleave", ".tableCell", function() {
//whenever leaving, it's always safe to remove hover state
$(this).removeClass("hovered");
});
.grid {
border: 1px solid black;
}
.grid td {
width: 50px;
height: 50px;
border: 1px solid black;
}
.selected {
background-color: green;
}
.hovered {
background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table class="grid">
<tr>
<td class="tableCell"></td>
<td class="tableCell"></td>
<td class="tableCell"></td>
</tr>
<tr>
<td class="tableCell"></td>
<td class="tableCell"></td>
<td class="tableCell"></td>
</tr>
<tr>
<td class="tableCell"></td>
<td class="tableCell"></td>
<td class="tableCell"></td>
</tr>
</table>
Upvotes: 0
Reputation: 207501
It would be so much easier if you used classes and use CSS Specificity to deal with the states.
$("table tbody").on("click", "td", function() {
$(this).toggleClass("selected");
});
table {
border-collapse: collapse;
width: 200px;
height: 200px;
}
td {
border: 1px solid black;
text-align: center;
background-color: white;
}
td:hover {
background-color: yellow;
}
td.selected, td.selected:hover {
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>4</td>
<td>5</td>
<td>6</td>
</tr>
<tr>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
</tbody>
</table>
Now how can we apply it to tic tac toe? Add more css classes and a little bit of logic.
var turn = true; //determines x (true) and o (false)
$(".game tbody").on("click", "td", function() { //bind click to cell
var cell = $(this); //get cell that was clicked
if (cell.hasClass("selected")) return; //if cell was selected than ignore click
$(this)
.addClass("selected") //mark cell as selected
.addClass(turn?"x":"o"); //set the class based on turn
turn = !turn; //toggle player
$(".game").toggleClass("x o"); //toggle whose turn it is (so hover is different)
});
table {
border-collapse: collapse;
width: 200px;
height: 200px;
}
td {
border: 1px solid black;
text-align: center;
background-color: white;
}
.x td:hover {
background-color: #ABEBC6;
}
.o td:hover {
background-color: #F5B7B1;
}
td.x, td.x:hover {
background-color: #239B56;
}
td.o, td.o:hover {
background-color: #B03A2E;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table class="game x">
<tbody>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>4</td>
<td>5</td>
<td>6</td>
</tr>
<tr>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
</tbody>
</table>
Upvotes: 4
Reputation: 788
You can use the jQuery .unbind() event to do this.
jQuery(function($) {
$('.foo').on('mouseenter', function(e) {
$(this).text('hover');
});
$('.foo').on('mouseleave', function(e) {
$(this).text('');
});
$('.foo').on('click', function(e) {
$('.foo').unbind('mouseenter');
});
});
.foo {
border: 1px solid #000;
text-align: center;
line-height: 200px;
height: 200px;
width: 200px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="foo"></div>
Upvotes: -1
Reputation: 5637
Try to organize your table cells by some attribute or class "hasClicked" and "unClicked". Then, only apply the hover ever for the "unClicked".
So, let's say you start off by giving each table cell a class called hasNotBeenClickedYet
. Whenever we hover over an element that has the class hasNotBeenClickedYet
, we want to do your hover action.
When one of these has been clicked, we want to remove the hasNotBeenClickedYet
from that cell, so it no longer has the hover action.
So we'd want to change
$(".tableCell").hover(function(){
...
}
to something like
$(".hasNotBeenClickedYet").hover(function(){
...
}
and remove that class when it's been clicked
$(".hasNotBeenClickedYet").click(function(){
$(".hasNotBeenClickedYet").removeClass("hasNotBeenClickedYet");
...
}
Upvotes: 0