InstantClick 网页预加载 让秒开不再是梦
感谢@Jimmy.
前段时间当我在使用ActionBox主题(即将发布)的时候,大家是不是感觉微狐网的各个页面几乎是秒开?那是因为我在Jimmy的建议下采用了一个叫instantclick的JS库,现在分享给大家。
这个JS库适用于所有现代网页,当然本文着重介绍Typecho下的使用方法。
尽管网络带宽不断增加,但网站并没有更快很多。这是因为最大的瓶颈在于页面加载的延迟。在访问者点击一个链接之前,鼠标会悬停在链接上面,这两个事件之间通常有200ms~300ms的间隔,InstantClick 利用这个时间间隔预加载页面。这样当你点击页面的时候,其实页面已经加载到本地了,呈现当然也就会很快。
InstantClick 使用了 pushState 和 Ajax 技术,这个组合被称为 pjax。
项目主页:传送门
通用:初始化InstantClick
... <script src="http://www.microhu.com/instantclick.min.js" data-no-instant></script> <script data-no-instant>InstantClick.init();</script> </body> </html>
这样全站链接就实现了预加载,使用Chrome来感受下你网站的蜕变吧。
自带进度条设置
Instantclick支持进度条,通过调整#instantclick-bar的Background实现颜色修改。
#instantclick-bar { background: white; }
当然不想用也可以关闭它。
#instantclick { display: none; }
黑名单机制
InstantClick默认采用黑名单机制,用来解决可能会导致出现冲突的情况,如:Google AD、多说评论等。
在<script>中加data-no-instant将JS加入预加载黑名单,会解决这个问题。
百度统计等JS代码也需要加入data-no-instant,否则可能会导致统计不全等问题。
Typecho下的BUG
在Typecho平台下,若使用原生评论系统又采用了InstantClick,会导致回复按钮无法定位的问题,给Typecho的评论JS加入了data-no-instant依然有问题,估计是产生了冲突,Jimmy给了我一个解决方案:
在主题Comments.php末尾再次放入Typecho评论JS。
Typecho 1.0+
<script type="text/javascript"> (function () { window.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-1'), 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-1'), 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> <script type="text/javascript"> (function () { var event = document.addEventListener ? { add: 'addEventListener', focus: 'focus', load: 'DOMContentLoaded' } : { add: 'attachEvent', focus: 'onfocus', load: 'onload' }; document[event.add](event.load, function () { var r = document.getElementById('respond-post-1'); if (null != r) { var forms = r.getElementsByTagName('form'); if (forms.length > 0) { var f = forms[0], textarea = f.getElementsByTagName('textarea')[0], added = false; if (null != textarea && 'text' == textarea.name) { textarea[event.add](event.focus, function () { if (!added) { var input = document.createElement('input'); input.type = 'hidden'; input.name = '_'; input.value = (function () { var _a8C5A = //'xr' '8d0'+//'vI' 'vI'+/* 'mj'//'mj' */''+//'P' '06'+'d'//'chS' +//'wo' '0ef'+'41'//'9G' +'8c8'//'R' +//'p1' 'd0'+//'mi' 'mi'+'baf'//'lu' +'c'//'dm' +//'ED' '1a9'+//'Lh' 'd9'+'6'//'luM' +//'xH' 'f1'+//'W' '2c7'+'f'//'f' +//'9' '9'+//'Nd' 'Nd'+/* '8ys'//'8ys' */''+''///*'6Yc'*/'6Yc' +//'H' '0', _LceE8M = [[3,5],[16,18],[31,32],[31,32],[31,33]]; for (var i = 0; i < _LceE8M.length; i ++) { _a8C5A = _a8C5A.substring(0, _LceE8M[i][0]) + _a8C5A.substring(_LceE8M[i][1]); } return _a8C5A; })(); f.appendChild(input); added = true; } }); } } } }); })(); </script>
Typecho 0.9
<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-2095'), 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-2095'), 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>