menu ZigZagK的博客
account_circle

正在努力加载中QAQ

在PJAX的基础上使用AJAX评论等功能
apps Typecho
local_offer 查看标签
comment 9 条评论

终于把AJAX评论搞好了QwQ,效果可以在这篇文章下面评论试试(所以在本页可以随意划水2333333)。

AJAX评论

膜拜dalao

绛木子:不使用插件实现Ajax评论功能

QQdie:Typecho不使用插件实现Ajax评论功能

实现方法

因为我js菜爆了,网上传统的基于js的AJAX评论我并不是很能看懂QAQ。

最近发现绛木子这种比较好理解,而且容易魔改。就花了一段时间弄了一下。

的确是套(抄)上去就能用了,但是有一个很尴尬的问题……绛木子和QQdie现在用的主题都没有PJAX,而我在加上去之后和PJAX撞了……

兼容PJAX

绛木子教程里说的开启反垃圾保护是为了不验证来源页,但是不知道什么奥妙重重的原因,如果主题有PJAX,那么就算开启反垃圾保护,在切换页面之后好像依然会验证来源页,导致无法评论(或者PJAX失效)。

魔改了好久之后我还是解决不了,于是索性把:

if($archive->request->get('_') != Helper::security()->getToken($archive->request->getReferer())){
    $archive->response->throwJson(array('status'=>0,'msg'=>_t('非法请求')));
}

这段给删了。结果就行了……

JS部分

这个还是得看主题怎么样自己定制啦……由于我把评论结构改成@式的了,所以这部分代码放到之后再给。

评论@式

实现方式

这个是自己瞎搞的……原理其实特智障。

先写了两个函数:

function GetCommentAt($coid){
    $db=Typecho_Db::get();$fa=$db->fetchRow($db->select('coid,author')->from('table.comments')->where('coid = ?',$coid));
    $content='<strong class="haveat"><a href="#comment-' . $fa['coid'] . '">@' . $fa['author'] .'&nbsp;</a></strong>';
    return $content;
}
function RewriteComment($comment){
    $content=convertSmilies($comment->content); //convertSmilies是表情转换
    if ($comment->parent) $content=GetCommentAt($comment->parent) . $content;
    return $content;
}

其实就是把父评论的信息从数据库里拿出来,再加到评论内容的前面。

为了将评论改为两层的,再把输出评论的部分改一下(下面给出的是框架):

<div id="<?php $comments->theId(); ?>">
    <?php if ($comments->levels==0) { ?>
    <div> <!-- 对于顶级评论,评论框包住子评论 -->
        <?php echo RewriteComment($comments); ?> <!-- 输出转化后的评论 -->
        <?php if ($comments->children) { ?>
            <div class="comment-children">
                <?php $comments->threadedComments($options); ?>
            </div>
        <?php } ?>
    </div>
    <?php } else { ?>
    <div> <!-- 对于非顶级评论,评论框不包住子评论 -->
        <?php echo RewriteComment($comments); ?>
    </div>
    <?php if ($comments->children) { ?>
    <div class="comment-children"> <!-- 子评论还是处在comment-children中以便定位 -->
        <?php $comments->threadedComments($options); ?>
    </div>
    <?php } ?>
    <?php } ?>
</div>
<?php } ?>

然后评论就变成两层式的了,那么也就可以进行“无限”嵌套并且样式不爆炸了QAQ:

function themeInit($archive) {
    Helper::options()->commentsMaxNestingLevels = 19260817; //评论"无限"层
    if ($archive->is('single') && $archive->request->isPost() && $archive->request->is('themeAction=comment')) ajaxComment($archive); //AJAX评论
}

评论无限加载(实验性)

效果就是将翻页改成点击加载更多。

PS:使用后发现此方法将引起一些问题,所以我就没在用了QAQ

膜拜dalao

枫叶:typecho 实现点击加载更多文章

实现方法

虽然是点击加载更多评论,但是原理和上面那篇教程里的一样。

不过因为Typecho没有单独输出评论下一页的函数,所以需要css里把除了下一页之外的东西隐藏掉……

PHP部分:

<?php $comments->pageNav('','查看更多评论',0,'',array('wrapTag' => 'div','wrapClass' => 'page-navigator','itemTag' => '','nextClass' => 'next mdui-btn mdui-btn-block mdui-ripple mdui-color-theme-accent mdui-m-b-1')); ?>

