How to override background-color on mouseup event

How to override background-color on mouseup event
0

#1

I have three “buttons” in my navigation.

What should occur:
Hover over “Offline” and that button turns blue.
Click “Offline” and that button turns green.
Click “All” button and that button turns green.
THEN the “Offline” button background-color should be cleared.

The Problem:
The last step does not occur. The “Offline” button remains green
when the “All” button is clicked.

View my Twitch app codepen to see what is happening.
Any help you can provide to fix this is greatly appreciated :slight_smile:


#2

The problem is in last line of your li mouseup event:

$('li').mouseup(function(){
    $('#offline').css('background-color', 'none');
    $('#online').css('background-color', 'none');
    $('#all').css('background-color', 'none');
    $(this).css('background-color', 'green'); 
    // the line above sets the background color of last clicked li to
    // green, so even after removing the "active" class, the in-line
    // styling is still in effect.
});

Just get rid of the last line and it should work fine.


#3

That will not have the effect that I am after if I remove the last line. I need to have the color to turn from blue to green on mouseup event and while still hovering over the newly clicked button (li element). I am beginning to think that it will not be possible to emulate that behavior but I am not sure…


#4

Let me think about it and get back with you.


#5

OK I think I have what you want.

In your JS code comment out the following:

$('li').mousedown(function(){
  $('li').css('pointer-events', 'none');
});
$('li').mouseup(function(){
  $('li').css('pointer-events', 'unset');
}); 

and in your css where you define li:hover, try changing/adding this:

li:hover, li:active {
    background-color:dodgerblue;
    color: #fff;
    border-radius: .5em;
    padding-bottom: .125em;
}

li:active {
    background-color:green;
}

EDIT: Almost forgot, in addition to the click event, you will also need to add mousedown to each of the #online, #offline, #all on event handlers. For example, the #online on event will now look like:

