上一篇文章的全站式AJAX其实是不够完美的,而且脚本也很复杂,本来已经被我放弃了,但前几天我上一篇文章中来了一位不速之客:jimmy 提到另一种方式实现全站AJAX,就是PJAX。
对于PJAX,我虽早有耳闻但没去细看(当初托百度的福,让我搜到的全是垃圾!)。对于jimmy的网站,我当初只是随手点了评论上的连接进去看一下,随即发现全站AJAX整合得非常好让我对全站AJAX效果又重燃希望。碰巧过几天就是周末+中秋节+公司福利再放一天假,于是小长假连休4天,是个好机会。
花了三天时间终于搞定,过程就不说了。
全站式AJAX(包括评论)
HTML播放器(兼容移动设备)
自适应PC与iPad
NProgress进度条
timthumb自动缩略图
简易LightBox效果(图片可原图放大)
手机端的自适屏功能留到下次更新再做好了 XD
接下来简单分享下心得吧。
要打造良好体验的全站式AJAX博客,我觉得至少需要这么三样东西:
PJAX(封装PUSHSTATE + AJAX)插件:https://github.com/defunkt/jquery-pjax/
AjaxComments(Willin插件版):http://kan.willin.org/typecho/typecho-ajax-comments.html
NProgress进度条插件 :http://ricostacruz.com/nprogress/
当然其他的例如scrollLoading/LazyLoad(图片分屏加载插件),Audioplayer.js/Audio.js(HTML5音乐播放插件)等,有兴趣的自行选择。
官网都有简单的调用教程,应该不用我多说什么。
但有两点,我觉得大家一定会遇到的。
解决方法嘛,自然就是把AjaxComments的脚本提取出来囖。
如果觉得提取有困难的,请看:
function ajaxcomments(){
$body = (window.opera) ? (document.compatMode == "CSS1Compat" ? $('html') : $('body')) : $('html,body');
var
comments_order = 'ASC',
comment_list = '.comment-list',
comments = '.comments-title',
comment_reply = '.comment-reply',
comment_form = '#comment-form',
respond = '.respond',
textarea = '.textarea',
submit_btn = '.submit',
new_id = '',
parent_id = '';
$(submit_btn).attr('disabled', false);
click_bind();
$(comment_form).submit(function() {
$(submit_btn).attr('disabled', true).fadeTo('slow', 0.5);
$.ajax({
url: $(this).attr('action'),
type: $(this).attr('method'),
data: $(this).serializeArray(),
beforeSend: function() {
NProgress.start()
$(comment_list).fadeTo(100,0.1)
},
complete: function() {
$(comment_list).fadeTo(600,1)
NProgress.done()
},
success: function(data) {
var wait = 5;
$submit = $('#comment-form .submit');
var submit_val = $submit.val();
function countdown() {
if (wait > 0) {
$submit.val(wait);
$submit.attr('disabled', true).fadeTo('slow', 0.5);
wait--;
setTimeout(countdown, 1000)
} else {
$submit.val(submit_val).attr('disabled', false).fadeTo('slow', 1);
wait = 5
}
}
$(countdown);
try {
if (!$(comment_list, data).length) {
if (data.indexOf('Error') > -1) {
alert("评论发送过于频繁,请稍后再试。")
}
} else {
$(textarea).val('');
new_id = $(comment_list, data).html().match(/id=\"?comment-\d+/g).join().match(/\d+/g).sort(function(a, b) {
return a - b
}).pop();
data = $('#comment-' + new_id, data).hide();
$('#reply-to-' + new_id, data);
if (!$(comment_list).length) $(respond).before('<ol class="comment-list"><\/ol>');
parent_id ? (comments_order == 'DESC' && $('#' + parent_id + ' li').length ? $('#' + parent_id + ' li:first').before(data) : $(respond).before(data), parent_id = '') : $(comment_list + ':first').append(data);
$('#comment-' + new_id).fadeIn();
$(comments).length ? (n = parseInt($(comments).text().match(/\d+/)), $(comments).text($(comments).text().replace(n, n + 1))) : 0;
TypechoComment.cancelReply();
$(comment_reply + ' a, #cancel-comment-reply-link').unbind('click');
click_bind();
$('#author').length ? countdown() : $(submit_btn).attr('disabled', false).fadeTo('slow', 1);
$body.animate({
scrollTop: $('#comment-' + new_id).offset().top - 200
},
500)
}
} catch(e) {
alert('Error!\n\n' + e)
}
}
});
return false
});
function click_bind() {
$(comment_reply + ' a').click(function() {
$body.animate({
scrollTop: $(respond).offset().top - 180
},
400);
h = $(this)[0].href;
parent_id = 'comment-' + h.substring(h.indexOf('replyTo=') + 8, h.indexOf('#'));
$(textarea).focus()
});
$('#cancel-comment-reply-link').click(function() {
parent_id = ''
})
}
};
如果你直接使用这个js,记住针对自己的模板修改类名,不做修改是肯定无法使用的。因为我的类名是按照我个人习惯来搞的。
这个问题是,当你实现了全站AJAX和评论AJAX以后,发现点击评论上的‘回复’或者‘取消回复’会导致页面刷新。
当初我的AJAX评论还不是很稳定,时不时报错。跟jimmy交流的时候,他提到我会遇到这个回复按钮的问题(确实遇到了,但我还没到解决这个问题的时候),他直接给了我解决方案,赞一个XD。
原文地址:Typecho下回复按钮的问题
为了避免其他因素导致文章无法打开,我这里留一份底:
1.打开主题的comments.php
2.找到<?php $comments->listComments(); ?>
3.在前后加上<div data-no-instant>和</div>
如下
<div data-no-instant>
<?php $comments->listComments(); ?>
</div>
最后在comments.php的尾部加上以下代码
<script type="text/javascript">
//<![CDATA[
var TypechoComment = {
dom : function (id) {
return document.getElementById(id);
},
create : function (tag, attr) {
var el = document.createElement(tag);
for (var key in attr) {
el.setAttribute(key, attr[key]);
}
return el;
},
reply : function (cid, coid) {
var comment = this.dom(cid), parent = comment.parentNode,
response = this.dom('respond-post-286'), input = this.dom('comment-parent'),
form = 'form' == response.tagName ? response : response.getElementsByTagName('form')[0],
textarea = response.getElementsByTagName('textarea')[0];
if (null == input) {
input = this.create('input', {
'type' : 'hidden',
'name' : 'parent',
'id' : 'comment-parent'
});
form.appendChild(input);
}
input.setAttribute('value', coid);
if (null == this.dom('comment-form-place-holder')) {
var holder = this.create('div', {
'id' : 'comment-form-place-holder'
});
response.parentNode.insertBefore(holder, response);
}
comment.appendChild(response);
this.dom('cancel-comment-reply-link').style.display = '';
if (null != textarea && 'text' == textarea.name) {
textarea.focus();
}
return false;
},
cancelReply : function () {
var response = this.dom('respond-post-286'),
holder = this.dom('comment-form-place-holder'), input = this.dom('comment-parent');
if (null != input) {
input.parentNode.removeChild(input);
}
if (null == holder) {
return true;
}
this.dom('cancel-comment-reply-link').style.display = 'none';
holder.parentNode.insertBefore(response, holder);
return false;
}
}
//]]>
</script>
嗯,基本上就这些。
如果你对底层的AJAX基础有兴趣,可以阅读: Typecho实现全站式Ajax的方法
沙发
顺便测试邮件 XD
真是个不借的方法。
看见你也用上了 :)
代码溢出了。
呃…… 评论表单placehold挡住了填写内容。
请问您是使用什么浏览器呢?我这边在chrome 和firefox ie10 下看均无问题。
我用的 Firefox 32.0.3 ,
placehold问题已经解决。代码没有换行。
感谢,已用上,折腾了几天,评论不好搞,索性弄了多说的
最新版的1.0 在ajax评论方面做了些修改,上面这些代码不能用(这些是0.9时代的东西)。
2021 年 实验有效!!
测试看看