css部分:

div.page-navigator a:not([class~="next"]) {display:none;}

JS部分:

$('a.next').click(function() {
    $this = $(this);$this.hide();$("#commenet-load").show();
    var href = $this.attr('href');
    if (href != undefined) {
        $.ajax({
            url: href,
            type: 'get',
            error: function() {mdui.alert("评论加载出错了QAQ");},
            success: function(data) {
                //把下一页网站里的#allcomment拿出来加入当前页的#allcomment
                var $res = $(data).find('#allcomment');
                $("#allcomment").append($res);mdui.mutation();
                //把点击加载更多按钮的链接换成下一页的下一页
                var newhref = $(data).find('a.next').attr('href');
                if (newhref != undefined) {$('a.next').attr('href', newhref);}
                else {$('a.next').remove();}
            },
            complete: function() {
                $("#commenet-load").hide();$this.show();
            }
        });
    }
    return false;
});

总的JS部分

这里放的代码是上面AJAX评论的,综合了评论@式和评论无限加载:

$('#comment-form').submit(function(){
    var form = $(this), params = form.serialize();
    params += '&themeAction=comment';
    var appendComment = function(comment){
        //评论框样式,按照自己的主题调整QAQ
        var html = '<div id="comment-{coid}" class="mdui-panel" mdui-panel><div class="mdui-panel-item mdui-panel-item-open"><div class="mdui-panel-item-header"><div class="mdui-panel-item-title"><div class="comment-author mdui-chip mdui-hidden-xs-down"><img class="avatar mdui-chip-icon mdui-color-grey-200" src="{avatar}" alt="{author}" width="100" height="100" />\n<span class="fn mdui-chip-title">{authorurl}</span></div><div class="mdui-hidden-sm-up"><img class="avatar mdui-chip-icon mdui-color-grey-200" src="{avatar}" alt="{author}" width="100" height="100" /></div></div><div class="mdui-panel-item-summary"><span class="mdui-hidden-xs-down">{datetime}</span><span class="fn mdui-chip-title mdui-hidden-sm-up">{author}</span></div><i class="mdui-panel-item-arrow mdui-icon material-icons">keyboard_arrow_down</i></div><div class="comment-meta mdui-panel-item-body"><span class="mdui-typo-caption mdui-text-color-theme-accent mdui-hidden-sm-up">{datetime}<br></span>{content}<div class="mdui-chip">{ifauthor}</div><span class="comment-reply mdui-float-right"><a href="?replyTo={coid}#<?php $this->respondId(); ?>" onclick="return TypechoComment.reply(\'comment-{coid}\',{coid});" class="mdui-btn mdui-color-theme-accent mdui-ripple">回复</a></span>';
        $.each(comment,function(k,v){
            regExp = new RegExp('{'+k+'}', 'g');
            html = html.replace(regExp, v);
        });
        //#allcomment是所有评论的容器
        var el = $('#allcomment .comment-list:first');
        if(0 != comment.parent){
            //有父评论
            el = $('#comment-'+comment.parent);
            //.haveat是@的标记
            if (el.find('.haveat').length<1){
                //父评论是顶级评论(没有@)
                el = $('#comment-'+comment.parent).find('.comment-meta');
                //由于是顶级评论,所以需要在评论框里面插入子评论
                if(el.find('.comment-children').length < 1){
                    $('<div class="comment-children"><ol class="comment-list"></ol></div>').appendTo(el);
                } else if(el.find('.comment-children .comment-list').length < 1){
                    $('<ol class="comment-list"></ol>').appendTo(el.find('.comment-children'));
                }
            } else{
                //父评论不是顶级评论(有@),那么要加在评论框后面而不是里面
                if(el.find('.comment-children').length < 1){
                    $('<div class="comment-children"><ol class="comment-list"></ol></div>').appendTo(el);
                } else if(el.find('.comment-children .comment-list').length < 1){
                    $('<ol class="comment-list"></ol>').appendTo(el.find('.comment-children'));
                }
            }
            //定位到.comment-list插入评论
            el = $('#comment-'+comment.parent).find('.comment-children .comment-list:first');
        } else {
            if(el.length < 1){
                $('<ol class="comment-list"></ol>').appendTo($('#allcomment'));
                el = $('#allcomment .comment-list:first');
            } else {
                el = $('#allcomment .comment-list:first');
            }
            //定位到.comment-list插入评论
        }
        $(html).prependTo(el); //需要将较新的评论显示在前面,这样比较方便
    }
    //AJAX评论,里面的提示框都是MDUI里现成的2333333
    $.ajax({
        url: '<?php $this->permalink();?>',
        type: 'POST',
        data: params,
        dataType: 'json',
        beforeSend: function() { mdui.snackbar({message:'正在提交评论QwQ',position:'right-bottom',timeout:'1000'});$('#commentsumbit').css('display','none');$('#commenting').css('display','block'); },
        complete: function() { mdui.mutation(); },
        success: function(result){
            if(1 == result.status){
                $('#commenting').css('display','none');$('#commentsumbit').css('display','block');
                    mdui.dialog({content:'评论成功啦ヾ(≧∇≦*)ゝ',onClose:function(){$('html,body').animate({scrollTop:$('#comment-'+result.comment.coid).offset().top},'fast');},cssClass:'mdui-dialog-alert',buttons:[{text:'ok'}]});
                appendComment(result.comment);
                var number=parseInt($('#commentsnumber').text())+1;
                $('#commentsnumber').text(number+" 条评论"); //评论数+1
                form.find('textarea').val('');form.find('textarea').css('height','');
                if ($('#cancel-comment-reply-link').css('display')!='none') $('#cancel-comment-reply-link').click();
            }else{
                mdui.alert(undefined === result.msg ? '发生了未知错误Orz' : result.msg);
            }
        },
        error:function(xhr, ajaxOptions, thrownError){
            mdui.alert('提交评论失败了QAQ');
        }
    });
    return false;
});

