jQuery + AJAX + 双重调用

4

我正在构建基于ajax的导航,一切都运行良好,除了一个问题:

当我在Firebug中查看时,每次单击时都会调用并加载ajax站点两次。

这是脚本:

$(document).ready(function () {

    //Check if url hash value exists (for bookmark)
    $.history.init(pageload);   

    //highlight the selected link
    $('a[href=' + document.location.hash + ']').addClass('selected');

    //Seearch for link with REL set to ajax
    $('a[rel=ajax]').click(function () {

        //grab the full url
        var hash = this.href;

        //remove the # value
        hash = hash.replace(/^.*#/, '');

        //for back button
        $.history.load(hash);   

        //clear the selected class and add the class class to the selected link
        $('a[rel=ajax]').removeClass('selected');
        $(this).addClass('selected');

        //hide the main and show the progress bar
        $('#main').hide();
        $('#loading').show();


        //run the ajax
        getPage();

        //cancel the anchor tag behaviour
        return false;
    }); 
});

//AJAX Navigation Helper function
function pageload(hash) {

    //if hash value exists, run the ajax
    if (hash) getPage();    
}

//AJAX Navigation Helper function   
function getPage() {

    //generate the parameter for the php script
    var data = 'page=' + encodeURIComponent(document.location.hash);

    $.ajax({
        url: "loader.php",  
        type: "GET",        
        data: data,     
        cache: false,
        success: function (html) {  

            //hide the progress bar
            $('#loading').hide();   

            //add the main retrieved from ajax and put it in the #main div
            $('#main').html(html);

            //display the body with fadeIn transition
            $('#main').fadeIn('slow');      

            //reload site scripts
            $.getScript("js/script.js"); 

        }       
    });

}

每当我点击导航栏中的列表时,页面会正常加载到#main,但它会发生两次(在Firebug中显示)。有没有人知道为什么?
我注意到当我通过URL访问某个页面时不会发生这种情况(只会进行一次ajax调用),所以我猜问题可能出现在click函数中。
附注:我正在使用jquery历史插件,但我不认为问题出现在那里,是吗?

getPage被调用了多少次,以及为什么被调用了多少次? - user166390
它在点击函数中被调用一次以获取内容,在页面加载函数中被调用一次,以防用户通过浏览器直接导航到它 - 我看不出问题在哪里 :( - r0skar
你的jQuery代码是否位于任何动态加载/修改的内容中(例如从AJAX请求加载的内容,模态弹出区域等)? - Ryan Wright
不是真的。整个代码在页面底部以单独文件形式存在,还有一些部分直接放在页面上。 - r0skar
在这里找到最佳答案:https://dev59.com/cXVC5IYBdhLWcg3wsTfv - mahipal purohit
4个回答

5

我猜getPage被调用了两次。在函数开头加上一个debugger语句,然后打开Firebug看看是否真的是这样。如果是被调用两次,下面是解决该问题的一种方法:

//AJAX Navigation Helper function   
function getPage() {

    if(getPage.isLoaded != true) {

        //generate the parameter for the php script
        var data = 'page=' + encodeURIComponent(document.location.hash);

        $.ajax({
            url: "loader.php",  
            type: "GET",        
            data: data,     
            cache: false,
            success: function (html) {  

                //hide the progress bar
                $('#loading').hide();   

                //add the main retrieved from ajax and put it in the #main div
                $('#main').html(html);

                //display the body with fadeIn transition
                $('#main').fadeIn('slow');      

                //reload site scripts
                $.getScript("js/script.js"); 

            }       
        });

    }

    getPage.isLoaded = true;

}

好的,我认为一旦我在单击时将getPage.isLoaded设置回false,它就可以工作了。非常感谢!! - r0skar

4
我相信您的点击事件正在向上冒泡到锚点。
尝试一下:
    $('a[rel=ajax]').click(function (event) {

        //cancel the anchor tag behaviour
        event.preventDefault();

        //grab the full url
        var hash = this.href;

        //remove the # value
        hash = hash.replace(/^.*#/, '');

        //for back button
        $.history.load(hash);   

        //clear the selected class and add the class class to the selected link
        $('a[rel=ajax]').removeClass('selected');
        $(this).addClass('selected');

        //hide the main and show the progress bar
        $('#main').hide();
        $('#loading').show();


        //run the ajax
        getPage();


    }); 

编辑:仅简单地返回false无法取消jquery绑定事件。

编辑:@wildrot是正确的。


实际上,在任何其他操作之前,您应该执行event.preventDefault()。一些“浏览器”在甚至到达preventDefault()之前就能够继续处理事件。 - vzwick
谢谢你们两个!不幸的是,当我点击链接时它仍然会进行2次调用。无论我在哪里放置event.preventDefault()。而且只有在通过URL直接导航到页面时才会进行一次调用。 - r0skar
只是猜测,可能历史插件每次都会进行第二次调用以“缓存”新加载的内容吗? - r0skar

1
只需添加

$('a[rel=ajax]').die('click').click(function (event) { -> will load once..

希望这有所帮助。

1

只是猜测,但是...你通过 AJAX 加载的内容是否包含相同的脚本?


嗨,这个东西只包含HTML代码,getScript调用了一个script.js文件,但是它还没有任何内容。 - r0skar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接