Javascript onClick and onmouseover and onmouseOut - javascript

I would like to ask how to differentiate between onClick and onMouseOver and onMouseOut.
For instance,
I use onMouseOver to change the tab background to grey using
onMouseOver="this.style.backgroundColor=Blue;"
onMouseOut takes away this background
onMouseOut="this.style.backgroundColor=White;"
How do I write a call for onClick that gives a blue background and keeps it there even when the mouse cursor moves away from the tab?
Thanks

How about you have two CSS classes, "active" and "clicked". They both set the background to blue. On click, you add the "clicked" class. On mouse over, you add the "active" class. On mouse out, you remove the "active" class. If the element had the "clicked" class it'd still have it, and hence keep its color.

You need to work with event listeners. I recommend using a framework for this, like prototypejs or jquery.
You will need event listeners / observers for observing the mouseOver, mouseOut and click events. When your click event fires, you stop observing for mouseOver and mouseOut. This should do the trick.

I would do a check in the MouseOut that only changes the color if it's not already blue.

Normally I would add a CSS class to the element which has the active (last clicked on item) state. That CSS class can have priority over the normal styling of the element.
I would even use CSS and not JavaScript for hover state changes.

Very simple solution is here for your help. Hope it works for you.
<script type="text/javascript">
function row_mout(mout_value) {
document.getElementById(mout_value).style.background = "#FFFFFF";
}
function row_mover(mover_value){
document.getElementById(mover_value).style.background = "#123456";
}
function row_click(click_value) {
if(document.getElementById('chk_'+click_value).checked == true){
document.getElementById(click_value).style.background = "#123456";
document.getElementById(click_value).onmouseout = "";
document.getElementById(click_value).onmouseover = "";
}//if over
else if(document.getElementById('chk_'+click_value).checked == false){
document.getElementById(click_value).style.background = "#FFFFFF";
document.getElementById(click_value).onmouseout = function onmouseout(event){
row_mout(click_value);
}
document.getElementById(click_value).onmouseover = function onmouseover(event){
row_mover(click_value);
}
}//else if over
}

Related

Simplifying Active States

I have a question that I believe comes down to method preference.
In the following code when the div parent element is clicked on, the div itself expands and also triggers an icon animation
var slideSection6 = document.getElementById("manualsHandbooks").addEventListener("click", function()
{
if (this.parentElement.style.height == "60px" || this.parentElement.style.height == "")
{
this.parentElement.style.height = "215px";
document.getElementById("MAHB").classList.add("active");
}
else
{
this.parentElement.style.height = "60px";
document.getElementById("MAHB").classList.remove("active");
}
}, false);
I was thinking about how easy it was just to add a class and change the state of the icon and I wanted to experiment and try adding the another click event just to the icon to make it animate on a click and active the parent element in the div as well. Basically the reverse of the above.
I thought it would be as simple as adding another condition to the if statement to the effect of
|| document.getElementId("MAHB").classList.add=("active") == true
But this doesn't work and I know it's not proper form. Could someone get me started so I could figure this out?
Element.classList has a toggle method that could make things a bit easier. If you want to check if a certain class is present, you can also use classList.contains.
I'd suggest not using the height of your elements to determine their current state. Why don't you alter the height using an active css class?
Your click handler could then be:
var button = document.getElementById("manualsHandbooks");
button.addEventListener("click", function() {
this.parentElement.classList.toggle("active");
document.getElementById("MAHB").classList.toggle("active");
}, false);
You can read more about classList here: https://developer.mozilla.org/en-US/docs/Web/API/Element/classList

change div class onclick on another div, and change back on body click

