I've been trying to figure out the relatively new (at least for me, I guess) .on() method provided with jQuery versions 1.7.x onwards. We've been using live(), bind() in our code to handle event handlers till now and we're thinking of an overhaul because of the performance issues which .live() seems to have.
So here's my problem. This is the page structure I have in my page:
<div id="header"></div>
<div id="content"></div>
<div id="footer">
<div id="default"></div>
<div class="close">Close</div>
<div id="extras">//some random stuff// </div>
</div>
I've created an object to store frequently used selectors to such as $(document), $("#header"), $("#footer") like this:
var elements = {
$doc: $(document),
$foo: $("#footer"),
$head: $("#header")
};
The behavior expected from the click of .close inside #footer is that #extras must hide from view. I tried to bind the click event of .close to #footer (delegated) like this:
elements.$foo.on("click","div.close",hideFooter)
WHICH DID NOT WORK. But, if bound to elements.$doc like this:
elements.$doc.on("click", "div.close", hideFooter);
IT WORKS. But isn't this how .live() works? (If for every click it should to go to the DOM start and bubble down to div.close)
Am I doing something wrong here?
EXTRA INFO
The contents of the anonymous function hideFooter are :
function hideFooter(event) {
$(event.currentTarget).next().hide("slow")
.closest("#footer").css({ "opacity": "0.8" });
$("#default").show();
}
THE CODE SEQUENCE in default.js
var elements = {
$doc: $(document),
$foo: $("#footer"),
$head: $("#header")
};
elements.$doc
.ready(function () {
elements.$foo.on(events.click, "div.close", hideFooter);
})
.on(events.click, "#content", HideHeaderFooter)
.on(events.hover, "#footer", showFooter);
To make sure the footer element is loaded before your script runs, you can put your script toward the bottom of the page.
<body>
<div id="header"></div>
<div id="content"></div>
<div id="footer">
<div id="default"></div>
<div class="close">Close</div>
<div id="extras">//some random stuff// </div>
</div>
<script src="/default.js" type="text/javascript"></script>
</body>
Or if you want your <script> to be in the <head> of the page, you can wrap your code in a jQuery .ready() handler so that it doesn't run until the page is loaded.
$(function() {
// Code in here will not run until the rest of the page has loaded.
var elements = {
$doc: $(document),
$foo: $("#footer"),
$head: $("#header")
};
elements.$doc
.on(events.click, "#content", HideHeaderFooter)
.on(events.hover, "#footer", showFooter);
elements.$foo.on("click","div.close",hideFooter);
});
So now your code will be delayed until the page has loaded, and so your footer element will exist and be ready for DOM selection.
Why don't you put it together in the handler? This should work:
elements.$foo.on("click","div.close", function() {
$(this).next().hide("slow").closest("#footer").css({ "opacity": "0.8" });
});
You have this
elements.$foo.on("click","div.close",HideFooter)
Did you mean this?
elements.$foo.on("click","div.close",hideFooter)
Notice the 'H' in your function name.
Related
HTML:
<div class="channellist"></div>
Using Ajax i am getting the channels dynamically when the page loads and appending in the channellist container. After appending my html looks like this.
<div class="channellist" id="channellist">
<div class="c01" id="c1"></div>
<div class="c01" id="c2"></div>
<div class="c01" id="c3"></div>
</div>
I tried like this
$('.channellist').hover(function() {
alert(this.id);
});
I got the alert message.
when i tried the hover on c01 class i didnt got the alert.
$('.c01').hover(function() {
alert(this.id);
});
I dont know where it is going wrong. Can anyone help to figure it out.
You need use event delegation, try this
$('.channellist').on('mouseenter mouseleave', '.c01', function() {
console.log(this.id);
});
// only for example
setTimeout(function () {
$('.channellist').html(
'<div class="c01" id="c1">1</div>' +
'<div class="c01" id="c2">2</div>' +
'<div class="c01" id="c3">3</div>'
);
}, 1000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="channellist" id="channellist"></div>
$.on
The name "hover" used as a shorthand for the string "mouseenter
mouseleave". It attaches a single event handler for those two events,
and the handler must examine event.type to determine whether the event
is mouseenter or mouseleave. Do not confuse the "hover"
pseudo-event-name with the .hover() method, which accepts one or two
functions.
Using Ajax i am getting the channels dynamically
This can be sorted using event delegation like:
$('#channellist').on('mouseenter', '.c01', function() {
alert(this.id);
});
syntax of event delegation is something like:
$(staticParent).on(event, selector, callback);
where $(staticParent) should be the element which was available when DOM was ready, In your case it seems to be #channellist element.
Since code is dynamically attached to the div, onload of the document the event will not be present, So use .live event or use .on by delegating the event. Then event will execute. For your reference Check this link:
https://jsfiddle.net/HimeshS/ocxoy6c2/
https://jsfiddle.net/HimeshS/ocxoy6c2/
For .live:
$(.c01).live("mouseenter", function(){
alert(this.id);
});
<div class="channellist" id="channellist">
<div class="c01" id="c1"></div>
<div class="c01" id="c2"></div>
<div class="c01" id="c3"></div>
</div>
Your blocks are empty, their height is 0, and you can't hover on tham.
Try to make height more, or print some text inside,
Like:
<div class="channellist" id="channellist">
<div class="c01" id="c1">1</div>
<div class="c01" id="c2">2</div>
<div class="c01" id="c3">3</div>
</div>
So, I have a simple code that I can't get it to work. I tried to find answers on the same topic here, but being new to jQuery all answers seem too complicated.
Anyways, what I want to do is have the same script run for different divs. After some reading here I managed to arrange the following code, but it doesn't seem to work.
<div id="mydiv1" onclick="handleClick(this)" style="position:relative; left:0px;">Div One</div>
<div id="mydiv1a" style="position:relative; left:0px;">Div One A</div>
<div id="mydiv2" onclick="handleClick(this)" style="position:relative; left:0px;">Div Two</div>
<div id="mydiv2a" style="position:relative; left:0px;">Div Two A</div>
<script>
$(document).ready(function(){
function handleClick(x) {
$(x.id + 'a').fadeToggle("slow");
}
}
</script>
What I want this to do is when I click #mydiv1, the function should run on #mydiv1a. And the same for #mydiv2. Thank you in advance for your help!
It's better to assign the handling within your script (not inline in html). Bonus for that is that you can use jQuery delegation, i.e. assign a click handler on the document body for a number of elements within the body. Furthermore, the styling should be in a css tag/css file where possible (why?). In this case both position and left are useless. The snippet shows all this:
$('body').on('click', '#mydiv1, #mydiv2', handleClick);
// ^ handler on body | |
// for elements |
// handler method
function handleClick(e) {
$('#'+this.id+'a').fadeToggle('slow');
}
#mydiv1, #mydiv2 {
cursor: pointer;
}
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<div id="mydiv1">Div One</div>
<div id="mydiv1a">Div One A</div>
<div id="mydiv2">Div Two</div>
<div id="mydiv2a">Div Two A</div>
You need to use # which is how you select element with a specific id in jQuery or css for that matter
$('#' + x.id + 'a').fadeToggle("slow");
But you can simplify your code to the below
$('div').filter(function(){ return /\d+$/.test(this.id) }).click(function(){
$(this).next().fadeToggle("slow");
});
Try this
$(this).next().fadeToggle("slow");
This code creates a click event for both divs. The event will be aware of the specific div clicked.
$(function(){
$("#mydiv1, #mydiv2").click(function(){
$(this).fadeToggle("slow");
});
});
I have a pop-up that has a .close class which is basically just an X plus some extra spacing. My problem is, I can't get the click event to work when it's in my code, however, if I paste it into Google's dev tools console, it works as expected...
The culprit...
$('.modal').bind(touchClick, 'close', function(e) {
$('.modal.active').removeClass('active');
$('.modal.b').removeClass('b');
$('.modal.c').removeClass('c');
$('.modal.d').removeClass('d');
$('.modal.e').removeClass('e');
$('.modal .content').html('');
});
The setup...
<div class="modal">
<div class="content">
<div class="close">
<div class="x"></div>
</div>
</div>
<div class="bg"></div>
</div>
Is your script above your html?
Try this:
$(function(){
$('.modal').bind(touchClick, 'close', function(e) {
$('.modal.active').removeClass('active');
$('.modal.b').removeClass('b');
$('.modal.c').removeClass('c');
$('.modal.d').removeClass('d');
$('.modal.e').removeClass('e');
$('.modal .content').html('');
});
});
Make sure the .modal node is in the DOM before you execute your code.
The code attaches a click handler to .modal. If it isn't in the dom, there is nothing to attach it to.
If the modal is being injected into the DOM, make the click handler attach to the body instead.
$('body').bind(touchClick, '.modal .close', function (e) {
...
});
Note that I added a . to close to make it a class...
I had a suggestion to add this to my code:
<script type="text/javascript">
$(document).on('scroll', '.wrapper1', function () {
$(".wrapper2").scrollLeft($(".wrapper1").scrollLeft());
});
$(document).on('scroll', '.wrapper2', function () {
$(".wrapper1").scrollLeft($(".wrapper2").scrollLeft());
});
</script>
So I could change two scroll bars at together. Here's the HTML that I am using:
<div class="wrapper1">
<div class="div1">
</div>
</div>
<div class="wrapper2">
<div class="div2">
<div data-ng-class="{'hidden': loading!=0 }"
data-ng-form="gridForm">
<table class="form grid table" style="height: 600px; width: 1500px;">
</table>
</div>
</div>
</div>
I have jQuery loaded but it seems that the scroll bars don't scroll together. Can anyone help suggest why this is.
Note I need to use .on as the scroll bar area is loaded dynamically.
Here's a fiddle: http://jsfiddle.net/npwD8/
I've updated your example on JSFiddle to one that works, though I am not certain it will ultimately fit your use case.
http://jsfiddle.net/npwD8/4/
$('.wrapper').on('scroll', function({
$(".wrapper").not(this).scrollLeft($(this).scrollLeft());
});
The scroll event does not bubble, so delegating down from window won't work. You'll need to manually handle the attachment of these events when those elements are added to the DOM.
The scroll() event is unqualified to use event bubbling;
"In all browsers, the load, scroll, and error events (e.g., on an <img>
element) do not bubble." - jQuery on() documentation.
Therefore event delegation (e.g. $(document).on('...', '...')) isn't possible with it I'm afraid.
I have the following HTML:
<div id="panel">
<div class="listing" id="ref_1">...</div>
<div class="listing" id="ref_2">...</div>
<div class="listing" id="ref_3">...</div>
<div class="listing" id="ref_4">...</div>
</div>
What I should like to do is, when someone hovers over a div.listing, to alert() to the screen the id name.
Meaning, if a person hovers over with their mouse the id="ref_3", to alert("ref_3");
Question: How do I do this with JQuery/Javascript?
UPDATE:
Linked below is the live site. As you'll see, none of the answers below work. (Line 340)
http://tinyurl.com/ybbey4
Any recommendation?
$('.listing').bind('mouseover',function(){
alert($(this).attr('id'));
});
You can see this code working here.
UPDATE
looking at your code, you might want to try this instead:
$('.hlisting').live('mouseover',function(){
alert($(this).attr('id'));
});
Are you currently using $ as a function in other script file, and not using noConflict
BillyJ, it sounds like you maybe aren't loading up the jQuery library in your HTML file.
Be sure to include <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js" type="text/javascript"></script> in your file before calling the above function.
better yet
$('#panel div.listing').mouseover(function() {
alert($(this).attr('id'));
});
this works
<!DOCTYPE>
<html>
<head><title>test</title>
<style type="text/css">
.listing { width: 100px; height: 100px; border: 1px black solid; }
</style>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("jquery", "1.4.1");
google.setOnLoadCallback(function() {
$('#panel div.listing').mouseover(function() {
alert($(this).attr('id'));
});
});
</script></head>
<div id="panel">
<div class="listing" id="ref_1">...</div>
<div class="listing" id="ref_2">...</div>
<div class="listing" id="ref_3">...</div>
<div class="listing" id="ref_4">...</div>
</div>
</body>
</html>
Seems to work fine separate from your site...
I'd suggest just adding a div in the code with a hslisting class. Don't use JS to inject it. See if something about the way you are injecting it is causing problems.
http://jsbin.com/agosa works just fine.
The 'mouseenter' event is usually a better choice than 'mouseover'. From
http://api.jquery.com/mouseenter/ :
"The mouseenter event differs from mouseover in the way it handles event bubbling. If mouseover were used in this example, then when the mouse pointer moved over the Inner element, the handler would be triggered. This is usually undesirable behavior. The mouseenter event, on the other hand, only triggers its handler when the mouse enters the element it is bound to, not a descendant."
jQuery('#panel div.listing').bind('mouseenter',function(){
alert(this.id);
return false;
});