how can i prevent nested list's click event - javascript

<script type="text/javascript" src="/js/jquery1.8.3.js"></script>
<script>
$(document).ready(function(){
$("li").has("ul").bind("click",function(e){
console.log($(this).text());
});
});
</script>
<ul>
<li>Fruit
<ul>
<li>Apple</li>
<li>Banana</li>
</ul>
</li>
</ul>
How can I bind click-event only when Fruit is clicked, not Apple, Banana
I hope that click-event is not occured when Apple or Banana is clicked
please help me..

One way, as already illustrated, is with event.stopPropagation(). I dislike this method, since it prevents any other event handlers on the page registering the event.
Better is to check to see if the event originated in another li element. Something like this would do:
$("li").has("ul").bind("click",function(e){
if ($(e.target).closest('li').get(0) !== this) {
return;
}
console.log($(this).text());
});
Let's break apart the key line there:
get e.target, the element where the event originated
make a jQuery object out of it
check to see if that element is an li or get its nearest li ancestor (closest does this)
get that li as a native DOM element
compare the li to the one where the event handler was bound
If the li elements are not the same, the event originated on a nested li. If they are the same, it didn't.
jsFiddle

Wrap you 'Fruit' with an element (like span), and bind the event on this element.
From Quentin's advice, use an element that will tell the user that it is interactive (like <button>, <a>), it's better in fact.

<script type="text/javascript" src="/js/jquery1.8.3.js"></script>
<script>
$(document).ready(function(){
$("ul li").on("click",function(e){
alert($(this).text())
});
or
$("ul li").live("click",function(e){
alert($(this).text())
});
});
</script>
<ul>
<li>Fruit
<ul>
<li>Apple</li>
<li>Banana</li>
</ul>
</li>
</ul>
No need to prevent. Based on your jquery plugin version use live or on. Both are same. If you use this it'll handle the click event that which element you are clicked.
The live() method was deprecated in jQuery version 1.7, and removed in version 1.9. Use the on() method instead

Try this.
$("li").has("ul").bind("click",function(e){
console.log($(this).text());
e.cancelBubble = true;
e.returnValue = false;
//e.stopPropagation works only in Firefox.
if (e.stopPropagation) {
e.stopPropagation();
e.preventDefault();
}
});

Try this : working example
$("li").has("ul").bind("click", function (e) {
if (!$(e.target).find("li").length) return;
console.log($(this).text());
});

$(document).ready(function () {
$("li").has("ul").bind("click", function (e) {
console.log($(this).text());
});
$("li ul").bind("click", function (e) {
e.stopPropagation()
});
});
Demo: Fiddle
Another solution without stopping the event propagation is something like(will work for the given markup)
$(document).ready(function () {
$("li").has("ul").bind("click", function (e) {
if ($(this).is(e.target)) {
console.log($(this).text());
}
});
});
Demo: Fiddle

Related

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() );
});

How to create click event for specific link in a jQuery listview.

