setInterval 与其他 jQuery 事件 - 递归过多

发布于 2024-09-09 09:40:06 字数 2144 浏览 3 评论 0原文

我正在尝试为一个小页面构建一个 Javascript 侦听器,该页面使用 AJAX 根据 URL 中的锚点加载内容。在网上查找并修改了一个使用 setInterval() 来执行此操作的脚本,到目前为止它工作正常。但是,我在 $(document).ready() 中有其他 jQuery 元素,用于菜单和内容的特殊效果。如果我使用 setInterval() 则其他 jQuery 效果都不起作用。我想出了一种方法来让它工作,方法是在 setInterval() 的循环中包含 jQuery 效果,如下所示:

$(document).ready(function() {
    var pageScripts = function() {
        pageEffects();
        pageURL();      
    }
    window.setInterval(pageScripts, 500);
});

var currentAnchor = null;

function pageEffects() {
    // Popup Menus
    $(".bannerMenu").hover(function() {
        $(this).find("ul.bannerSubmenu").slideDown(300).show;
    }, function() {
        $(this).find("ul.bannerSubmenu").slideUp(400);
    });

    $(".panel").hover(function() {
        $(this).find(".panelContent").fadeIn(200);
    }, function() {
        $(this).find(".panelContent").fadeOut(300);
    });

    // REL Links Control
    $("a[rel='_blank']").click(function() {
        this.target = "_blank";
    });
    $("a[rel='share']").click(function(event) {
        var share_url = $(this).attr("href");

        window.open(share_url, "Share", "width=768, height=450");
        event.preventDefault();
    });
}

function pageURL() {
    if (currentAnchor != document.location.hash) {
        currentAnchor = document.location.hash;
        if (!currentAnchor) {
            query = "section=home";
        } else {
            var splits = currentAnchor.substring(1).split("&");
            var section = splits[0];
            delete splits[0];
            var params = splits.join("&");
            var query = "section=" + section + params;
        }
        $.get("loader.php", query, function(data) {
            $("#load").fadeIn("fast");
            $("#content").fadeOut(100).html(data).fadeIn(500);  
            $("#load").fadeOut("fast");
        });
    }
}

这在一段时间内工作正常,但在加载页面几分钟后,它会拖动到IE 和 Firefox 中的近乎停止。我检查了 FF 错误控制台,它返回错误“太多递归”。 Chrome 似乎并不在意,尽管页面已经打开了很长一段时间,但页面仍或多或少地继续正常运行。

在我看来, pageEffects() 调用导致了递归问题,但是,任何将其移出循环的尝试都会破坏它们,并且一旦 它们就停止工作setInterval 使其成为第一个循环。

对此的任何帮助将不胜感激!

I'm trying to build a Javascript listener for a small page that uses AJAX to load content based on the anchor in the URL. Looking online, I found and modified a script that uses setInterval() to do this and so far it works fine. However, I have other jQuery elements in the $(document).ready() for special effects for the menus and content. If I use setInterval() no other jQuery effects work. I finagled a way to get it work by including the jQuery effects in the loop for setInterval() like so:

$(document).ready(function() {
    var pageScripts = function() {
        pageEffects();
        pageURL();      
    }
    window.setInterval(pageScripts, 500);
});

var currentAnchor = null;

function pageEffects() {
    // Popup Menus
    $(".bannerMenu").hover(function() {
        $(this).find("ul.bannerSubmenu").slideDown(300).show;
    }, function() {
        $(this).find("ul.bannerSubmenu").slideUp(400);
    });

    $(".panel").hover(function() {
        $(this).find(".panelContent").fadeIn(200);
    }, function() {
        $(this).find(".panelContent").fadeOut(300);
    });

    // REL Links Control
    $("a[rel='_blank']").click(function() {
        this.target = "_blank";
    });
    $("a[rel='share']").click(function(event) {
        var share_url = $(this).attr("href");

        window.open(share_url, "Share", "width=768, height=450");
        event.preventDefault();
    });
}

function pageURL() {
    if (currentAnchor != document.location.hash) {
        currentAnchor = document.location.hash;
        if (!currentAnchor) {
            query = "section=home";
        } else {
            var splits = currentAnchor.substring(1).split("&");
            var section = splits[0];
            delete splits[0];
            var params = splits.join("&");
            var query = "section=" + section + params;
        }
        $.get("loader.php", query, function(data) {
            $("#load").fadeIn("fast");
            $("#content").fadeOut(100).html(data).fadeIn(500);  
            $("#load").fadeOut("fast");
        });
    }
}

