Reputation: 477
In my application, it parses data from an xml file and then show the data in a <li>
list.
So there is a <ul>
list and a loop for the xml file to put some specific data in each <li>
tag.
It successfully reads the xml file and creates the list, but the problem is that the list is kind of not active. For example, I made a click
function so it gives alert("done!");
when a <li>
is clicked, but it is not working.
Here is my code:
var tracksArray = [];
$.ajax({
url: 'https://dl.dropboxusercontent.com/u/33538012/playlist.xml',
dataType: "xml",
success: parse,
error: function() {
alert("Error: Something went wrong");
}
});
function parse(document) {
$(document).find("track").each(function() {
tracksArray.push($(this).find('url').text());
$(".panel1 ul").append(
"<li id='row" + tracksArray.length + "'>" +
"<p class='title'>" + $(this).find('title').text() + "</p>" +
"</li>"
);
});
}
$(".panel1 ul li").on("click", function() {
alert("done!");
})
div.app {
margin: 50px auto;
width: 400px;
height: 400px;
border-radius: 10px;
overflow: hidden;
position: relative;
}
div.app > .blur {
width: 100%;
height: 100%;
-webkit-filter: blur(5px);
}
div.mainSection,
div.dashboard {
position: absolute;
left: 0px;
text-align: center;
color: #fff;
font-size: 20px;
}
div.mainSection {
width: 100%;
height: 85%;
background: rgba(0, 0, 0, 0.5);
top: 0;
}
div.dashboard {
width: 100%;
height: 15%;
background: rgba(255, 0, 0, 0.5);
bottom: 0;
}
div.mainSection > .panel1,
div.mainSection > .panel2,
div.mainSection > .panel3 {
width: 100%;
Height: 100%;
Background: rgba(0, 0, 0, 0.5);
position: absolute;
left: 0px;
top: 0px;
}
div.mainSection > .panel3 > p {
margin-top: 80px;
}
.grid-button {
background: none;
border: none;
padding: 3px;
width: 100%;
}
.grid {
display: inline-block;
height: 4px;
position: relative;
width: 32px;
transition: all 0.3s ease-in-out;
}
.grid:after,
.grid:before {
content: '';
position: absolute;
background-color: #FFF;
display: inline-block;
height: 4px;
left: 0;
width: 32px;
transition: all 0.3s ease-in-out;
}
.grid.open {
background-color: #FFF;
}
.grid.open:after {
top: 10px;
}
.grid.open:before {
top: -10px;
}
.grid.close {
background-color: transparent;
transform: scale(0.9);
}
.grid.close:after,
.grid.close:before {
top: 0;
transform-origin: 50% 50%;
}
.grid.close:before {
transform: rotate(135deg);
}
.grid.close:after {
transform: rotate(45deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="app">
<div class="blur"></div>
<div class="mainSection">
<div class="panel1">
<ul></ul>
</div>
<div class="panel2" style="display: none;"></div>
<div class="panel3" style="display: none;"></div>
</div>
<div class="dashboard"></div>
</div>
As you can see, the last part of the my js code is for giving alert if a <li>
is clicked, but nothing happens.
Does anyone know why is that?
Upvotes: 0
Views: 57
Reputation: 153
Because you add the onclick
listener directly to the li
element, it will not work if the li
is dinamicly appended/removed from the ul
via AJAX callback. When you first attached the onclick
to the li
, which are not already appended to the ul
, it will do nothing.
It can be done by attaching the onclick
listener to the ul
itself. then checks whether the target li
clicked within the ul
.
$('panel1 ul').on('click', 'li', function() {
console.log('list clicked!');
});
That means every clicked elements within the panel1 ul
will be delegated up to ul
. And if it is li
, the callback will be executed.
Upvotes: 1
Reputation: 21396
Give a class to your li
s like;
$(".panel1 ul").append(
"<li class="lis" id='row" + tracksArray.length + "'>" +
"<p class='title'>" + $(this).find('title').text() + "</p>" +
"</li>"
);
And then try;
$(".lis").live("click", function(){
alert("done!");
});
Upvotes: 1
Reputation: 19341
You can do like following way.
Here apply concept of Event Propagation
So you can get click event like:
$('.panel1').on("click", "ul li", function(){
var tracksArray = [];
$.ajax({
url: 'https://dl.dropboxusercontent.com/u/33538012/playlist.xml',
dataType: "xml",
success: parse,
error: function() {
alert("Error: Something went wrong");
}
});
function parse(document) {
$(document).find("track").each(function() {
tracksArray.push($(this).find('url').text());
$(".panel1 ul").append(
"<li id='row" + tracksArray.length + "'>" +
"<p class='title'>" + $(this).find('title').text() + "</p>" +
"</li>"
);
});
}
$('.panel1').on("click", "ul li", function(){
alert( $( this ).children( "p" ).text());
})
div.app {
margin: 50px auto;
width: 400px;
height: 400px;
border-radius: 10px;
overflow: hidden;
position: relative;
}
div.app > .blur {
width: 100%;
height: 100%;
-webkit-filter: blur(5px);
}
div.mainSection,
div.dashboard {
position: absolute;
left: 0px;
text-align: center;
color: #fff;
font-size: 20px;
}
div.mainSection {
width: 100%;
height: 85%;
background: rgba(0, 0, 0, 0.5);
top: 0;
}
div.dashboard {
width: 100%;
height: 15%;
background: rgba(255, 0, 0, 0.5);
bottom: 0;
}
div.mainSection > .panel1,
div.mainSection > .panel2,
div.mainSection > .panel3 {
width: 100%;
Height: 100%;
Background: rgba(0, 0, 0, 0.5);
position: absolute;
left: 0px;
top: 0px;
}
div.mainSection > .panel3 > p {
margin-top: 80px;
}
.grid-button {
background: none;
border: none;
padding: 3px;
width: 100%;
}
.grid {
display: inline-block;
height: 4px;
position: relative;
width: 32px;
transition: all 0.3s ease-in-out;
}
.grid:after,
.grid:before {
content: '';
position: absolute;
background-color: #FFF;
display: inline-block;
height: 4px;
left: 0;
width: 32px;
transition: all 0.3s ease-in-out;
}
.grid.open {
background-color: #FFF;
}
.grid.open:after {
top: 10px;
}
.grid.open:before {
top: -10px;
}
.grid.close {
background-color: transparent;
transform: scale(0.9);
}
.grid.close:after,
.grid.close:before {
top: 0;
transform-origin: 50% 50%;
}
.grid.close:before {
transform: rotate(135deg);
}
.grid.close:after {
transform: rotate(45deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="app">
<div class="blur"></div>
<div class="mainSection">
<div class="panel1">
<ul></ul>
</div>
<div class="panel2" style="display: none;"></div>
<div class="panel3" style="display: none;"></div>
</div>
<div class="dashboard"></div>
</div>
Hope it helps.
Upvotes: 1
Reputation: 102
A little change, move the click events into function parse
. Since that ajax is asynchronous, when $.ajax
is executed, it is executed in another thread and at the mean time $(".panel1 ul li").on("click",...)
executes but finds the selector finds nothing. So moving click events into parse function ensures that the events is added after ajax is done.
function parse(document) {
$(document).find("track").each(function() {
tracksArray.push($(this).find('url').text());
$(".panel1 ul").append(
"<li id='row" + tracksArray.length + "'>" +
"<p class='title'>" + $(this).find('title').text() + "</p>" +
"</li>"
);
});
$(".panel1 ul li").on("click", function() {
alert("done!");
});
}
Upvotes: 1
Reputation: 1647
That is because javascript run asyn.
When the data still waits for the ajax.
$(".panel1 ul li").on("click", function() {
alert("done!");
})
is already executed.
That's why it doesn't work!
You can simply put the on() function at the end of parse() function.
Here is my jsbin
https://jsbin.com/jicawe/edit?html,css,js,output
Upvotes: 1
Reputation: 24915
You can use a delegate:
$(document).on("click", "pane1 ul li", function(){ ... });
function createLI() {
var html = "";
for (var i = 0; i < 5;) {
html += "<li>" + ++i + "</li>";
}
$("#list").append(html);
}
function registerEvents() {
$(document).on("click", "#content ul li", function() {
alert($(this).text());
})
}
registerEvents();
createLI();
li {
background: #eee;
margin: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div id="content">
<ul id="list"></ul>
</div>
Upvotes: 1