Javascript eventListeners not firing - javascript

I am trying to get all buttons to do the same on click like the first button does.
Basically, it's just calling a function on click.
That function changes the innerHtml of the target div, adds a Css animation class, then removes the Css animation on mouseout.
This works exactly how i want it to on the first button, but not one the second and last.
function declaration() {
document.getElementById("me").innerHTML = "I am a function declaration and i
hoist to the top of the code, you
can call me before i get
declared.I look like this: < br > function declaration() {}
";
document.getElementById("me")
.classList.add("slideIt");
document.getElementById("fnDeclaration")
.addEventListener('mouseout', function() {
document.getElementById("me")
.classList.remove("slideIt");
});
}
document.getElementById("fnDeclaration").addEventListener("click", function() {
declaration();
});
http://codepen.io/damianocel/pen/xwJmwN
Why is this (not) happening?

Your content div (#me) is set-up last in the HTML (hence in DOM), so it sits on top of your buttons when sliding down.
Therefore you actually mouseout from your button as soon as the sliding down animation starts, which as per your code removes the slideIt class, hence stops the animation.
A quick fix could simply be to push your content div down below (z-index-wise) your buttons: #me {z-index: -10;}
Demo: http://codepen.io/anon/pen/vNvqYx

Related

Why can't jquery remove these classes?

I have created a series of elements that when you click on any one of them, they will expand, pushing the other elements out of the way. Initially if you clicked on it again the element would contract, but now I want to take the close functionality and put it in a button with in the element.
Initially when you click on the element, I use jQuery to add a number of classes to a variety of elements.
$(".left > .elem").click(function () {
$(this).addClass("expand");
$(this).parent().addClass("WithLarge");
$(this).children(".bar").addClass("visible");
$(this).children(".reduce_button").addClass("visible");
$(".right").addClass("shift_right");
});
When I click the close button I would like to remove those classes.
$(".reduce_button").click(function () {
$(this).parent().removeClass('expand');
$(this).parent().removeClass("WithLarge");
$(this).parent().children(".bar").removeClass("visible");
$(this).parent().children(".reduce_button").removeClass("visible");
}
The problem is, those classes aren't budging.
You can try it out on the JSFiddle
Click on the yellow box(".left > .elem"), it expands pushing the others out of the way, click on the red box(".reduce_button"), and nothing happens. I tried
console.log($(this).parent().hasClass('expand'));
$(this).parent().removeClass('expand');
console.log($(this).parent().hasClass('expand'));
to see if it has been removed. It returns false, even though the class is still there.
Why can't I remove these classes?
You ARE removing the class. But, the click on the .reduce_button is also triggering the .elem click event, which adds the class back again.
EDIT:
As commented below by j08691, you can add stopPropagation to keep the event of going on to the next listener, like:
$(".reduce_button").click(function (e) {
$(this).parent().removeClass('expand');
e.stopPropagation();
...
Here is your fiddle updated: http://jsfiddle.net/HybHK/9/

Strange lag which disappears by clicking anywhere on the html body

I have some overlay elements which are display: none initially but turn to display: inline when I hover over specific items on the page, and disappear again when the mouse hovers over something else. Exactly same behavior as tool-tips with the difference that this overlay objects have clickable and interactive elements (such as a jquery accordion).
Everything works perfectly, until I interact with these overlay elements, i.e. click on one of the clickable items in the overlay element. Then, once that overlay item becomes display:none again, the page becomes extremely laggy in terms of how long it takes when I hover over an item to find its corresponding overlay element (they are selected by their id) and for it to appear and disappear.
The strange thing is that if I click anywhere on the html body, the lag disappears and everything becomes fast as in the beginning.
Out of despair, I have tried to programmatically call blur, focus, trigger('click') once the overlay element is set back to display:none but none has helped so far, and I have to manually click on the page for the lag to go away.
Any idea what causes such behavior and how I can fix it? thanks,
Edit: code
CSS part:
span.overlay {
z-index:10;
display:none;
position:absolute;
}
span.visible { display:inline; }
HTML part: lots of such span elements, each with their own unique id.
<span class='overlay ui-widget-content' id='xyz'>
<!-- lots of stuff here -->
</span>
javascript part:
/* displays overlay element when user hovers over the first td */
$('table.foo > tbody > tr > td:first-child').hover(
function(e) {
$(this).parent().tooltip('disable');
var elem = $('#' + $(this).parent().data('overlay-id'));
if (!elem.hasClass('visible')) {
elem.css('left', e.pageX + 20).css('top', e.pageY).addClass('visible');
elem.find('.accordion:first').accordion('refresh');
}
}, function() {
var elem = $('#' + $(this).parent().data('overlay-id'));
if (! elem.is(':hover') && ! elem.hasClass('pin')) {
$(elem).removeClass('visible');
}
$(this).parent().tooltip('enable');
});
/* if mouse leaves span.visible and it is not pinned it will hide the span */
$('body').on('mouseleave', 'span.visible',
function() {
if (!$(this).hasClass('pin')) {
$(this).removeClass('visible');
}
});
Edit: profiling the code, it seems that get offsetHeight and get offsetWidth take way longer than before. Yet I do not know why this should happen and why it should go away by clicking on the page.
previously, when I do not observe the problem, these two functions each take less than 3%.
try binding the mouseleave event upon opening the "tooltip". Replace your code with this (not tested):
/* displays overlay element when user hovers over the first td */
$('table.foo > tbody > tr > td:first-child').on('mouseenter',
function(e) {
$(this).parent().tooltip('disable');
var elem = $('#' + $(this).parent().data('overlay-id'));
if (!elem.hasClass('visible')) {
elem.css('left', e.pageX + 20).css('top', e.pageY).addClass('visible');
elem.find('.accordion:first').accordion('refresh');
// notice the "ONE" handler, it'll unbind the event after execution
elem.one('mouseleave', function() {
if (!$(this).hasClass('pin')) {
$(this).removeClass('visible');
}
$(this).parent().tooltip('enable');
});
}
}
);
Notice the one listener to unbind the event after it's first execution.
I can't guarantee that this will fix your issue but I experienced lots of performance hits when a page has A LOT of elements and browsers need to check hover events that change very quickly.
This way the browser only needs to check one mouseleave event. And if it happened, it's gone again. It seems you may have too many bound events and don't clean them up properly.
I'm not sure if I replicated your desired functionality correctly so please add code if I missed something. I was unsure why exactly you'd need to bind a mouseleave event via body AND via .hover().

change cursor property with javascript

i have coded a simple javascipt that when the user clicks sth, to do some stuff. I also want that the cursor to be changed, so i added this
<script>
$(document).ready(function() {
$(".targetClass").click(function () {
$('#loaderImage').show();
//this is the line i add
$('.container').css('cursor','wait');
});
});
</script>
And it works. But if i take the cursor on a link the cursor will change again to "pointer" value. What i have to do so the cursor, after the click remain to wait value (even i put it on any element of the page)? Thx!!
here is the solution to your problem.
create a class with pointer wait and add it to button/link also while clicking on it.
$(document).ready(function() {
$(".targetClass").click(function () {
//$('#loaderImage').show();
//this is the line i add
$('.container').css('cursor','wait');
$(this).addClass('cursor');
});
});
.cursor{
cursor:wait;
}
Just ADD this below CODE EXAMPLE HERE.
(1) If all a links shows busy.
$('.container, a').css('cursor','wait');
(2) If all a links within CONTAINER shows busy.
$('.container, .container a').css('cursor','wait');
(3) If all a links within whole(DOM) page shows busy.
$('*').css('cursor','wait');
EXAMPLE HERE.
Every element within the container will overwrite the cursor wait with it's default behaviour. You would have to set cursor wait to all elements.
$('*').css('cursor','wait');
You can use:
$('*').css('cursor','auto');
to set everything to default again.
Or possibly better:
$('*').css('cursor','');
to reset to the previous cursor state, therefore not overriding other cursor changes.
add the following to the function:
$(document).css('cursor','wait');

jQuery/JS setTimeout/clearTimeout

I'm not super proficient at this, but I have a navigation item where on hover, a div with a search form slides down. Currently, when you mouseover, then mouseout, the div stays open until you click the close button.
I'm trying to make it so that when you mouseout the div slides backup after a few seconds, unless the user is on the div or nav link still (i.e., they're filling out the search form).
Here's what I have so far:
$("#services_link").mouseover(function() {
$("#services_link").css('background-position','left -73px');
$("#vendors_dropdown").slideDown(function() {
setTimeout(HideMe, 4000);
});
});
function HideMe() {
$("#services_link").css('background-position','left 0');
$("#vendors_dropdown").slideUp();
}
That gets me as var as the div sliding down on hover of the link, and sliding up after 4 seconds (regardless of where the mouse cursor is). So I just need the div to stay open if the mouse cursor is on the link or div.
I've looked at 3 or 4 other similar questions (and answers) and none really quite do the trick. setTimeout (and clearTimeout) is kinda new to me, so please excuse the noob question. :)
Bind both mouseenter and mouseleave. You'll want to do the timeout on the mouseleave, but then reset it when/if the mouseenter happens again.
Try looking at just the selected answer here to see how to do what I'm talking about.
Something like this:
var timeout;
$("#services_link, #vendors_dropdown").mouseenter(function() {
window.clearTimeout(timeout);
$("#services_link").css('background-position','left -73px');
$("#vendors_dropdown").slideDown();
}).mouseleave(function(){
timeout = window.setTimeout(HideMe, 4000);
});
function HideMe() {
$("#services_link").css('background-position','left 0');
$("#vendors_dropdown").slideUp();
}

Add DISPLAY: NONE to span via jQuery when: mouse-click outside span, OR click EXIT button, etc+

What I want is really simple, but every time I try to add the functionality I want, the more I'd mess things up, so I decided to ask help and stick with the working basic script I have now.
I already have a script in progress, that I would like to develop to work almost exactly like this:
https://stackoverflow.com/a/7133084/1399030 { http://jsfiddle.net/Paulpro/YpeeR/25/ } (by: PaulP.R.O.)
Open a hidden span
Hide a hidden span
Span has "CLOSE" button to exit span
Hide currently opened span when another span is triggered
Think... Image Gallery Preview functionality... Kind of.
"Preview" spans are triggered when either .popCover or a.thumbnail is clicked on the webpage, this hidden span will appear based on its specified unique id, by jQuery inserting display: block; to its css.
This is inside a loop with multiple items.
I've gotten this far and this is the working script that I use:
$(document).ready(function() {
$('.popCover').click(function(){
divID = $(this).attr('id');
$("#tooltip-"+divID).fadeIn('5000', function() {
$("#tooltip-"+divID).css("display", "block");
});
});
$("a.thumbnail").click(function() {
dvID = $(this).attr('id');
$("#tooltip-"+dvID).fadeIn('5000', function() {
$("#tooltip-"+dvID).css("display", "block");
});
});
});
But now, I need to add to these functions the trigger to make the span disappear again, (by inserting display: none; to its css.
I'd want the CURRENT SPAN to disappear when:
01. Mouse click is made outside of the span element
02. An exit or X button is clicked INSIDE the span. (like on image galleries, when they preview an image, and exit it by either clicking outside the element or an exit button provided within the preview)
03. .popCover or a.thumbnail is re-clicked (probably to trigger another span of a different ID to show.)
NOTES:
Currently, I can click as many anchors on the page and all these spans with different IDs just accumulate and stack up over each other on the page.
I don't really want that. I don't want more than 1 span to be open at one time, so I was hoping to add functionality that would make the current opened span exit itself when another anchor click is made.
I really did try to do this myself, but... I can't get the methods I've tried to work. It was too complicated to add all these functions together since I'm no jQuery expert. I could get one to work and then ruin it by trying to work in another.
Also, I was thinking of using this similar way of exiting the span:
$(".the_span").fadeOut("5000").css("display", "none");
The only reason I'm not willing to just use some plugin and uncomplicate things for me is, I already really like my "Preview" span css, I have it all ready. I just need the jquery part to work:
To display: block a span when triggered, and display: none it if mentioned conditions are met.
Hoping for assistance, and will be very grateful for each single one! Thank you.
You have to try to add a class on the opened / active element and then bind all the events to close it. Binds have to be done on elements with class .active for example, when closed, .active class have to be removed.
I've finally gotten this to work! :o)
By using if ($("span.the_span").is(":visible")) to check if span with class="the_span" was currently visible / open / or has display: block in its CSS, and if so, to:
- hide the currently open span, before proceeding to show the new span. -
Here's my working finished product that addresses all the functionality I wanted:
$(document).ready(function() {
// When clicks on either ".popCover" or "a.thumbnail" is made,
// Funcion clickPOP is triggered:
var clickPOP = function() {
divID = $(this).attr('id');
// Checks if "span.the_span" is already currently open:
if ($("span.the_span").is(":visible")) {
$("span.the_span").css("display", "none"); // If open, this is where it closes it..
$("#tooltip-"+divID).fadeIn('200', function() { // Then, proceeds to open the new clicked span here.
$("span.the_span #tooltip-"+divID).css("display", "block"); });
}
// But if no "span.the_span" is currently open:
// No need to close anything, it will directly open the new span...
else {
$("#tooltip-"+divID).fadeIn('5000', function() {
$("span.the_span #tooltip-"+divID).css("display", "block"); });
}
} // End of Function. Added functionality starts below...
// Exits "span.the_span" when mouse clicks outside of element
// ... ("Outside of element" means: outside of "span.the_span")
$(document).click(function(){
$("span.the_span").css("display", "none");
});
// Exit Button : Exits "span.the_span" when exit button is clicked
$('span.exitme').css('cursor', 'pointer').click(function(e){
$("span.the_span").css("display", "none");
e.stopPropagation();
});
// This makes sure that clicks inside "span.the_span" continue to work
$('span.the_span').click(function(e){
e.stopPropagation();
});
// This makes sure that clicks on ".popCover" continue to work
$(".popCover").click(function(e){
e.stopPropagation();
});
// This makes sure that clicks on "a.thumbnail" continue to work
$("a.thumbnail").click(function(e){
e.stopPropagation();
});
// Clicks on both ".popCover" & "a.thumbnail"
// ... will trigger actions specified on function: clickPOP.
$(".popCover").click(clickPOP);
$("a.thumbnail").click(clickPOP);
});
As you can see, I've also added the $(document).click(function() etc. to get my original desired functionality of hiding the span when mouse clicks outside of the element, but making sure that clicks can still be made if they are done on .popCover (div) or a.thumbnail (link) on the webpage.
Also, I wouldn't have been able to complete writing this method without the tips from these posts:
* Running same function / different triggers: https://stackoverflow.com/a/1191837/1399030
* Fix clicking inside element (including exit button): https://stackoverflow.com/a/4660691/1399030
* How to check if something is hidden or visible: https://stackoverflow.com/a/178450/1399030
I especially found the last post VERY helpful (and basically it made me understand what I was doing), because poster: Tsvetomir Tsonev included in his code comments:
// Checks for display:[none|block], ignores visible:[true|false]"
I didn't really initially understand that jQuery was able to check or connect with CSS that wasn't inline (being a jQuery noob myself), so that post was indeed very enlightening.
Of course, if there is a better, more efficient way to do this, I would be very happy to be enlightened some more! jQuery is still a learning curve for me, and I'm a very eager student!

Categories

Resources