Let me define the problem a little bit more:
i have
<div class="contact">
<div id="form"></div>
<div id="icon"></div>
</div>
i want onclick on #icon, to change the class of .contact to .contactexpand( or just append it).
Then i want that the on body click to change the class back, but of course that shouldnt happen when clicking on the new class .contactexpand, and if possible that clicking on icon again changes the class back again.
I tried numerous examples and combinations but just couldn't get the right result and behavior.
Check this: Working example
Let's go step by step
I want onclick on #icon, to change the class of .contact to .contactexpand( or just append it). […] and if possible that clicking on icon again changes the class back again.
You want to use the toggleClass() method to achieve this. Simply:
$('#icon').on('click', function(e){
$(this).parent()
.toggleClass('contact')
.toggleClass('contactexpand');
});
Then i want that the on body click to change the class back
You will have to make sure that body removes contactexpand class and adds contact. At this point I would just give the container element an id (or class if you prefer), just to make things simpler. Then what you do is pretty simple:
$('body').on('click', function(e){
$('#thisdiv')
.removeClass('contactexpand')
.addClass('contact');
});
but of course that shouldnt happen when clicking on the new class .contactexpand.
This is the step that the other answers missed, I think. Since everywhere you click, you also click on the body element, you will always trigger the click event on the body, hence removing the contactexpand class and adding the contact one.
Enter event.stopPropagation(). This method will make sure that the events doesn't bubble up the DOM, and will not trigger the body click.
$('#thisdiv').on('click', function(e){
e.stopPropagation();
});
Working example
You can add a class to parent element like the following code.
$(".contact #icon").click(function(){
var element = $(this).parent(".contact");
element.removeClass("contact").addClass("contactexpand");
});
I like to the jQuerys toggleClass function like so:
$('#icon').click(function(){
$('#contactbox').toggleClass('contact');
$('#contactbox').toggleClass('contactexpand');
});
Or you could use addClass('className') and removerClass('className') if you would like to apend it rather than toggle it :)
Here is an example: http://jsfiddle.net/aUUkL/
You can also add an onclick event to the body of the page and use hasClass('className') to see whether or not to toggle the class when the body is clicked. You could use something like this (Although I havent tested this bit!):
$('body').click(function(){
if( $('#contactbox').hasClass('contactexpand') ){
$('#contactbox').addClass('contact');
$('#contactbox').removeClass('contactexpand');
}
});
You can do this
$('body').on('click', function(event) {
if ($(event.target).attr('id') == 'icon') {
$(event.target).parent().toggleClass('contactexpand');
} else {
$('.contact').removeClass('contactexpand');
}
});
Check out this jsfiddle
var $contact = $('.contact');
$contact.find('#icon').click(function(e, hide) {
e.stopPropagation();
$contact[hide ? 'removeClass' : 'toggleClass']('contactexpand');
});
$(document).on('click', function(e) {
if (e.srcElement === $contact[0]) return;
$contact.find('#icon').trigger('click', true);
});
http://jsfiddle.net/kZkuH/2/

jQuery and modifiying a class

