使用jquery重新绑定事件不起作用

时间:2021-05-19 00:08:27

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

在上面的示例中,next / prev是使用$(“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.

在其中一个页面上,我有一个弹出窗口,里面有一些按钮,它们链接到一个控制弹出窗口内容的ajax调用。

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:

这告诉我ajax请求没问题,某些地方的元素绑定存在问题。这是我的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.

我在$(document).ready()处理程序的内部和外部都尝试了上面的脚本。

Can someone please help me as to what I am not doing?

有人可以帮助我,我不做什么?

EDIT As requested, HTML:

编辑根据要求,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:

HTML:

<div class="prev" onClick="nav(-1)" title="Previous Page">&lt;&lt; Previous</div>
<div class="next" onClick="nav(1)" title="Next Page">Next &gt;&gt;</div>

EDIT

编辑

So I have tried all 3 of the (current) answers and am getting nowhere! This is very frustrating!

所以我已经尝试了所有3个(当前)答案而且无处可去!这非常令人沮丧!

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.

此外,我知道发布有关网页的链接是违反SO规则的,但如果有人想要链接,我绝望地私下提供它。请问。

EDIT

编辑

So, I'm thinking, the hidded div (for the popup) is staying populated even after I use the following script:

所以,我在想,即使在我使用以下脚本之后,隐藏的div(用于弹出窗口)也会保持填充:

$('#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

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在页面加载时被复制。从控制台:

<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!

我在另一个页面上创建了一个#resTable元素(以与前一个相同的方式加载)。我注意到,即使在文档就绪处理程序中使用$('#resTable')。unbind(),单击该元素也会显示上一页的弹出窗口!

HOW IS THIS POSSIBLE WHEN THE SCRIPT FOR THE POPUP DOESN'T EVEN EXIST ON THAT PAGE, LET ALONE THE CONTENT??

如果POPUP的脚本在这个页面上不存在,那么这个内容怎么可能?

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.

到目前为止:Popup正在外部页面中创建重复的div(带有导航按钮的div)。我想这样做是为了让它在整个页面上正确分层,而不仅仅是包含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.

更深入地了解正在发生的事情。弹出窗口的div显然位于页面内,而不是容器中。 bPopup正在将div移动到包含页面的标签内。这意味着在bPopup调用之后导航到的所有页面上都可以使用div。关闭弹出窗口不会将div移回,因此当使用导航按钮重新加载页面时,div正在被复制。

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.

不幸的是,在与客户交谈之后,我无法发布实时链接。而创建一个jsFiddle则需要很长时间。

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.

正如上面编辑中所解释的,问题是bPopup在父页面内重新创建弹出div而不是在弹出窗口关闭时删除它。

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

我不确定是否有办法删除页面上的元素?问题是,如果可以删除一个元素,bpopup创建的副本与原始副本完全相同,因此任何以副本为目标的脚本也将定位原始副本

4 个解决方案

#1


1  

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() {
...

#2


1  

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 -

@Sudhir提到的事件委托应该有效,但是,如果你遇到问题,你可能想尝试每次页面加载时强制绑定新事件。就像是 -

In the Main Page, that has the Prev and Next button, define all your functions -

在主页面中,有Prev和Next按钮,定义所有功能 -

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.

请记住,这不是最好的方法,但这将确保其他事情没有问题。如果此绑定有效,那么我们可以隔离问题并确认您使用绑定的方式存在问题。如果它仍然不起作用,请告诉我。

#3


1  

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:

我没有尝试过这方面的任何小提琴,但你是否尝试将弹出按钮的事件绑定放在ajax请求的“完整”hanlder上?这似乎是一种确保绑定到单个元素的更安全的方法:

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

#4


0  

try this

尝试这个

$("body").delegate('#resTable','click',function() {
    //some codes
}


$("body").delegate('div[class^="sideNav"]','click',function() {
    //some codes
}

#1


1  

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() {
...

#2


1  

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 -

@Sudhir提到的事件委托应该有效,但是,如果你遇到问题,你可能想尝试每次页面加载时强制绑定新事件。就像是 -

In the Main Page, that has the Prev and Next button, define all your functions -

在主页面中,有Prev和Next按钮,定义所有功能 -

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.

请记住,这不是最好的方法,但这将确保其他事情没有问题。如果此绑定有效,那么我们可以隔离问题并确认您使用绑定的方式存在问题。如果它仍然不起作用,请告诉我。

#3


1  

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:

我没有尝试过这方面的任何小提琴,但你是否尝试将弹出按钮的事件绑定放在ajax请求的“完整”hanlder上?这似乎是一种确保绑定到单个元素的更安全的方法:

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

#4


0  

try this

尝试这个

$("body").delegate('#resTable','click',function() {
    //some codes
}


$("body").delegate('div[class^="sideNav"]','click',function() {
    //some codes
}