Rebinding events with jquery not working
I have a page setup for a presentation layout:
+------------------------+
|prev next|
|+----------------------+|
|| page ||
|| dynamic content ||
|| ||
|+----------------------+|
+------------------------+
In the example above, next/prev are nav buttons that control the dynamic content using $("page").load(url);
On one of the pages I have a popup that has buttons in it that are linked to an ajax call which controls the content of the popup.
These buttons do their job nicely when the page is first loaded. If the page is changed (using the nav buttons) and then changed back, the popup will open but the buttons don't work. If you click the buttons, close the popup, and then reopen the popup, the information you requested on the 1st click shows but the buttons still don't work.
This tells me that the ajax request is fine, there is a problem with the binding of the elements somewhere. Here is my Javascript:
$('#resTable').on('click',this,function() {
$('#ayAvgDPm').html("");
$('#aoAvgDPm').html("");
$('#ayTotProfit').html("");
$('#aoTotProfit').html("");
$('#ayAvgPcPm').html("");
$('#aoAvgPcPm').html("");
$('#ayTotPcProfit').html("");
$('#aoTotPcProfit').html("");
$('#ayrRes').html("");
$('#etfProductPopup').bPopup();
});
$('div[class^="sideNav"]').on('click',this,function() {
$('#yrSummary').fadeIn(200);
$('#yAvgDPm').html("");
$('#oAvgDPm').html("");
$('#yTotProfit').html("");
$('#oTotProfit').html("");
$('#yAvgPcPm').html("");
$('#oAvgPcPm').html("");
$('#yTotPcProfit').html("");
$('#oTotPcProfit').html("");
$('#yrRes').html("");
var yr = "20"+$(this).attr('class').substr(-2);
var req = $.ajax({
url : '../includes/prod_results.php',
type : 'POST',
dataType : "json",
data : {
y : yr,
t : 'ETF'
},
success : function(j) {
var table = "<table cellspacing='0'><tr><th>Year</th><th>Returns</th></tr>";
for(var i = 0; i < 12; i++) {
if (i === 5 && yr === '2014'){
break;
}
var obj = j[i];
var month = obj['month'];
var profit = obj['profit'];
var bal = obj['bal'];
table += "<tr><td style='width:75px'>"+month+"</td><td style='padding: 0 15px'>"+parseFloat(profit).toFixed(2)+"%</td><td style='width:75px'>$"+comma(parseFloat(bal).toFixed(2))+"</td></tr>";
if (i === (11)) {
table += "</table>";
}
}
var YAvgDPm = comma(parseFloat(j.YAvgDPm).toFixed(2));
var OAvgDPm = comma(parseFloat(j.OAvgDPm).toFixed(2));
var YTotProfit = comma(parseFloat(j.YTotProfit).toFixed(2));
var OTotProfit = comma(parseFloat(j.OTotProfit).toFixed(2));
var YAvgPcPm = comma(parseFloat(j.YAvgPcPm).toFixed(2));
var OAvgPcPm = comma(parseFloat(j.OAvgPcPm).toFixed(2));
var YTotPcProfit = comma(parseFloat(j.YTotPcProfit).toFixed(2));
var OTotPcProfit = comma(parseFloat(j.OTotPcProfit).toFixed(2));
$('#yAvgDPm').html("$"+YAvgDPm);
$('#oAvgDPm').html("$"+OAvgDPm);
$('#yTotProfit').html("$"+YTotProfit);
$('#oTotProfit').html("$"+OTotProfit);
$('#yAvgPcPm').html(YAvgPcPm+"%");
$('#oAvgPcPm').html(OAvgPcPm+"%");
$('#yTotPcProfit').html(YTotPcProfit+"%");
$('#oTotPcProfit').html(OTotPcProfit+"%");
$('#yrRes').html(table);
$('#yrGraph').html("<img src='../images/graphs/etf_"+yr+".jpg'>");
return false;
}
});
return false;
});
I know it's fairly lengthy...
I have tried the above script both inside and outside the $(document).ready()
handler.
Can someone please help me as to what I am not doing?
EDIT As requested, HTML:
<table id="resTable" cellspacing="0">
<tr>
<th>Year</th>
<th> 1st Quarter</th>
<th>2nd Quarter</th>
<th>3rd Quarter</th>
<th>4th Quarter</th>
<th>Year Total</th>
<th>Month Avg</th>
</tr>
...
</table>
<div id="etfProductPopup">
<h1 style="text-align:center">ETF - Compounded Results</h1>
<div id="popupLeftBar">
<div class="sideNav14">
2014
</div>
<div class="sideNav13">
2013
</div>
<div class="sideNav12">
2012
</div>
<div class="sideNav11">
2011
</div>
<div class="sideNav10">
2010
</div>
<div class="sideNav09">
2009
</div>
<div class="sideNav08">
2008
</div>
<div class="sideNav07">
2007
</div>
<div class="sideNav06">
2006
</div>
<div class="sideNav05">
2005
</div>
<div class="sideNav04">
2004
</div>
<div class="sideNav03">
2003
</div>
</div>
<div id="popupMain">
<div id="yrSummary">
<table cellspacing="0">
<tr>
<th></th>
<th>Avg<br>$/Mth</th>
<th>Total<br>$ Profit</th>
<th>Avg<br>%/Mth</th>
<th>Total<br>% Profit</th>
</tr>
<tr>
<th>Year</th>
<td id="yAvgDPm"></td>
<td id="yTotProfit"></td>
<td id="yAvgPcPm"></td>
<td id="yTotPcProfit"></td>
</tr>
<tr>
<th>Overall</th>
<td id="oAvgDPm"></td>
<td id="oTotProfit"></td>
<td id="oAvgPcPm"></td>
<td id="oTotPcProfit"></td>
</tr>
</table>
</div>
<div id="yrGraph"></div>
<div id="yrRes"></div>
</div>
Really? No body got any other ideas on this? I really need you guys to come through for me on this!
Code for nav buttons:
function nav(d) {
n = page + d;
$('#slide').load('p/'+n+'.php');
}
HTML:
<div class="prev" onClick="nav(-1)" title="Previous Page"><< Previous</div>
<div class="next" onClick="nav(1)" title="Next Page">Next >></div>
EDIT
So I have tried all 3 of the (current) answers and am getting nowhere! This is very frustrating!
I am starting to think there may be some underlying issues and that the bindings are not the complete problem.
The page obviously nees to be loaded as if it was refreshed by the browser. The fact that the page works fine the 1st time it is loaded, regardless of how it is loaded, says to me that the bindings are all fine.
The page also works fine without the popup.
Are there any ideas, other than the bindings, what the underlying issue could be?
Also, I know it is against the rules of SO for me to publish a link to the webpage in question, but if anyone would like a link, I am desperate enough to provide it privately. Please ask.
EDIT
So, I'm thinking, the hidded div (for the popup) is staying populated even after I use the following script:
$('#etfProductPopup').bPopup({
onClose : function() {
postLoadBindings();
$('#ayAvgDPm').html("");
$('#aoAvgDPm').html("");
$('#ayTotProfit').html("");
$('#aoTotProfit').html("");
$('#ayAvgPcPm').html("");
$('#aoAvgPcPm').html("");
$('#ayTotPcProfit').html("");
$('#aoTotPcProfit').html("");
$('#ayrRes').html("");
}
});
I'm thinking the issue may be with the popup script...
https://raw.githubusercontent.com/dinbror/bpopup/master/jquery.bpopup.min.js
EDIT
Also just noticed that the popup div is being duplicated on page load. From the console:
<div id="etfProductPopup" style="display: none; left: 440px; position: absolute; top: 156px; z-index: 2147483650; opacity: 0;">...</div>
<div id="etfProductPopup" style="display: none; left: 440px; position: absolute; top: 156px; z-index: 2147483650; opacity: 0;">...</div>
EDIT
(Yes, I realize if there was a badge for 'Most Edits to Own Question' then I would have won, but I think the more data I provide, the better chance of a response)
I created a #resTable
element on another page (loaded the same way as the previous). I noticed that, even when using $('#resTable').unbind()
in the document ready handler, clicking the element brings up the popup from the previous page!
HOW IS THIS POSSIBLE WHEN THE SCRIPT FOR THE POPUP DOESN'T EVEN EXIST ON THAT PAGE, LET ALONE THE CONTENT??
Someone, PLEASE! There MUST be a rational explanation for this! I am not trying to program humans, this is a computer code, this runs of bits of data and cannot simply make it up as it goes along!
Can someone please help me with this?
Got this far: Popup is creating duplicate div inside the outer page (the one with the nav buttons). I guess it is doing this so that it layers properly over the whole page, rather than just the page that contains the original code for the div.
EDIT
A more in depth look as to what is happening. The div for the popup is obviously inside the page, not the container. bPopup is moving the div to within the <body>
tags of the containing page. This means that the div is available on all pages navigated to after the bPopup call. Closing the popup is not moving the div back, so when the page is reloaded using the nav buttons, the div is being duplicated.
Latest Progress
After speaking to the client I am not able to plost a live link, unfortunately.And to create a jsFiddle would take ages.
As explained in the edits above, the issue is bPopup re-creating the popup div inside the parent page and not removing it on popup close.
I am not sure if there is a way to delete an element on the page? The problem is, if an element can be deleted, the copy that bpopup creates is exactly the same as the original, so any script that targets the duplicate will also target the original
change:
$('#resTable').on('click',this,function() {
...
to
$(document).on('click','#resTable',function() {
...
and
$('div[class^="sideNav"]').on('click',this,function() {
...
to
$(document).on('click','div[class^="sideNav"]',function() {
...
Event delegation that @Sudhir mentioned should have worked, but yet, if you are facing the problem you might wanna try forcefully binding new events every time the page loads. Something like -
In the Main Page, that has the Prev
and Next
button, define all your functions -
var bindEvents = function(){
//we are unbinding to make
//sure we are not attaching more than once since
//instead of on, I am using direct CLICK binding.
$('#resTable').unbind("click").click(function() {
....
});
$('div[class^="sideNav"]').unbind("click").click(function() {
....
});
};
var nav = function(d) {
n = page + d;
$('#slide').empty();
$('#slide').load('p/'+n+'.php', function(){
//bind events
bindEvents();
});
}
$(function(){
//the first page call, when page loads
nav(0);
});
Remember that, this is not the best approach, but this will ensure that other things are alright. If this binding works then we can isolate the issue and confirm that there is problem in how you are using your bindings. Let me know if it still does not work.
I didn't try any fiddle on this, but have you tried putting the events binding of popup buttons on the "complete" hanlder of the ajax request? It seems a safer way to assure bindings to a single element:
var req = $.ajax({
url : '../includes/prod_results.php',
type : 'POST',
dataType : "json",
data : {
y : yr,
t : 'ETF'
},
success : function(j) {
var table = "<table cellspacing='0'><tr><th>Year</th><th>Returns</th></tr>";
for(var i = 0; i < 12; i++) {
if (i === 5 && yr === '2014'){
break;
}
var obj = j[i];
var month = obj['month'];
var profit = obj['profit'];
var bal = obj['bal'];
table += "<tr><td style='width:75px'>"+month+"</td><td style='padding: 0 15px'>"+parseFloat(profit).toFixed(2)+"%</td><td style='width:75px'>$"+comma(parseFloat(bal).toFixed(2))+"</td></tr>";
if (i === (11)) {
table += "</table>";
}
}
var YAvgDPm = comma(parseFloat(j.YAvgDPm).toFixed(2));
var OAvgDPm = comma(parseFloat(j.OAvgDPm).toFixed(2));
var YTotProfit = comma(parseFloat(j.YTotProfit).toFixed(2));
var OTotProfit = comma(parseFloat(j.OTotProfit).toFixed(2));
var YAvgPcPm = comma(parseFloat(j.YAvgPcPm).toFixed(2));
var OAvgPcPm = comma(parseFloat(j.OAvgPcPm).toFixed(2));
var YTotPcProfit = comma(parseFloat(j.YTotPcProfit).toFixed(2));
var OTotPcProfit = comma(parseFloat(j.OTotPcProfit).toFixed(2));
$('#yAvgDPm').html("$"+YAvgDPm);
$('#oAvgDPm').html("$"+OAvgDPm);
$('#yTotProfit').html("$"+YTotProfit);
$('#oTotProfit').html("$"+OTotProfit);
$('#yAvgPcPm').html(YAvgPcPm+"%");
$('#oAvgPcPm').html(OAvgPcPm+"%");
$('#yTotPcProfit').html(YTotPcProfit+"%");
$('#oTotPcProfit').html(OTotPcProfit+"%");
$('#yrRes').html(table);
$('#yrGraph').html("<img src='../images/graphs/etf_"+yr+".jpg'>");
return false;
},
complete:function(){
//put the bindings to popup here
}
});
链接地址: http://www.djcxy.com/p/21270.html
上一篇: 如何制作逼真的轮盘球旋转动画
下一篇: 使用jquery重新绑定事件不起作用