Discuz教程网

[插件制作] Discuz X3中自动加载更多的代码分析

[复制链接]
authicon dly 发表于 2013-8-26 11:47:05 | 显示全部楼层 |阅读模式
在研究DiscuzX3.0的过程中需要使用无刷新自动加载更多数据代替翻页效果,但是又不局限与DZ官方默认的只有帖子列表对帖子才有效果,仔细研究了一下分析如下,以备查询。

需要注意三处:
1、模板前台效果页中的“加载更多”按钮,作用:显示“加载中”与引入需要的js文件;
2、最重要的autoloadpage.js文件,作用:实现自动加载的主代码段;
3、模板页中需要加载数据的DOM结构化,作用:在2中的js容易处理DOM元素,原则是可选取、以替换、容易使用js的正则处理。


具体实现细节分析:

第1步:模板页的“加载更多”按钮与js主文件的引入。
  1. <!--{if $multipage && $filter != 'hot'}-->
  2. <!--{if !($_G[forum][picstyle] && !$_G[cookie][forumdefstyle])}-->
  3. <u><a class="bm_h" href="javascript:;" rel="$multipage_more" curpage="$page" id="autopbn" totalpage="$maxpage" picstyle="$_G[forum][picstyle]" forumdefstyle="$_G[cookie][forumdefstyle]">{lang next_page_extra}</a>
  4. <script type="text/javascript" src="http://yourweb.com/{$_G[setting][jspath]}autoloadpage.js?{VERHASH}"></script></u>
  5. <!--{else}-->
  6. <div id="pgbtn" class="pgbtn"><a href="http://youweb.com/forum.php?mod=forumdisplay&fid={$_G[fid]}&filter={$filter}&orderby={$_GET[orderby]}{$forumdisplayadd}&{$multipage_archive}&page=$nextpage" hidefocus="true">{lang next_page_extra}</a></div>
  7. <!--{/if}-->
  8. <!--{/if}-->
复制代码

其中,注意下划线的部分,a标签里需要的变量都是在对应的php文件里面备好。前三个很重要:rel代表将要去提取数据的php文件地址,curpage代表当前页,totalpage代表总页数;后面两个:picstyle与forumdefstyle分别代表图片格式与板块默认格式,如果开发其他单独页,基本用不到。

