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().
Related
I'm moving elements from one list to another, the issue is:
I have javascript binded functions to the <li> depending of the <ul>, if I click one <li> that is inside an <ul> with an specific ID, a function is excecuted.
When I move the <li> with success, it's assumed the <li> is already in the other <ul> (The destination one). but if I click the <li> in the new list, the event still bind with the source one <ul>
How do I do to bind the <li> with the current <ul>?
Thanks for your help.
<ul id="sourceList">
<li>element1</li>
<li>element2</li>
</ul>
<ul id="destinationList"></ul>
<script>
$('#sourceList li').click(function () {
$(this).appendTo('#destinationList');
console.log("from source");
});
$('#destinationList li').on("click", function () {
$(this).appendTo('#sourceList');
console.log("from destination");
});
</script>
Events are binded when the script is executed the first time so, in your code, every li from #sourceList has a click event attached to the first defined event listener, no matter if you move the element to another container or not. You need to use event delegation for that:
$('#sourceList').on('click', 'li', function () {
$(this).appendTo('#destinationList');
console.log("from source");
});
$('#destinationList').on('click', 'li', function () {
$(this).appendTo('#sourceList');
console.log("from destination");
});
Hey so here is the code demo I made
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
</head>
<body>
<ul contenteditable class="outerList">
<li class="innerElement">Hello</li>
<li class="innerElement">World</li>
<li class="innerElement">Hello World</li>
</ul>
<script>
$(".outerList").keydown(function () {
console.log("I am the outer ul");
});
$(".innerElement").keydown(function() {
console.log("I am an inner element");
});
</script>
</body>
</html>
and here is the jsFiddle to run it
http://jsfiddle.net/scrbovyr/
Basically I have a content editable UL and I want to catch the enter key and pass in my own custom function. But I need to know which LI element the keydown event was thrown on. And as shown in the demo, I can only seem to tie a keydown event listener (or any event listener for that matter) to the outer UL element. Is there a way to attach the keydown event to each LI? Or is there at least a way to attach it to the UL but still tell which child it came from?
Thanks in advance, let me know if any additional information would help!
You will have to add contenteditable to your li elements in order to achieve that. You are setting contenteditable to your ul element, thus, the event will be binded to that element, you may edit the li elements, but they do not have contenteditable set, so the keyboard events won't be triggered for those elements.
<ul class="outerList">
<li contenteditable class="innerElement">Hello</li>
<li contenteditable class="innerElement">World</li>
<li contenteditable class="innerElement">Hello World</li>
</ul>
And then:
$(".innerElement").keydown(function() {
console.log("I am an inner element");
});
You may check the node at the current selection
If you don't want to make each li a contenteditable element, you may get the element at the current selection or caret position and perform a check against it.
The embedded example shows how you would achieve this using the Web API Interface for contenteditable selections. (I tested this in Chrome, but it may need additional logic to achieve cross-browser compatibility).
It is also worth noting that you can bind some event listeners to the children of a contenteditable element. For example, the click event may be bound to the li elements as you can see in the embedded example.
$(document).ready(function() {
function getCurrentNode() {
var node = window.getSelection().getRangeAt(0).commonAncestorContainer;
return node.nodeType === 1 ? node : node.parentNode;
}
$('.outerList').on('click keyup', function (e) {
var $target = $(getCurrentNode()),
$closest = $target.closest('b');
console.log(e.type);
console.log('I am the outer ul');
console.log($target);
// Optional. Filter by clostest selector.
if ($closest.length) {
console.log('Target matches selector', $closest);
}
});
$('.innerElement').on('click', function (e) {
console.log(e.type);
console.log('I am an inner element');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul contenteditable class="outerList">
<li class="innerElement">Hello</li>
<li class="innerElement"><i>Hello</i></li>
<li class="innerElement"><b><i>Hello</i></b></li>
<li class="innerElement"><b>Hello</b></li>
<li class="innerElement">Hello</li>
<li class="innerElement">Hello</li>
</ul>
I'm loading a php page into a div using the following:
<li>Some Content</li>
$('[data-target]').click( function (e) {
var target = $($(this).attr('data-target'));
target.load($(this).attr('href'));
e.preventDefault(); // prevent anchor from changing window.location
});
<div id="right_section"></div>
This works perfectly fine.... however:
I want to load another page into that same div, but the link is in content1.php . I basically want it to overwrite itself with another page when a link is clicked.
Thoughts ?
You should use jQuery's .on event handler to bind the click event.
http://api.jquery.com/on/
In your case it would look like:
Main Page:
<li>Some Content</li>
<div id="right_section"></div>
<script>
$(document).ready(function()){
$('body').on('click', 'a.load-external', function(e){
var target = $( $(this).attr('data-target') );
target.load( $(this).attr('href') );
e.preventDefault();
});
});
</script>
content1.php
<li>Some Content 2</li>
What this would do is bind the click event on all a.someclass elements inside body and that includes dynamically created elements.
Btw, I added the .someclass so that it will not bind to all a elements but only to specific a elements that you want to load a content from.
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'); });
});
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());
});