I'm trying to create a function that starts when you click on a specific link in a listview.
The issue is that event doesn't seem to fire when you click the link. The list is created dynamically. I'm not sure if that causes an issue.
<label for="listviewForLastTenCalls">Last Ten Calls:</label>
<ul data-role="listview" id="listviewForLastTenCalls">
</ul>
<script>
$('#listviewForLastTenCalls li').click(function(){
//alert('click event handler fired');
</script>
Demo
<ul data-role="listview" id="listviewForLastTenCalls">
<!-- items dynamically generated -->
</ul>
JS
$(document).on('click', '#listviewForLastTenCalls li a', function () {
// code
});
The issue is you are adding the click listener after you have created the list. When you first create the listener there is nothing for it to listen to. You need to add the on click event after you add the <li>
$('#listviewForLastTenCalls li a').click( function () {
// code
});
I hope this is not your fully markup,...
<label for="listviewForLastTenCalls">Last Ten Calls:</label>
<ul data-role="listview" id="listviewForLastTenCalls">
</ul>
<script>
$('#listviewForLastTenCalls li').click(function(){
//alert('click event handler fired');
}); //<--
</script>
And if the list is creadted dynamically, you have to attach the event, after list was created...
You have to do event delegation for dynamically added elements.
$('"#listviewForLastTenCalls"').on("click",'li' ,function(){
alert('triggered');
});
And why on() works ??
Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on().
Something like this:
$(function() {
$("#listviewForLastTenCalls li").on('click', function() { alert('clicked'); });
});

How can I over-ride the click of each LI in jQuery?

I have the following UL:
<ul class="xbreadcrumbs" style="position:absolute; bottom:0px">
<li>A Crumb</li>
</ul>
This is being dynamically created by my javascript. How can I override the click for each LI that is inside of a UL called xbreadcrumbs in jQuery and have it do something instead of go to a new hyperlink?
Also, how can I get the behavior to be different for each li?
Updated:
$.each('.xbreadcrumbs li', function(){
$(this).live('click',function(e){
e.stopPropagation();
console.log('clicked for each li');
});
});
Live is part of the answer, the other part of the answer is that you need to use the event's target property to know which element was actually clicked.
$('.xbreadcrumbs li').live('click', function(e){
e.preventDefault();
console.log('Clicked on element', e.target);
});
Once you add the ul dynamically to the DOM you could subscribe to the .click() event of the inner lis:
$('.xbreadcrumbs li').click(function() {
// do something when the li is clicked
});
you'll have to use the .live() function so that dynamically created elements get the event attached...
$("ul.xbreadcrumbs li").live("click", function() {
//do something
}
Use a live event:
$('.xbreadcrumbs li').live('click', function(){
//override here
});
Since the </ul> is being added dynamically it is best to use $.live() or $.delegate() like this:
$('.xbreadcrumbs li').live('click', function(e){
e.stopPropagation();
console.log('Clicked');
});
Hope this helps!

Why doesn't this jQuery code work?

I have this jQuery code:
$(".topic_form").hide();
$("#edit_topics_link").click(function(e) {
e.preventDefault();
$(".topic_form").show();
$(this).hide();
$("<a href='#' id='done_link'>Done</a>").insertBefore(".topic_form");
});
$("#done_link").click(function(e) {
e.preventDefault();
$(this).remove();
$(".topic_form").hide();
$("#edit_topics_link").show();
});
The first half of the code does this: it hides a form when the page loads. Then when you click a link, it shows the form, hides the clicked link, and adds a new link. This works 100% fine.
The 2nd half of the code doesn't work. When you click the newly added link, it should remove it, show the old link, and re-hide the form. Nothing happens when I click the newly added link. Why is this? How can I fix it?
Because the element to which you're attaching the click-handler to doesn't exist at the time of the document's loading, there are no events attached. You should be able to use live() to fix this:
$("#done_link").live('click', function(e) {
e.preventDefault();
$(this).remove();
$(".topic_form").hide();
$("#edit_topics_link").show();
});
The .live() method is able to affect elements that have not yet been added to the DOM through the use of event delegation: a handler bound to an ancestor element is responsible for events that are triggered on its descendants.
You could also use delegate() on the ancestor element of the #done_link element:
$("#parentElementSelector').delegate('#done_link', 'click', function(e) {
e.preventDefault();
$(this).remove();
$(".topic_form").hide();
$("#edit_topics_link").show();
});
References:
live().
delegate().
The reason it doesn't work is that when you call the second part of the script the link doesn't exist yet. There are 2 ways to solve it. Either move the second part into the first part. That way the attachment of the event handler happens when the link exists:
$(".topic_form").hide();
$("#edit_topics_link").click(function(e) {
e.preventDefault();
$(".topic_form").show();
$(this).hide();
$("<a href='#' id='done_link'>Done</a>").insertBefore(".topic_form")
.click(function(e) {
e.preventDefault();
$(this).remove();
$(".topic_form").hide();
$("#edit_topics_link").show();
});
});
Or use the live method to assign the handler. The live method will watch the dom and whenever something with the selector you specified (in this case .topic_form) appears it will attach the event to it:
$(".topic_form").hide();
$("#edit_topics_link").click(function(e) {
e.preventDefault();
$(".topic_form").show();
$(this).hide();
$("<a href='#' id='done_link'>Done</a>").insertBefore(".topic_form");
});
$("#done_link").live('click', function(e) {
e.preventDefault();
$(this).remove();
$(".topic_form").hide();
$("#edit_topics_link").show();
});

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.

Categories

Resources