第2步:细看autoloadpage.js文件。
  1. (function() {

  2.         var autopbn = $('autopbn');
  3.         var nextpageurl = autopbn.getAttribute('rel').valueOf();
  4.         var curpage = parseInt(autopbn.getAttribute('curpage').valueOf());
  5.         var totalpage = parseInt(autopbn.getAttribute('totalpage').valueOf());
  6.         var picstyle = parseInt(autopbn.getAttribute('picstyle').valueOf());
  7.         var forumdefstyle = parseInt(autopbn.getAttribute('forumdefstyle').valueOf());
  8.         picstyle = picstyle && !forumdefstyle;
  9.         var autopagenum = 0;
  10.         var maxpage = (curpage + autopagenum) > totalpage ? totalpage : (curpage + autopagenum);

  11.         var loadstatus = 0;

  12.         autopbn.onclick = function() {
  13.                 var oldloadstatus = loadstatus;
  14.                 loadstatus = 2;
  15.                 autopbn.innerHTML = '正在加载, 请稍后...';
  16.                 getnextpagecontent();
  17.                 loadstatus = oldloadstatus;
  18.         };

  19.         if(autopagenum > 0) {
  20.                 window.onscroll = function () {
  21.                         var curtop = Math.max(document.documentElement.scrollTop, document.body.scrollTop);
  22.                         if(curtop + document.documentElement.clientHeight + 500 >= document.documentElement.scrollHeight && !loadstatus) {
  23.                                 loadstatus = 1;
  24.                                 autopbn.innerHTML = '正在加载, 请稍后...';
  25.                                 setTimeout(getnextpagecontent, 1000);
  26.                         }
  27.                 };
  28.         }

  29.         function getnextpagecontent() {

  30.                 if(curpage + 1 > totalpage) {
  31.                         window.onscroll = null;
  32.                         autopbn.style.display = 'none';
  33.                         return;
  34.                 }
  35.                 if(loadstatus != 2 && curpage + 1 > maxpage) {
  36.                         autopbn.innerHTML = '下一页 &raquo;';
  37.                         if(curpage + 1 > maxpage) {
  38.                                 window.onscroll = null;
  39.                         }
  40.                         return;
  41.                 }
  42.                 curpage++;
  43.                 var url = nextpageurl + '&t=' + parseInt((+new Date()/1000)/(Math.random()*1000));
  44.                 var x = new Ajax('HTML');
  45.                 x.get(url, function (s) {
  46.                         s = s.replace(/\n|\r/g, '');
  47.                         if(s.indexOf("id="autopbn"") == -1) {
  48.                                 $("autopbn").style.display = "none";
  49.                                 window.onscroll = null;
  50.                         }

  51.                         if(!picstyle) {
  52.                                 var tableobj = $('threadlisttableid');
  53.                                 var nexts = s.match(/\<tbody id="normalthread_(\d+)"\>(.+?)\<\/tbody>/g);
  54.                                 for(i in nexts) {
  55.                                         if(i == 'index' || i == 'lastIndex') {
  56.                                                 continue;
  57.                                         }
  58.                                         var insertid = nexts[i].match(/<tbody id="normalthread_(\d+)"\>/);
  59.                                         if(!$('normalthread_' + insertid[1])) {

  60.                                                 var newbody = document.createElement('tbody');
  61.                                                 tableobj.appendChild(newbody);
  62.                                                 var div = document.createElement('div');
  63.                                                 div.innerHTML = '<table>' + nexts[i] + '</table>';
  64.                                                 tableobj.replaceChild(div.childNodes[0].childNodes[0], tableobj.lastChild);
  65.                                         }
  66.                                 }
  67.                         } else {
  68.                                 var nexts = s.match(/\<li style="width:\d+px;" id="picstylethread_(\d+)"\>(.+?)\<\/li\>/g);
  69.                                 for(i in nexts) {
  70.                                         var insertid = nexts[i].match(/id="picstylethread_(\d+)"\>/);
  71.                                         if(!$('picstylethread_' + insertid[1])) {
  72.                                                 $('threadlist_picstyle').innerHTML += nexts[i];
  73.                                         }
  74.                                 }
  75.                         }
  76.                         var pageinfo = s.match(/\<span id="fd_page_bottom"\>(.+?)\<\/span\>/);
  77.                         nextpageurl = nextpageurl.replace(/&page=\d+/, '&page=' + (curpage + 1));

  78.                         $('fd_page_bottom').innerHTML = pageinfo[1];
  79.                         if(curpage + 1 > totalpage) {
  80.                                 autopbn.style.display = 'none';
  81.                         } else {
  82.                                 autopbn.innerHTML = '下一页 &raquo;';
  83.                         }
  84.                         loadstatus = 0;
  85.                 });
  86.         }

  87. })();
复制代码

[ib]先看参数:

    var autopbn = $('autopbn');//代表“加载更多”按钮的ID,可以获取对应上面的一下其他参数如下

    var nextpageurl = autopbn.getAttribute('rel').valueOf();//获取下一页数据的地址

    var curpage = parseInt(autopbn.getAttribute('curpage').valueOf());//当前页数

    var totalpage = parseInt(autopbn.getAttribute('totalpage').valueOf());//总页数

    var picstyle = parseInt(autopbn.getAttribute('picstyle').valueOf());//图片风格(扩展不必要)

    var forumdefstyle = parseInt(autopbn.getAttribute('forumdefstyle').valueOf());//版块默认风格(扩展不必要)

    picstyle = picstyle && !forumdefstyle;//风格判断(扩展不必要)

   var autopagenum = 0;//是否自动加载更多(当页面下拉时)默认为0不自动加载,如果设置大于0,则是可自动加载的页数,超过此页数后将出现“下一页”按钮。

    var maxpage = (curpage + autopagenum) > totalpage ? totalpage : (curpage + autopagenum);//最大页的判断结合自动加载的页数,决定出现“下一页”或者“加载更多”,还是隐藏此按钮。

    var loadstatus = 0;//加载状态标记