最后

其实这主要是篇给自己的总结文章,阅读过程中很有可能会觉得很混乱……有问题可以评论里提问,我有空(可能不太有,咕咕咕)会回复的QAQ。

版权声明:本博客所有文章除特别声明外,均采用 CC BY 4.0 CN协议 许可协议。转载请注明出处!
名称不能为空
email
邮箱不能为空,请填写正确格式
link
网址请用http://或https://开头
message
评论不能为空
资瓷Markdown和LaTeX数学公式
sentiment_very_satisfied
    2019-07-13 21:33:06ohmyga
    keyboard_arrow_down
    2019-07-13 21:33:06

    居然资瓷ajax评论了 赞 |´・w・)ノ

    remove_red_eye访客
      2019-07-13 21:33:50ohmyga
      keyboard_arrow_down
      2019-07-13 21:33:50
      @ohmyga 

      好高级的说((

      remove_red_eye
      访客
        2019-07-14 14:53:33ZigZagK
        keyboard_arrow_down
        2019-07-14 14:53:33
        @ohmyga 

        Dalao您的Blog不是早就有了吗QAQ
        (其实现在还有bug一堆

        account_circle
        博主
          2019-07-15 10:26:06ohmyga
          keyboard_arrow_down
          2019-07-15 10:26:06
          @ZigZagK 

          awsl 我是直接发送ajax请求再刷新页面的 你这直接插入评论 太高级了(

          remove_red_eye
          访客
          2019-07-14 23:07:42ZigZagK
          keyboard_arrow_down
          2019-07-14 23:07:42
          @ZigZagK 

          啊我这垃圾语文……我是说我的还有bug一堆QAQ

          account_circle
          博主
    2019-07-12 08:36:12初夏阳光
    keyboard_arrow_down
    2019-07-12 08:36:12

    测试一下

    remove_red_eye访客
    2019-06-17 20:39:53可耐的菊花茶
    keyboard_arrow_down
    2019-06-17 20:39:53

    前排兹瓷zigzag胖qwq

    remove_red_eye访客
      2019-06-22 20:48:33ZigZagK
      keyboard_arrow_down
      2019-06-22 20:48:33
      @可耐的菊花茶 

      你好好学竞赛去

      account_circle
      博主
    2019-06-16 09:28:52ZigZagK
    keyboard_arrow_down
    2019-06-16 09:28:52

    测试一下

    account_circle博主
keyboard_arrow_up