单页上的多帧Ajax分页

时间:2014-09-05 15:16:55

标签: jquery ajax wordpress pagination

我正在使用标签类别/存档页面的WordPress网站上工作。基本上,每种帖子类型都显示在专用标签中。

在每个类别页面上,我有三个循环,每个循环分别进行分页。这与自定义查询变量完全一致。每个循环都是独立分页的,因此站点可以在每个页面加载时跟踪每个循环中的当前位置。

最终,我想使用Ajax分页。当用户点击下一页'在标签A 上,我不想重新加载带有相同内容的标签B 标签C ,我只是想替换标签A 的内容。

我实际上非常接近让这个工作。我可以通过页面上的链接对每个循环进行分页,但浏览器的前进/后退按钮不再有效。

这是我到目前为止所拥有的:

function doPager() {
    $('.pagination a').click(function(e) {
        e.preventDefault();
        loadContent($(this).attr('href'), $(this).attr('tabName'));
        history.pushState(null, null, $(this).attr('href'));
        historyedited = true;

        $(document).scrollTop(0);
    });
}

此函数将点击处理程序添加到每个分页链接。当我构建分页链接(在php中)时,我设置了自定义属性' tabName'到我要加载的选项卡的基本名称。

我的元素ID被命名为 [base] Tab [base] TabContent ,因此通过传递此属性,我可以保证我从中加载内容适当的标签。

function loadContent(url, tabName) {
    destinationTab = '#' + tabName + 'Tab';
    $(destinationTab).fadeTo(250,0).load(url + ' '+ destinationTab + 'Content', function() {
        $(destinationTab).fadeTo(250,1);
        doPager();
        $('.jsDisabled').addClass('hidden');
    });
}

此功能可加载/替换内容。

以上功能正常运行。我遇到麻烦的地方是浏览器历史记录支持:

if (window.history && history.pushState) {
    historyedited = false;
    $(window).bind('popstate', function(e) {
        if (historyedited) {
            loadContent(location.pathname + location.search);
            // ^ This is the problem.
        }
    });
    doPager();
}

正如评论中所述,我的问题在于对loadContent()的这一特定呼吁。没有tabName参数,因此就函数而言,没有要加载的内容。

最终,我需要一种方法来识别相应的选项卡名称,然后传递给这个特定的调用,但这就是我被困住的地方。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

我继续挖掘和测试不同的选项,我找到了解决方案,所以我想我会分享我找到的东西。

总结一下,我开始使用以下脚本:

