Dungeoun Dungeoun - 1 month ago 5
CSS Question

Why 'keyup' event unable to make a change in CSS?

The mouseleave event is able to make CSS changes but when the ALT key is released, keyup event doesn't perform the CSS changes it's supposed to. Is it interfering with the mouseenter? if yes, then how to resolve the issue?



$(document).on('mouseleave', '.el', function(e) {
$(this).css("background-color", "white");
$(this).css("color", "black");

});

$(document).on('keyup', '.el', function(e) {
if (e.altKey) {
$(this).css("background-color", "white");
$(this).css("color", "black");

}
});

$(document).on('mouseenter keypress', '.el', function(e) {
if (e.altKey) {

$(this).css("background-color", "#99DCFC");
$(this).css("color", "red");

}

});

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="t1" align="center" border=1>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Email Address</th>
<th>Telephone Number</th>
</tr>
<tr id="r">
<tbody>
<td id="d1" class="el" contenteditable="true"></td>
<td id="d2" class="el" contenteditable="true"></td>
<td id="d3" class="el" contenteditable="true"></td>
<td id="d4" class="el" contenteditable="true"></td>
<td>
<button id="del1">Delete</button>
</td>
</tbody>
</tr>
</table>




Answer

There are two problems with your code:

  1. In the keyup event e.altKey will be false because the alt key was just released. Try testing the actual key code instead via e.which.

  2. Within the event handler, this will refer to the element that the event occurred for, which seems obvious except that that element isn't necessarily the one that the mouse is over: for a key event it will always be the element that has the (keyboard) focus at the time. The simplest fix for this is to use a class instead of setting CSS properties individually, because then you can just remove the class from whichever element currently has it by saying $(".highlight") rather than $(this). Therefore you also you don't want a delegated event handler for keyup, because the focus could be on none of the elements in question at the time.

$(document).on('mouseleave', '.el', function(e) {
  $(this).removeClass("highlight");
});

$(document).on('keyup', function(e) {
  if (e.which === 18) {
    $(".highlight").removeClass("highlight");
  }
});

$(document).on('mouseenter keypress', '.el', function(e) {
  if (e.altKey) {
    $(this).addClass("highlight");
  }
});
.highlight {
  background-color: #99DCFC;
  color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="t1" align="center" border=1>
  <tr>
    <th>First Name</th>
    <th>Last Name</th>
    <th>Email Address</th>
    <th>Telephone Number</th>
  </tr>
  <tr id="r">
    <tbody>
      <td id="d1" class="el" contenteditable="true"></td>
      <td id="d2" class="el" contenteditable="true"></td>
      <td id="d3" class="el" contenteditable="true"></td>
      <td id="d4" class="el" contenteditable="true"></td>
      <td>
        <button id="del1">Delete</button>
      </td>
    </tbody>
  </tr>
</table>

Note also that using a class to set the colours is neater than having to repeat colour codes in separate functions.

(I think the above is still a little buggy, but it should get you much closer to where you want to be.)

Comments