I have the following and it works as it lets me control the the background color of a button. However, I do not have any control over when the button is hovered on.
popUpDialog.parent().find('button:contains("Save")').addClass('gb').removeClass('ui-state-default');
popUpDialog.parent().find('button:contains("Save")').addClass('gb').removeClass('ui-state-hover');
Is there a way to modify the hover class or effect what happens to the button when it gets a hover?
Try the following.
$(function(){
var button = popUpDialog.parent().find('button:contains("Save")');
button.addClass('gb')
.hover(function(){
$(this).removeClass(''ui-state-hover'');
}, function(){
$(this).removeClass(''ui-state-default');
});
});
You can unbind the hover event for the button which will keep the class from being added in the first place:
popUpDialog.parent().find('button:contains("Save")').unbind('mouseenter').unbind('mouseleave')

Is there a way to detect mouse press in jQuery?

I want to add a class to a link when it is clicked, but I can't use:
$('a.someLink').click(function() {
// code
});
since click seems to detect when a user clicks and lets go of the mouse clicker on an element. I need to add the class as soon as the user has clicked on the element, even before he lets ago of the mouse clicker and after he lets go I need the class to be removed.
Basically I'm trying to mimic css's active state on links:
a:active
How can this be done?
mousedown() would be what you are looking for in the jQuery docs
You can use $('a.someLink').mousedown(function() { //code }); instead
$('a.someLink').mousedown(function() {
//code
});
http://api.jquery.com/mousedown/
With $('a.someLink').mousedown() you can add the class, and then with $('a.someLink').mouseup() you can remove it.
mousedow(): http://api.jquery.com/mousedown/
mouseup(): http://api.jquery.com/mouseup/
Try mousedown which is triggered even before click event.
$('a.someLink').mousedown(function() {
// code
});

Internet Explorer and <select> tag problem

I am having the following problem under Internet Explorer 7/8:
I have a popup that gets activated when user mouseover a link. The popup is a simple <div> that contains some data. Inside this <div> tag there is a <select> tag with some <option>s. I have attached mouseover/mouseout events to the <div>, so that this popup will stay open while cursor is over it. The problem comes when you click on the <select> and then move the cursor over any of the <option>s. This triggers the mouseout event of the <div> tag and respectively closes it.
How can I prevent the closing of the popup in IE ?
You should be able to detect if the situation is the one you want just with the values off the event. It is a little convoluted but it seems to work.
In the event handler of your outer div, do something like this:
<div onmouseover="if (isReal()) { toggle(); }"
onmouseout="if (isReal()) { toggle(); }">
</div>
Then implement the isReal method:
function isReal() {
var evt = window.event;
if (!evt) {
return true;
}
var el;
if (evt.type === "mouseout") {
el = evt.toElement;
} else if (evt.type === "mouseover") {
el = evt.fromElement;
}
if (!el) {
return false;
}
while (el) {
if (el === evt.srcElement) {
return false;
}
el = el.parentNode;
}
return true;
}
Basically the isReal method just detects if the event was coming from within the div. If so, then it returns false which avoids calling the hide toggle.
My suggestion would be to set another flag while the select box has focus. Do not close the div while the flag is set.
How about re-showing the div when the mouse is over the <options>s through mouseover events of <options>s.
Edit: execution order of mouseover of option and mouseout of div might cause problems though.
In the mouseout event for the div add a timeout to the div element that will hide the div in 200 milliseconds or so.
Then in the mouseover event for the div/select and the click event of the select clear the timeout stored in the div element.
This gives a very slight delay before hiding the div that allows the mouseover or click events to clear the timeout before it is executed. It's not pretty but it should work.
instead of using mouseout as the event to close the div, use mouseleave, then the event will only be triggered when the pointer leaves the boundary of the div, not when it moves onto other elements within it
you could try adding another mouseover event specifically for the options list.
Well, the reason for this behavior is because the mouseover/out events bubble, which effectively means that whenever you mouseover any of the elements inside the popup, the popup receives the event also.
You can read more here about these events, and here about event bubbling.
You have 3 possible solutions here:
Change the events to onmouseenter/leave. You've mentioned that this didn't help, which just sounds plain odd, since these aren't supposed to bubble.
Check srcElement in relation to from/toElement in the event.
An improved version of McKAMEY's check would be:
function isReal() {
var evt = window.event;
if (!evt) {
return true;
}
var el;
if (evt.type === "mouseout") {
el = evt.toElement;
} else if (evt.type === "mouseover") {
el = evt.fromElement;
}
if (!el) {
return false;
}
// this will also return true if el == evt.srcElement
return evt.srcElement.contains(el);
}
Does the same thing, just shorter.
3 . Another option would be to create a transparent, invisible div just under your popup that covers the area that the select box drops down into. I'm assuming that it's dropping outside the actual area of the popup.
Hope this helps!
have you tried hover instead of mouseover/out effects?
$(".myDiv").hover(function(){
$(this).show();
}, function {
$(this).hide();
});
What about something like this:
<div id="trigger">
Hover over me!
</div>
<div class="container">
<select>
<option>Blah</option>
<option>Blah</option>
</select>
</div>
$("#trigger").mouseover(function(){
$('.container).show();
});
$(".container").mouseleave(function(){
$(this).hide();
});
The basic idea is that you show the container element when you hover over the trigger then when you leave the container you hide the container. You'd need to position the container so it clipped the trigger element, otherwise it would hide straight away.
Why have mouseover / mouseout on the <div>? Why not just show the <div> on the mouse over, then set <body onmouseover="hidedivs();"> I don't know if this would work, but if the <div> is on top of the body, then the <div> should stay visible.
Many people posting solutions/examples do not seem to realize one thing: onmouseout event on <div> fires before onmouseover event on <select>.
When <div> loses focus (onmouseout) do not close it immediately, but after say, 500 milliseconds. If during this time <select> gets focus (mouseover) do not close <div> at all (clearTimeout).
Also, try to play with event propagation/bubling.
Given that selects in IE are a pain, especially when it comes to the whole layering issue where a select appears above a div even though it shouldn't, can I point you in the direction of YUI's Menu button controls. They look really nice, are easy to implement and won't cause this issue
Here is a link: http://developer.yahoo.com/yui/examples/button/btn_example07.html
You should use event.stopPropagation() while in <select>, or cancelBubble() in <select> element itself.

Categories

Resources