$('#online').on('click mousedown', function() {

#6

Sorry, it did not work. The hover works until I click either “Offline” or “All” button. When I click either of the buttons no changes in “view” of streamer data occur and the color of the buttons do not change. It seems this code inactivated my other event handlers from triggering.

EDIT: ok I will try adding the mousedown to the event handlers.


#7

Did you see the Edit in my last post?


#8

You did not comment out the code for the li mousedown and mouseup I mentioned in the previous post. Also, It looks like you added some more mouseup stuff. Get rid of all of the following:

$('li').mouseup(function(){
	$('#offline').css('background-color', 'none');
	$('#online').css('background-color', 'none');
	$('#all').css('background-color', 'none');
    $(this).css('background-color', 'green');
});

 // ADDED 20171011-1758
  
$('li').mousedown(function(){
  $('li').css('pointer-events', 'none');
});
$('li').mouseup(function(){
  $('li').css('pointer-events', 'unset');
});

#9

I added the mousedown to my .on(“click”) event handlers. I also commented out the following:

$('li').mouseup(function(){
	$('#offline').css('background-color', 'none');
	$('#online').css('background-color', 'none');
	$('#all').css('background-color', 'none');
    $(this).css('background-color', 'green');
});
 
$('li').mousedown(function(){
  $('li').css('pointer-events', 'none');
});
$('li').mouseup(function(){
  $('li').css('pointer-events', 'unset');
});

That did not fix the issue. The button remains blue after clicking the button while the mouse remains hovered over the button.


#10

If you look back at the code I posted earlier, you will see:

li:hover, li:active {
    background-color:dodgerblue;
    color: #fff;
    border-radius: .5em;
    padding-bottom: .125em;
}

li:active {
    background-color:green;
}

You ommitted the second part of:

li:active {
    background-color:green;
}

#11

added:

li:active {
    background-color:green;
}

li:active declaration only temporarily changes color while mouse button is in mousedown state then reverts back to normal upon mouseup . This is not working, the button remains blue after clicking button while still hovering over it.


#12

Question: In general, do you want all of the buttons to turn blue on mouse over (not clicking or mousedown or mouseup)? If so, then you are getting what you asked for.

After all the changes I suggested, you now can hover over any of the buttons and they turn blue. If you click on a button (while the mouse is held down), the button changes to green (which is the color you want it in general after you are not hovering over it). When you mouseup, the color button will turn blue, because you said on hover you want it to turn blue.

I guess I am not understanding what exactly you want to happen during hover, click, mousedown, and mouseup.


#13

I apologize for not clearly communicating what I was attempting to achieve. I’m going to try again.

Yes, I want the buttons to turn blue upon mouse over. That was solved prior to my original post with:

li:hover {
      background-color: dodgerblue;
}

The blue button should turn green after being clicked. I can do that with an event handler:

$('li').on('click', function() {
      // active class contains declaration of **background-color: green;**      
      $(this).addClass(active);
}

If the user clicks the web page button but does not move the mouse arrow outside of the web page button after clicking on it, the button stays blue. When that happens (when user clicks web page button but does move mouse after clicking it)… that blue button needs to turn green.

I do not want to require the user to have to move the mouse after clicking the web page button to see that the button underneath turns green. The clicked blue button should immediately turn green without having to move the mouse arrow. That is what I was trying to achieve with the following code:

// override the background-color set by li:hover declaration
// after lifting mouse button but WHILE still positioned over the li element
$('li').mouseup(function(){
	$('#offline').css('background-color', 'none');
	$('#online').css('background-color', 'none');
	$('#all').css('background-color', 'none');
    $(this).css('background-color', 'green');
});

#14

When the user clicks or holds down the mouse on button, the current code does turn the background-color of it to green. But because you put a hover pseudo-class on the li element, when you mouseup, the css hover effect will take over.

I am not an expert in CSS, so I can not offer a css solution, but I think you may have to remove the hover in the css and change all the colors via JavaScript. It is going to be more complex code, because of your criteria, but I think it is possible. I have gotten you to this point, but you will probably have to figure it out on your own or maybe someone who has implemented something like it before will reply to your topic.


#15

Thank you for your time and pointers. I will play around with removing the li:hover and doing it in javascript.


#16

I was able to fix this with some more javascript, .hover and strategically placed !important statement in my css.


#17

I just took your latest code and was able to replace your lines 107 thru 187 with the following 23 lines of code:

// MOUSEDOWN event handler    
$('li').on('mousedown', function() {
  $('.profile').addClass('hide'); 
  $('li').removeClass('active');
  var currentStatus = $(this)[0].id;
  $('#'+ currentStatus).addClass('active');
  if (currentStatus === 'all') {
    $('.online').removeClass('hide');
    $('.offline').removeClass('hide');
  }
  else
    $('.' + currentStatus).removeClass('hide');
});  

// MOUSEENTER event handler  
$('li').on('mouseenter mouseleave', function() {  
	$(this).toggleClass('hover');
});

// MOUSEUP event handler
$('li').on('mouseup', function() {
	$(this).addClass('active');
});  

#18

Hey, glad you solved your issue. There would be a kinda CSS-only solution for this that would require wrapping the text inside your <li>'s in anchors and using the :focus pseudo-class.

HTML

  <ul class="status">
      <li id="online"><a class="links" href="#">Online</a></li>
      <li id="offline"><a class="links" href="#">Offline</a></li>
      <li id="all"><a class="links" href="#">All</a></li>
  </ul>

CSS

ul li a {
  color:#000;
  padding:5px;
}
ul li a:focus, ul li a:hover {
  color:white;
}
ul li a:focus {
  background-color:green;
  outline:none;
}
ul li a:hover:not(:focus) {
  background-color:dodgerblue;
}

Only problem with this is that the buttons wouldn’t remain focused (because that’s how the :focus pseudo-class works).

There’s still a much more “dry” way of doing what you accomplished though. Which would be like so:

CSS

ul li.active {
  background-color:green;
}
ul li:hover:not(.active) { /* Blue only on hover and if it doesn't have an .active class */
  background-color:dodgerblue;
  border-radius: .5em;
}

JS

$('ul li').click(function(){
   $('ul li').removeClass('active'); // Remove active class from all <li>'s
   $(this).addClass('active'); // Add active class to the clicked one
});

// event handler: only show online users when user clicks online link
$('#online').click(function(){
	showAll();
	hideOffline();
});
// event handler: only show offline users when user clicks offline link
$('#offline').click(function(){
	showAll();
	hideOnline();
});
// event handler: show both online and offline users when user clicks all link
$('#all').click(function(){
	showAll();
});

All the others mouseup and mouseleave aren’t needed and the HTML would remain as you already have it.

EDIT: Didn’t notice @RandellDawson answer. You could combine both his and mine and have a very short and nice piece of code.


#19

The code is now cleaner. Thank you for the refactoring suggestions @RandellDawson and @noyb