jQuery on/delegate correct syntax - javascript

As the jQuery API is currently down, is anyone able to assist me with the below? I am ajax loading an unordered list into the web page and need to be able to attach hover and click events to the list items.
<ul>
<li class="option">Item 1</li>
<li class="option">Item 1</li>
<li class="option">Item 1</li>
</ul>
So far I have tried a few variations of the below jQuery code using .on for version 1.7+
$("ul").on("click", "li .option", function(){
alert($(this).text());
});
Can anyone point me in the right direction? I'm aware that .live has been deprecated and that .delegate has been superseded so really only looking for a solution that will allow me to use .on.

Not li .option, because it find element within li with class option, but you have this class to li, so it will be li.option or .option.
So for .on(), it looks like:
$("ul").on("click", "li.option", function(){
alert($(this).text());
});
But for .delegate(), it looks like:
$("ul").delegate("li.option", "click", function(){
alert($(this).text());
});
According to you edit
you're trying to bind click to li.option with container reference ul, which is also append to DOM alter. So you can go for #content, which already exists in DOM ans where you append you whole list.
So delegate event will looks like:
$("#content").delegate("ul > li.option", "click", function(){
alert($(this).text());
});

Related

Changing HTML list item to active in navbar

I am loading my navbar into each page with $("#navbar-partial").load("navbar.html) at the bottom of the page in script tags.
The navbar list code is below:
<ul id="main-nav" class="nav nav-sidebar">
<li>
</li>
<li>
</li>
<li>
</li>
<li>
</li>
</ul>
Ive tried this and some variations of this but cant get it to work:
$(document).ready(function () {
$('.nav li').on('click', function (e) {
$(this).addClass('active').siblings().removeClass('active');
});
});
This is in the same script tag at the bottom of the html page, after the load call.
Any ideas?
Thanks
You should use delegation
$(document).on('click', ".nav li", function(e) {
$(this).addClass('active').siblings().removeClass('active');
});
Because the content isn't present on DOM ready (given the asynchronous nature of Ajax), you'll need to use on() to bind the click handler to an ancestor element, which is present in the DOM at the point of DOM-ready, the element with id="navbar-partial", into which you're loading the new content:
// selecting the element present on DOM-ready:
// binding the 'click' event that's fired on elements
// matching the '.nav li' selector:
$('#navbar-partial').on('click', '.nav li', function (e) {
$(this).addClass('active').siblings().removeClass('active');
});
You could bind to an element further up the DOM tree, but binding to the closest element is reduces the amount of bubbling required to detect the event.
References:
on().

Jquery doesn't work on HTML tags which via called by AJAX

i have an unordered list
<ul id="showlist"></ul>
if user calls ajax function this fills with list items like
<ul>
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
</ul>
my problem begins after that. i have a <script> tag at the very and of my page. it says when down button is pressed make first child of <ul> blue. but it does nothing
<script>
$(body).keydown(function(e) {
if(e.keyCode == 40){
$("#showlist:first-child").attr("style","background-color:blue");
}
})
</script>
how can i solve my problem?
Use $('body') instead of $(body).
You also have an issue with your selector:
$("#showlist li:first-child")
Working example: http://jsfiddle.net/hF6LF/
Also, you mentioned in your post that this script is at the end of the page. If you had the script in the head, you would need to wait for dom ready for the body element to exist. It might be safer to bind the handler to document, which will always exist.
Use .on jquery method
$(body).on("keydown", function(e) {
.....
});
Jquery .on()
Yo have to use the on event listener which can handle events on descendant elements not yet created.
See https://api.jquery.com/on/
For example something like the following.
$(document).on( "keydown", "body", function() {
alert( $( this ).text() );
});

jQuery nav menu doesn't update first element

I'm trying to build a custom navigation menu with 3 options. Initially, only the active option is visible. Clicking on the active option shows the other options, and upon clicking on another one, it is prepended at the beginning of the menu and the other list items are once again hidden.
// html
<ul>
<li>Option 1</li>
<li>Option 2</li>
<li>Option 3</li>
</ul>
// css
li {
display: block;
}
li:not(:first-child) {
display: none;
}
// js
$(function(){
$('li:first-child').on('click', function(){
$(this).siblings().toggle()
});
$('li').not(':first-child').on('click', function(){
$(this).prependTo('ul')
$(this).siblings().hide()
});
});
http://jsfiddle.net/H85Yj/
However, the only issue is that after it executes once, it won't run again. I'm guessing that the li:first-child still remains as the first option. Any way I can work around this?
The (undocumented, so far as I can see, in the API for prependTo()) problem you appear to be experiencing is that, once you move the li element from the HTML, the event-binding is not transferred with them; therefore clicking on the li no longer triggers an event. The easiest way around that is to bind the events to the parent ul element, and handle the events there (as the click events bubble up through the DOM and are acted upon by the ancestor).
Therefore, I'd suggest:
$('ul').on('click', 'li', function(){
var self = $(this),
siblings = self.siblings();
if (siblings.filter(':visible').length) {
self.prependTo(self.parent());
siblings.hide();
}
else {
siblings.toggle();
}
});
JS Fiddle demo.
Although, on reflection, the following seems more simple:
$('ul').on('click', 'li', function(){
var _self = $(this);
if (_self.is(':first-child')) {
_self.siblings().toggle();
}
else {
_self.prependTo(_self.parent()).siblings().hide();
}
});
JS Fiddle demo.
Note that I've adjusted the CSS a little, too (to use simple CSS rather than SCSS); setting the display: none as the default rule for the li elements, and display: block for the li:first-child element (as opposed to the needlessly-complex :not(:first-child) rule you used originally).
References:
:first-child selector.
:visible selector.
filter().
is.
on().
parent().
prependTo().
siblings().

How to find the list <li> number using jQuery?

I want to find the order of the <li> the user has clicked. For eg.,
<ul>
<li id="li1">This is list one</li>
<li id="li2">This is list Two</li>
<li id="li3">This is list three</li>
</ul>
When the user clicks on the list item 2, then I had to retrieve the id of that item as li2. How to achieve this?
As pointed out below there are a couple of ways to add the event handlers. .bind is one, .click another. You can also create the function with your logic separately and refer to it in you bind or click event attachment.
<script type="text/javascript">
// version 1 with bind
$(function(){
$("li").bind("click", function(){alert(this.id);});
})
</script>
<script type="text/javascript">
// version 2 with click and the separated method
$(function(){
$("li").click(listClickHandler);
})
function listClickHandler(){
alert(this.id);
}
</script>
separating your handler methods from your handler assignments makes a lot of sense when you are assigning event handlers on the fly or at different points in the page life cycle. The reason I use bind more often then click is that bind can be used for a lot of different events so it would be easy to imagine creating an event assignment factory:
<script type="text/javascript">
// version 3, event assignment factory
function assign(selector, event, method){
$(selector).bind(event, method);
}
$(function(){
assign(".menu li", "click", listClickHandler);
assign(".menu li", "mouseover", listHoverHandler);
})
function listClickHandler(){...};
function listHoverHandler(){...};
</script>
hopefully this is more then you will ever need.
Assuming there are just these li items on the page, the following would alert the id of the li if the user clicks on it.
<!-- on the side: you could leave out the type attribute, when using HTML5 -->
<script type="text/javascript" charset="utf-8">
$(document).ready(function(){
$("li").click(function(){
alert($(this).attr("id"));
});
});
</script>
More on click: http://api.jquery.com/click/
Mode on attr: http://api.jquery.com/attr/
Alternatively to Gabriels answer:
$("li").click(function(){
alert($(this).attr('id'));
});
$('li').click(function(){
alert(this.id);
}​);​
There is no need for an extra $()-function call: this.id works as well.
you might need to loop through your li list. I think you want to generate li ids depending on their index relative to the parent ul. right? you can that with following code
$("ul li").each(function(index, node){
$(this).click(function(){
alert("You clicked on li"+index);
});
});
See this http://www.jsfiddle.net/w9qpj/1/ for live example.
For fetching index of particular li you can use jQuery index function http://api.jquery.com/index/.
or for fetching li using its index you can use jQuery eq function http://api.jquery.com/eq/
$('ul li').eq(2).css('background-color', 'red');
Above code will make ul's 3rd li element's bacground color red.

jQuery Find not working for :first

I am trying to find some child a elements within a ul parent. But, I need to only find the first a. Here is what I am using
$('div.item a').click(function() {
$(this).parent().next('ul.subItems').find('a:first').addClass('selected');
});
HTML:
<div class="item"><a id="main5830" href="http://www.mysite.com">Test</a></div>
<ul class="subItems">
<li><a>test 1</a></li>
<li><a>test 2</a></li>
<li><a>test 3</a></li>
</ul>
I would like test 1's a element to get the class of selected.
For some reason, this is not selecting the first a within in the UL, or ANYTHING in the UL element. Have I done something wrong here?
It does work, just need to use return false; (or event.preventDefault();) at the end of the click event handler to prevent the anchor default click behaviour.
$('div.item a').click(function() {
$(this).parent().next('ul.subItems').find('a:first').addClass('selected');
return false;
});
or
$('div.item a').click(function(e) {
e.preventDefault();
$(this).parent().next('ul.subItems').find('a:first').addClass('selected');
});
Here's a Working Demo showing it working

Categories

Resources