This works fine for a while but after a few minutes of the page being loaded, it drags to a near stop in IE and Firefox. I checked the FF Error Console and it comes back with an error "Too many Recursions." Chrome seems to not care and the page continues to run more or less normally despite the amount of time it's been open.

It would seem to me that the pageEffects() call is causing the issue with the recursion, however, any attempts to move it out of the loop breaks them and they cease to work as soon as setInterval makes it first loop.

Any help on this would be greatly appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

み零 2024-09-16 09:40:06

我猜测 pageEffects 需要添加到 pageURL 内容中。

至少这应该更加高效并防止重复的处理程序

$(document).ready(function() {
   pageEffects($('body'));
   (function(){
       pageURL(); 
       window.setTimeout(arguments.callee, 500);
   })();              
});

var currentAnchor = null;

function pageEffects(parent) {
    // Popup Menus
    parent.find(".bannerMenu").each(function() {
        $(this).unbind('mouseenter mouseleave');
        var proxy = {
            subMenu: $(this).find("ul.bannerSubmenu"),
            handlerIn: function() {
              this.subMenu.slideDown(300).show();
            },
            handlerOut: function() {
              this.subMenu.slideUp(400).hide();
            }
        };
        $(this).hover(proxy.handlerIn, proxy.handlerOut);
    });

    parent.find(".panel").each(function() {
        $(this).unbind('mouseenter mouseleave');
        var proxy = {
          content: panel.find(".panelContent"),
          handlerIn: function() {
            this.content.fadeIn(200).show();
          },
          handlerOut: function() {
            this.content.slideUp(400).hide();
          }
        };
        $(this).hover(proxy.handlerIn, proxy.handlerOut);
    });

    // REL Links Control
    parent.find("a[rel='_blank']").each(function() {
        $(this).target = "_blank";
    });

    parent.find("a[rel='share']").click(function(event) {
        var share_url = $(this).attr("href");

        window.open(share_url, "Share", "width=768, height=450");
        event.preventDefault();
    });
}

function pageURL() {
    if (currentAnchor != document.location.hash) {
        currentAnchor = document.location.hash;
        if (!currentAnchor) {
            query = "section=home";
        } else {
            var splits = currentAnchor.substring(1).split("&");
            var section = splits[0];
            delete splits[0];
            var params = splits.join("&");
            var query = "section=" + section + params;
        }
        var content = $("#content");
        $.get("loader.php", query, function(data) {
            $("#load").fadeIn("fast");
            content.fadeOut(100).html(data).fadeIn(500);  
            $("#load").fadeOut("fast");
        });

        pageEffects(content);
    }
}

I am guessing that the pageEffects need added to the pageURL content.

At the very least this should be more efficient and prevent duplicate handlers

$(document).ready(function() {
   pageEffects($('body'));
   (function(){
       pageURL(); 
       window.setTimeout(arguments.callee, 500);
   })();              
});

var currentAnchor = null;

function pageEffects(parent) {
    // Popup Menus
    parent.find(".bannerMenu").each(function() {
        $(this).unbind('mouseenter mouseleave');
        var proxy = {
            subMenu: $(this).find("ul.bannerSubmenu"),
            handlerIn: function() {
              this.subMenu.slideDown(300).show();
            },
            handlerOut: function() {
              this.subMenu.slideUp(400).hide();
            }
        };
        $(this).hover(proxy.handlerIn, proxy.handlerOut);
    });

    parent.find(".panel").each(function() {
        $(this).unbind('mouseenter mouseleave');
        var proxy = {
          content: panel.find(".panelContent"),
          handlerIn: function() {
            this.content.fadeIn(200).show();
          },
          handlerOut: function() {
            this.content.slideUp(400).hide();
          }
        };
        $(this).hover(proxy.handlerIn, proxy.handlerOut);
    });

    // REL Links Control
    parent.find("a[rel='_blank']").each(function() {
        $(this).target = "_blank";
    });

    parent.find("a[rel='share']").click(function(event) {
        var share_url = $(this).attr("href");

        window.open(share_url, "Share", "width=768, height=450");
        event.preventDefault();
    });
}

function pageURL() {
    if (currentAnchor != document.location.hash) {
        currentAnchor = document.location.hash;
        if (!currentAnchor) {
            query = "section=home";
        } else {
            var splits = currentAnchor.substring(1).split("&");
            var section = splits[0];
            delete splits[0];
            var params = splits.join("&");
            var query = "section=" + section + params;
        }
        var content = $("#content");
        $.get("loader.php", query, function(data) {
            $("#load").fadeIn("fast");
            content.fadeOut(100).html(data).fadeIn(500);  
            $("#load").fadeOut("fast");
        });

        pageEffects(content);
    }
}
吾性傲以野 2024-09-16 09:40:06

