I'm trying to bind to a span element a function to scroll a slideshow (specifically rcarousel plugin).
that's the javascript code:
$('.forward').click(function() {
$("#carousel").rcarousel("next");
});
$('.rewind').click(function() {
$("#carousel").rcarousel("goToPage", 0);
});
Now, this code is inside a document.ready function, the forward button $(".forward") works and successfully scrolls the slideshow, but it's like the rewind button being totally ignored by the browser. With no errors thrown by the chrome devtools console; and if I paste the same code in the console .rewind starts magically to work.
Anyone knows what kind of sorcery is going on there?
PS: In the same document.ready function there are other bindings, each working flawlessly
The carousel buttons are changed dynamically by the carousel, so you need to use a delegated event handler, attached to a non-changing ancestor (document is the default of nothing closer is handy):
$(document).on('click', '.forward', function() {
$("#carousel").rcarousel("next");
});
$(document).on('click', '.rewind', function() {
$("#carousel").rcarousel("goToPage", 0);
});
Delegated events work by listening for the event to bubble up to a non-changing ancestor, then applying the jQuery selector, then applying the function to any clicked elements that caused the event. This means that the element only need to match at event time, not *event registration time).
Note: Do not connect delegated event handlers to 'body' as styling can cause body to have a zero height and not respond to bubbled mouse events.
Related
I have kind of strange problem.
I'm trying to add a couple of events to som DOM elements (all existing, some initially hidden:
$self.on("focus", function () {
$self.next().css("display", "inline-block");
});
$self.on("blur", function () {
$(this).next().hide();
});
$self.parent().find(".icon-ok").on("click", function() {
console.log("icon.ok")
});
You can see the relevant part of the DOM here (self is the span user-name):
Later on, the element eventually because visible and I can click on it. However, the event handler is never called. If I remove the blur event, than the click event works. However, I need both.
What's going on here?
How can I fix it?
Looks like the blur cancels out the click (due to event order) but using mousedown instead of blur may help you get both.
UPDATE: Added code based on comment
$self.parent().find(".icon-ok").on("mousedown", function() {
console.log("icon.ok")
});
Your problem might be the classic delegation problem, where in the element is not available in the DOM when the event is bound.
Delegate the event and see if that solves your problem.
$self.on("click", ".icon-ok", function() {
console.log("icon.ok")
});
User $self if that element is visible or any closest ancestor that you can find which is always present in the DOM.
Need to get info from any element, which was clicked.
Example:
<div>text1<section>text2</section></div>
and JS
$(function(){
$('body *').click(function(){
alert($(this).get(0).tagName.toLowerCase());
});
});
If I click text2, parent element throw alert too. I need only first alert from section. How I can block next alerts from all parent elements of section.
Use event.stopPropagation() to prevent the event from firing on the containing elements.
$(function(){
$('body *').click(function(e){
e.stopPropagation();
alert($(this).get(0).tagName.toLowerCase());
});
});
Just wanted to expand on Kooilnc answer - Using on with event delegation is another option.
Event delegation would be nice if you have an event listener bound before or after on a node that needs to listen to a click handler that has bubbled up. If you stopPropagation, this obviously would be an issue.
Here's a fiddle with a demo:
http://jsfiddle.net/ahgtLjbn/
Let's say a buddy of yours has bound an event listener to a node higher up in the DOM tree. He expects any events that bubble up to it, to be handled by his script.
Using event delegation, the event still bubbles up (so your buddies code will still fire), but it will only alert once (since we called e.stopPropagation).
Calling on without event delegation, or binding the event directly using click (which, under the hood, is just calling on) will prevent the event from bubbling, so your buddies code will never run.
I implemented this to my site from an earlier question but for some reason on Firefox and IE the drop-down box scrolls up by itself. I can't figure out why!
Just click News Feed and as the box drops down, it automatically drops up. It's supposed to drop down and if I click on newfeed again or outside, it's supposed to drop up. But it doesn't do that, it just springs back up.
I am using the JavaScript. What is going on here?
$('#bottom').click(function() {
$('#content').slideDown();
});
$(document).click(function(e) {
if (e.target.id !='bottom') {
$('#content').slideUp();
}
});
Change your #bottom event handler a bit to prevent the bubbling of the click event all the way up to the document:
//it is important to declare the `event` variable as a parameter of this anonymous function so it can be accessed inside the function
$('#bottom').click(function(event) {
event.stopPropagation();
$('#content').slideDown();
});
What's happening with your code is that the event handler for the #bottom element is being triggered, then after that the event handler for clicking on the document fires since the click event bubbles up the DOM. event.stopPropagation() will stop the event from bubbling.
Docs for event.stopPropagation(): http://api.jquery.com/event.stoppropagation/
i have 5 elements in a page.
i have selected them using class names $('.class')
i am trying to perform a function for those selected elements irrespective of event (click or hover or watever).
eg:
$('.class').hover(function(){definition1});
$('.class').click(function(){definition1});
i dont want to have 2 seperate event as above 2, instead i want the function to be executed irrespective of whether its hover or click event.
$('.class').bind('click mouseenter', function() {
// Go nuts.
});
(if using jQuery >= 1.7, swap bind() with on().)
Keep in mind that hover()'s second argument is for mouseleave event, which you haven't written anything for here.
If you want to cover most events, pass in 'blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error' as the first argument.
You could also try to detect them with code by iterating over properties that start with on, but it sounds too flaky to me.
To bind multiple events to one element in jQuery 1.7 and later you can do the following by separating event names by spaces:
jQuery('.class').on('click hover mousenter mouseleave', function(event){
// do what you need to do
});
which you can see in jsfiddle.
But: be careful, because you can easily fire the event too much times (more than necessary and more than enough). By binding so many events some may be called unnecessarily (as in the example above the code will be fired twice when the mouse cursor will leave the element it hovered over).
If you do not want to exec a function without any event put it in
$(function(){
function test(){definition1}
});
then in html
<body onload="test();">
Is there any specificity associated with event callback with jQuery. Say, I register a mousedown event callback on a div element, and also on the document. Which one would trigger if I click on the div? Does the order of registration matters? or the specificity (like css) matters?
thanks.
It will bubble up the DOM tree and call all other events of that type.
You can stop this with event.stopPropagation().
Your example
If you assigned the events like so...
$(document).mousedown(function() { alert('document'); });
$('div').mousedown(function() { alert('div'); });
Mouse down anywhere will trigger document's handler, and get one alert dialog with document.
Mouse down on any div will trigger the div's handler, and then bubble up the DOM all the way to document where it will trigger its event handler. You will get two alert dialogs; first the div one and then the document one.
Both events will be triggered, first the div, and then the document click.
It will execute both, from inside out. Clicking in the div will fire the div event then the document. Example on jsFiddle
$(window.document).click(function(e){
alert("doc");
});
$("div").click(function(e){
alert("div");
});
You can avoid it firing other events with e.stopImmediatePropagation(). See this example
$(window.document).click(function(e){
alert("doc");
});
$("div").click(function(e){
alert("div");
e.stopImmediatePropagation(); // prevents $(doc) from rising
});