$(document).ready(function($){
    if (window.history && history.pushState) {
        historyedited = false;
        $(window).bind('popstate', function(e) {
            if (historyedited) {
                loadContent(location.pathname + location.search);
                // ^ This is the problem.
            }
        });
        doPager();
    }
}

function doPager() {
    $('.pagination a').click(function(e) {
        e.preventDefault();
        loadContent($(this).attr('href'), $(this).attr('tabName'));
        history.pushState(null, null, $(this).attr('href'));
        historyedited = true;

        $(document).scrollTop(0);
    });
}


function loadContent(url, tabName) {
    destinationTab = '#' + tabName + 'Tab';
    $(destinationTab).fadeTo(250,0).load(url + ' '+ destinationTab + 'Content', function() {
        $(destinationTab).fadeTo(250,1);
        doPager();
        $('.jsDisabled').addClass('hidden');
    });
}

通过向分页链接添加自定义tabName属性,我可以确定要加载哪个内容框架的方式抽象函数。但是,我的loadContent()函数在按下前进/后退按钮时收到了一个未定义的tabName参数。

要解决此问题,我需要对现有脚本进行一些小的更改。


第一步:链接类

要做的第一件事是为每个分页链接分配类,表示我要加载的内容:

  • <a class='blogLink'>
  • <a class='videoLink'>
  • <a class='reviewLink'>

第二步:多次点击处理程序

我需要做的下一件事是更改我的doPager()功能。最初,此函数将一个单击处理程序普遍应用于.pagination元素中的每个链接。我真正想要的是一个看起来更像这样的函数:

function doPager() {
    $('a.blogLink').click(function(e) {
        e.preventDefault();
        loadBlogContent($(this).attr('href'));
        history.pushState(null, null, $(this).attr('href'));
        historyedited = true;

        $(document).scrollTop(0);
    });

    $('a.videoLink').click(function(e) {
        e.preventDefault();
        loadVideoContent($(this).attr('href'));
        history.pushState(null, null, $(this).attr('href'));
        historyedited = true;

        $(document).scrollTop(0);
    });

    $('a.reviewLink').click(function(e) {
        e.preventDefault();
        loadReviewContent($(this).attr('href'));
        history.pushState(null, null, $(this).attr('href'));
        historyedited = true;

        $(document).scrollTop(0);
    });
}

通过此更改,我为每种链接类型注册了一个唯一的处理程序,每个处理程序都调用一个特定的内容加载器。

第三步:多个内容加载器

除了添加多个点击处理程序外,我还添加了多个内容加载器。

function loadBlogContent(url) {
    loadContent(url, 'blog');
}

function loadVideoContent(url) {
    loadContent(url, 'video');
}

function loadReviewContent(url) {
    loadContent(url, 'review');
}

这样就无需复制/粘贴原始loadContent()

第四步:popstate Changes

这是原始问题的实际发生地点:

if (window.history && history.pushState) {
    historyedited = false;
    $(window).bind('popstate', function(e) {
        if (historyedited) {
            loadContent(location.pathname + location.search);
            // ^ This is the problem.
        }
    });
    doPager();
}

在popstate事件期间,loadContent()未收到tabName参数。为了解决这个问题,我将单loadContent()次调用替换为我在步骤3中添加的特定于类型的内容加载器:

if (window.history && history.pushState) {
    historyedited = false;
    $(window).bind('popstate', function(e) {
        if (historyedited) {
            loadBlogContent(location.pathname + location.search);
            loadVideoContent(location.pathname + location.search);
            loadReviewContent(location.pathname + location.search);
        }
    });
    doPager();
}

编辑:

我的原始答案中有一点令人讨厌的错误。由于调用doPager()函数的方式,我创建了一个场景,通过视频&#39; tab会为回调中的所有其他选项卡注册重复的单击处理程序。为解决该问题,我将单个doPager()函数替换为特定于帧的寻呼机注册函数:

function registerBlogPager() {
    $('a.blogLink').click(function(e) {
        e.preventDefault();
        loadBlogContent($(this).attr('href'));
        history.pushState(null, null, $(this).attr('href'));
        historyedited = true;

        $(document).scrollTop(0);
    });
}

function registerVideoPager() {
    $('a.videoLink').click(function(e) {
        e.preventDefault();
        loadVideoContent($(this).attr('href'));
        history.pushState(null, null, $(this).attr('href'));
        historyedited = true;

        $(document).scrollTop(0);
    });
}

function registerReviewPager() {
    $('a.reviewLink').click(function(e) {
        e.preventDefault();
        loadReviewContent($(this).attr('href'));
        history.pushState(null, null, $(this).attr('href'));
        historyedited = true;

        $(document).scrollTop(0);
    });
}

我还更改了ready()函数,以便在初始页面加载时调用每个寻呼机注册一次:

$(document).ready(function($){
    if (window.history && history.pushState) {
        historyedited = false;

        registerBlogPager();
        registerVideoPager();
        registerReviewPager();

        $(window).bind('popstate', function(e) {
            if (historyedited) {
                loadBlogContent(location.pathname + location.search);
                loadVideoContent(location.pathname + location.search);
                loadReviewContent(location.pathname + location.search);
            }
        });
    }
}

最后,我对我的通用loadContent()函数进行了更改。以前,这个函数会注册每个点击处理程序,但是使用传递给这个函数的frameName参数,我现在控制调用哪个寻呼机注册:

function loadContent(url, tabName) {
    destinationTab = '#' + tabName + 'Tab';
    $(destinationTab).fadeTo(250,0).load(url + ' '+ destinationTab + 'Content', function() {
        $(destinationTab).fadeTo(250,1);
        doPager();
        $('.jsDisabled').addClass('hidden');
    });

    if (frameName == "blog") {
        registerBlogPagers();
    }

    if (frameName == "video") {
        registerVideoPagers();
    }

    if (frameName == "review") {
        registerReviewPagers();
    }
}