感谢您的建议。我尝试了其中一些,但仍然没有达到理想的效果。经过一番仔细的测试,我发现发生了什么事。对于 jQuery(大概还有 Javascript),每当进行 AJAX 回调时,通过回调引入的元素都不会绑定到文档中最初绑定的元素,必须重新绑定它们。您可以通过在成功回调时调用所有 jQuery 事件或使用 jQuery 库中的 .live() 事件来完成此操作。我选择了 .live(),它现在就像一个魅力,不再出现递归错误:D。

    $(document).ready(function() {
    // Popup Menus
    $(".bannerMenu").live("hover", function(event) {
        if (event.type == "mouseover") {
            $(this).find("ul.bannerSubmenu").slideDown(300);
        } else {
            $(this).find("ul.bannerSubmenu").slideUp(400);
        }
    });

    // Rollover Content
    $(".panel").live("hover", function(event) {
        if (event.type == "mouseover") {
            $(this).find(".panelContent").fadeIn(200);
        } else {
            $(this).find(".panelContent").fadeOut(300);
        }
    });

    // HREF Events
    $("a[rel='_blank']").live("click", function(event) {
        var target = $(this).attr("href");
        window.open(target, "_blank");
        event.preventDefault();
    });

    $("a[rel='share']").live("click", function(event) {
        var share_url = $(this).attr("href");
        window.open(share_url, "Share", "width=768, height=450");
        event.preventDefault();
    });

    setInterval("checkAnchor()", 500);
});

var currentAnchor = null;

function checkAnchor() {
    if (currentAnchor != document.location.hash) {
        currentAnchor = document.location.hash;
        if (!currentAnchor) {
            query = "section=home";
        } else {
            var splits = currentAnchor.substring(1).split("&");
            var section = splits[0];
            delete splits[0];
            var params = splits.join("&");
            var query = "section=" + section + params;
        }
        $.get("loader.php", query, function(data) {
            $("#load").fadeIn(200);
            $("#content").fadeOut(200).html(data).fadeIn(200);
            $("#load").fadeOut(200);
        });
    }
}

无论如何,该页面即使在 IE 中也能按预期工作(我很少检查兼容性)。希望其他新手能从我的错误中吸取教训:p。

Thanks for the suggestions. I tried a few of them and they still did not lead to the desirable effects. After some cautious testing, I found out what was happening. With jQuery (and presumably Javascript as a whole), whenever an AJAX callback is made, the elements brought in through the callback are not binded to what was originally binded in the document, they must be rebinded. You can either do this by recalling all the jQuery events on a successful callback or by using the .live() event in jQuery's library. I opted for .live() and it works like a charm now and no more recursive errors :D.

    $(document).ready(function() {
    // Popup Menus
    $(".bannerMenu").live("hover", function(event) {
        if (event.type == "mouseover") {
            $(this).find("ul.bannerSubmenu").slideDown(300);
        } else {
            $(this).find("ul.bannerSubmenu").slideUp(400);
        }
    });

    // Rollover Content
    $(".panel").live("hover", function(event) {
        if (event.type == "mouseover") {
            $(this).find(".panelContent").fadeIn(200);
        } else {
            $(this).find(".panelContent").fadeOut(300);
        }
    });

    // HREF Events
    $("a[rel='_blank']").live("click", function(event) {
        var target = $(this).attr("href");
        window.open(target, "_blank");
        event.preventDefault();
    });

    $("a[rel='share']").live("click", function(event) {
        var share_url = $(this).attr("href");
        window.open(share_url, "Share", "width=768, height=450");
        event.preventDefault();
    });

    setInterval("checkAnchor()", 500);
});

var currentAnchor = null;

function checkAnchor() {
    if (currentAnchor != document.location.hash) {
        currentAnchor = document.location.hash;
        if (!currentAnchor) {
            query = "section=home";
        } else {
            var splits = currentAnchor.substring(1).split("&");
            var section = splits[0];
            delete splits[0];
            var params = splits.join("&");
            var query = "section=" + section + params;
        }
        $.get("loader.php", query, function(data) {
            $("#load").fadeIn(200);
            $("#content").fadeOut(200).html(data).fadeIn(200);
            $("#load").fadeOut(200);
        });
    }
}

Anywho, the page works as intended even in IE (which I rarely check for compatibility). Hopefully, some other newb will learn from my mistakes :p.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文