Typecho 全站 pjax 方案
其实最早添加 pjax 的时候就发现了评论会有问题,只是一直不知道怎么去解决,后来就放弃了。最近想出一种办法,使得全站 pjax 生效。
(可能不具有通用性,因为我使用的 Ajax 评论不是 willin kan 的那款)
搜索引擎搜到的有关 Typecho&pjax 的内容主要有如下几篇:
其中基本都要修改 Typecho 的内核代码,主要是 header 中的评论 js 输出,或者是用修改版 pjax.js。
引入 js 文件
<script src="//cdn.bootcss.com/jquery/2.1.4/jquery.min.js"></script>
<script src="//cdn.bootcss.com/jquery.pjax/1.9.6/jquery.pjax.min.js"></script>
pjax 初始化
function pjaxInit() {
var pjaxContainer = '#pjax-container',
pjaxSearchForm = '#search-form',
pjaxTimeout = 30000;
$(document).pjax('a[target!=_blank]', pjaxContainer, {
fragment: pjaxContainer,
timeout: pjaxTimeout
});
$(document).on('submit', 'pjaxSearchForm', function(event) {
$.pjax.submit(event, pjaxContainer, {
fragment: pjaxContainer,
timeout: pjaxTimeout
});
});
$(document).on('pjax:send', function() {
//载入动画
});
$(document).on('pjax:complete', function() {
//需要重载的插件
//载入动画结束
ajaxCommentRewrite();
});
}
干掉 TypechoComment
在 bindCommentReplyButton () 方法中加入
ajaxCommentRewrite();
ajaxCommentRewrite () 方法的具体代码
$(selector.commentReplyButton + ' a').prop('onclick', null).attr('href', 'javascript:;');
$(selector.commentCancelReplyLink).prop('onclick', null).attr('href', 'javascript:;');
原 Ajax 评论代码中需要修改的地方
TypechoComment.cancelReply();
替换为
cancelReply();
ajaxComments () 添加
removeTextareaEvent();
cancelReply () 方法的具体代码
function cancelReply() {
var response = $(selector.respondContainer)[0],
holder = $('#comment-form-place-holder')[0],
input = $('#comment-parent')[0];
if (null != input) {
input.parentNode.removeChild(input);
}
if (null == holder) {
return true;
}
$(selector.commentCancelReplyLink)[0].style.display = 'none';
holder.parentNode.insertBefore(response, holder);
return false;
}
removeTextarea () 方法的具体代码
function removeTextareaEvent() {
$(document).on('click', selector.submitTextarea, function() {
$(selector.submitForm + ' input[name="_"]:not(#comment_)').remove();
});
}
使用 jQuery 重新绑定回复按钮和取消回复按钮事件
$(document).on('click', selector.commentReplyButton, function() {
var cid = $(this).attr('data-cid'),
coid = $(this).attr('data-coid');
var comment = $('#' + cid)[0],
parent = comment.parentNode,
response = $(selector.respondContainer)[0],
input = $('#comment-parent')[0],
form = 'form' == response.tagName ? response : response.getElementsByTagName('form')[0],
textarea = response.getElementsByTagName('textarea')[0];
if (null == input) {
input = createElement('input', {
'type': 'hidden',
'name': 'parent',
'id': 'comment-parent'
});
form.appendChild(input);
}
input.setAttribute('value', coid);
if (null == document.getElementById('comment-form-place-holder')) {
var holder = createElement('div', {
'id': 'comment-form-place-holder'
});
response.parentNode.insertBefore(holder, response);
}
comment.appendChild(response);
$(selector.commentCancelReplyLink)[0].style.display = '';
if (null != textarea && 'text' == textarea.name) {
textarea.focus();
}
return false;
});
$(document).on('click', selector.commentCancelReplyLink, function() {
cancelReply();
});
createElement () 方法具体代码
function createElement(tag, attr) {
var el = document.createElement(tag);
for (var key in attr) {
el.setAttribute(key, attr[key]);
}
return el;
}
修改 comments.php
form 中添加 (注意把 wrap 修改为你对应的 pjaxContainer)
<input name="_" type="hidden" id="comment_" value="<?php echo Helper::security()->getToken(str_replace(array('?_pjax=%23wrap', '&_pjax=%23wrap'), '', Typecho_Request::getInstance()->getRequestUrl()));?>"/>
回复楼层按钮改为
<span class="reply" data-cid="comment-<?php $comments->coid();?>" data-coid="<?php $comments->coid();?>">
别忘了修改公共模板部分,通过添加 is_pjax () 方法来判断
function is_pjax()
{
return (isset($_SERVER['HTTP_X_PJAX']) && $_SERVER['HTTP_X_PJAX'] == 'true');
}
至此 Ajax 评论的问题基本解决
重载统计代码
在 pjax:success 中添加
if (window.ga) {
var location = window.location.pathname + window.location.search;
ga('send', 'pageview', {
'page': location,
'title': document.title
});
}
同时移除原来的
ga('send', 'pageview');