接下来是绑定事件:一个是onclick,一个是onscroll,功能类似。

    loadstatus = 1;//更改状态
    autopbn.innerHTML = '正在加载, 请稍后...';//更改按钮字样
    setTimeout(getnextpagecontent, 1000);//关键——调用获取加载数据主函数。

最后就是加载数据的主函数:getnextpagecontent 的函数体定义。

前面两大块就是判断,”加载中“按钮的显示与字样。最关键的是:
  1. var x = new Ajax('HTML');
  2. x.get(url, function (s) {}
复制代码

此函数功能是获取指定URL的内容并插入到页面中。
本文的细节与重点都在此间。主要有三点:
1、      s = s.replace(/\n|\r/g, '');
            if(s.indexOf("id=\"autopbn\"") == -1) {
                $("autopbn").style.display = "none";
                window.onscroll = null;
            }
注意红色部分一定要替换成自己定义的”加载中“按钮的ID

2、var tableobj = $('threadlisttableid');

041909lipb4b0b3pp44ixw.jpg.thumb.jpg


如图所示,红色部分与途中高亮显示的是所有要填加载的数据的共同的容器或者说是父标签的ID,这个必须有,下面插入新数据时必须用到。

3、var nexts = s.match(/\<tbody id="normalthread_(\d+)"\>(.+?)\<\/tbody>/g);
     var insertid = nexts.match(/<tbody id="normalthread_(\d+)"\>/);

注意红色部分,是负责在ajax获取对应url的html数据后检索需要的数据的,因此建议此段具有正则匹配的高效性与可操作性。避免使用太平常标签例如 div(匹配不精确),或者太复杂(不容易匹配)。

      if(!$('normalthread_' + insertid[1])) {
                        var newbody = document.createElement('tbody');

后面这两句注意,新建DOM元素的名字的统一规律,这样样式才能统一。

针对第3点,举个实例:(如下图)

041908n00xh5x0yihie10x.jpg.thumb.jpg


在实际项目中,遇到了以高亮显示的为数据基本主元素的数据集合。就是div元素,这样为了js计算方便,就需要把其内部的div元素尽量去掉,所有div外部再增家一个容器功能的父元素,此例中为threaddaily_box

这样,在js猪代码中应该为:

var tableobj = $('threadsdaily_box');
                var nexts = s.match(/\<div id="threadlist_(\d+)" class="tl"\>(.+?)\<\/div>/g);
                for(i in nexts) {
                    if(i == 'index' || i == 'lastIndex') {
                        continue;
                    }
                    var insertid = nexts.match(/<div id="threadlist_(\d+)" class="tl"\>/);
                    if(!$('threadlist_' + insertid[1])) {

                        var newbody = document.createElement('div');
                        tableobj.appendChild(newbody);
                        var div = document.createElement('div');
                        div.innerHTML = '<div>' + nexts + '</div>';
                        tableobj.replaceChild(div.childNodes[0].childNodes[0], tableobj.lastChild);
                    }
                }

注意所有红色部分的对应关系。

另外,此示例中把 var autopagenum = 0; 的值设为100足够用了。或者再大500-1000亦可。

再遇到类似问题,可以参照本文做相应调整和修改。


(本文完)

孺子牛原创,转载请说明。



上一篇:我想看下1314study的rewrite规则
下一篇:死海与盐湖win7主题软件下载[下么]
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1314学习网 ( 浙ICP备10214163号 )

GMT+8, 2025-5-1 23:31

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表