JavaScript 轻松搞定快捷留言功能 只需一行代码


Posted in Javascript onApril 01, 2010

别急,方法非常简单,还是先听我说说它的来历吧...

最开始,快捷留言这个功能要追溯到发表[AjaxControlToolkitTests自动测试框架完全解析之一:架构篇]这篇文章的时候,当时它纯粹是那篇文章的副产品,本来没太在意,本想只是给像我一样的懒人准备的一条捷径而已,后来因为没有提示这个功能会直接自动提交留言,还引起了几枚同学的不满意,于是后来又在醒目位置加上了提示:[提示:快捷链接会直接推荐并提交留言信息。],才平息了局势;

再后来,有部分同学可能是鼠标太高级,连击速度特别快的原因,每次使用我的快捷留言功能都会把五个(我要顶,路过,期待下一篇,太棒了,我要推荐)快捷链接都全部点一遍才过瘾,本来嘛,我放那么多快捷链接是希望给大家多提供几种选择,本意是不希望您每个都点一遍的,结果本来是出于为懒人提供的懒工具,却让人突然变勤劳了,实在是罪过。大家都这么勤劳,我可受不起,留言搞得跟聊天室刷屏一样,究其根本,还是原来的程序写得太简单,没有考虑细节,于是现在只留下了两个快捷链接,并且在程序上加了限制,这样就不至于会刷屏了。

再再后来,就是最近几天,我发现快捷留言的功能被越来越多的人加到了自己的博客里,昨天看到这篇文章(here)更是几乎原封不动地白盒拷贝了我的快捷留言功能的代码。这些应用让我重新思考快捷留言这个小功能的定位,客观地说,这个功能其实是对博客园现有留言功能的一个很好的扩展!那么,与其让人反复地去重新制作轮子,为啥不提供一个公共的扩展给大家直接使用呢?
基于以上历史原因,经过几个小时的努力,新版的通用快捷留言功能诞生了!这个版本的目标就是做到简单通用,其他博客园的博主只需简单的引用就可以直接在自己的博客里添加快捷留言功能了!目前该功能定为v1.0bate版,还有一些特性待完善,未来版本会提供更多的用户自定义设置功能,有什么新的想法也会逐步加进去,所以如果您希望未来能够自动升级新版本,就直接引用我这里的文件即可,所有使用这个脚本的用户都会同时同步更新。
其实用法真的很简单,只需要在[后台管理]->[设置]->[页首Html代码]的文本框里,填入下面这句话就行了。

//放在[后台管理]->[设置]->[页首Html代码]的文本框里 
<script language="javascript" type="text/javascript" src="http://files.cnblogs.com/justinw/jMsg.js"></script>

具体如下图所示:
JavaScript 轻松搞定快捷留言功能 只需一行代码
这里就是整个通用快捷留言功能的源代码了,时间很短,代码没有经过严格的测试,所以也请大家先实际使用测试一下,欢迎您批评指正!代码都很简单,我也加了很多注释,这里就不再累述了,有问题直接留言就行了。
//作者:Justin 
//版权:转载请保留出处即可。 
//版本:V1.0 beta 
//最后更新:201003300330 
//备注:如有问题,可以优先到 http://www.cnblogs.com/justinw/archive/2010/03/30/1700190.html 留言提问。 //--begin--jMsg--- 
function jMsg() { } 
//初始化动作 
jMsg.prototype.setup = function() { 
jMsg.loadEvent(this.combat); 
//jMsg.loadEvent(jMsg.msgDIV); 
jMsg.msgDIV(); 
} 
//提交留言信息 
jMsg.prototype.post = function(msg) { 
//这里通过判断HaveUp标志位,来防止反复提交相同留言。 
if (window.top.HaveUp) { 
alert('您已经顶过了!谢谢朋友 :)'); 
return; 
} 
var txt = document.getElementById('tbCommentBody'); 
if (txt != null) { 
txt.style.backgroundColor = "#E4F5FF"; 
var date = new Date(); 
txt.value = msg; 
txt.focus(); 
//如果提交过一次快捷留言,HaveUp就设置为true 
//每次重新进入页面,HaveUp就会被初始化。 
window.top.HaveUp = true; 
//这是博客园提交留言用的方法,通过这里正是提交留言。 
//如果没有登录就直接在客户端调用这个方法,内部会抛个错。(博客园代码问题,没有判空) 
PostComment(); 
} 
else { 
//目前博客园功能上约束只有登录后才能提交留言。 
//如果找不到tbCommentBody元素,可以认为当前用户没有登录。 
alert("使用博客园留言功能需要先登录哦!"); 
} 
} 
//推荐 
jMsg.prototype.recommend = function() { 
var diggit = jMsg.getElementsByClassName('diggit'); 
if ((diggit) && (diggit[0])) { 
diggit[0].onclick(); 
} 
else { 
alert("Debug:推荐按钮的ClassName改名了!"); 
} 
} 
//反对 
jMsg.prototype.combat = function() { 
var buryitMsg = function() { 
//目前博客园推荐和反对都是不记名的,被反对了当然希望知道原因啦。 
//这个功能只能做到防君子不防小人,仅仅是给了个提示而已。 
var txt = document.getElementById('tbCommentBody'); 
if (txt != null) { 
alert('这枚同学,非常希望能听到您的宝贵意见,请赐教...'); 
txt.style.backgroundColor = "#fe9ab3"; 
txt.focus(); 
} 
} 
var buryit = jMsg.getElementsByClassName('buryit'); 
if ((buryit) && (buryit[0])) { 
jMsg.addEvent(buryit[0], "click", buryitMsg); 
} 
} 
//提交留言的同时推荐 
jMsg.prototype.superPost = function(msg) { 
this.post(msg); 
this.recommend(); 
} 
//附加onload事件 
jMsg.loadEvent = function(fn) { 
var oldonload = window.onload; 
if (typeof window.onload != 'function') { 
window.onload = fn; 
} else { 
window.onload = function() { 
oldonload(); 
fn(); 
} 
} 
} 
//附加事件 
jMsg.addEvent = function(obj, type, fn) { 
if (obj.addEventListener) 
obj.addEventListener(type, fn, true); 
else if (obj.attachEvent) { 
obj.attachEvent("on" + type, function() { 
fn(); 
}); 
} 
} 
//通过ClassName找到DOM元素 
jMsg.getElementsByClassName = function(n) { 
var el = [], 
_el = document.getElementsByTagName('*'); 
for (var i = 0; i < _el.length; i++) { 
if (_el[i].className == n) { 
el[el.length] = _el[i]; 
} 
} 
return el; 
} 
//快捷留言的浮动导航条 
jMsg.msgDIV = function() { 
//是否出现浮动条。 
if (!(window.location.href.indexOf(".html") > -1)) return; 
//动态计算浮动滚动条的位置 
lastScrollY = 0; 
var beat = function() { 
var diffY; 
if (document.documentElement && document.documentElement.scrollTop) 
diffY = document.documentElement.scrollTop; 
else if (document.body) 
diffY = document.body.scrollTop 
else 
{ /*Netscape stuff*/ } 
percent = .1 * (diffY - lastScrollY); 
if (percent > 0) percent = Math.ceil(percent); 
else percent = Math.floor(percent); 
document.getElementById("msgDiv").style.top = parseInt(document.getElementById("msgDiv").style.top) + percent + "px"; 
lastScrollY = lastScrollY + percent; 
} 
msgDivCode = "<div id=\"msgDiv\" style='z-index:2010; right:2px; top:400px; position:absolute;'><strong><span style=\"color: red; font-size: 10pt;\">[快捷留言:点击下面链接后会直接提交留言信息。]</span></strong><br /><img src=\"/upload/2010-4/20100401005300831.gif\" /><a onclick=\"$jMsg.superPost('好贴!我顶你!');return false;\" href=\"###\"><span style=\"font-size: 30pt;\">我要顶!</span></a> <a onclick=\"$jMsg.superPost('好贴!路过!');return false;\" href=\"###\"><span style=\"font-size: 18pt;\">路过</span></a></div>"; 
document.write(msgDivCode); 
window.setInterval(beat, 120); 
} 
//--end--jMsg--- 
//todo:提供设置是否显示浮动条的接口 
//todo:提供自定义浮动条图片的接口 
//todo:提供完全自定义浮动条内容的接口 
//todo:提供浮动条以外的交互模式接口 
var $jMsg = new jMsg(); 
$jMsg.setup();

Update:201003301250->为维护博客园的推荐排名机制的公平有效和世界和平,特将superPost方法修正为不默认自动推荐文章,而是弹出提示框询问用户“是否要同时推荐该篇文章”,原来的[路过]链接改为使用post方法提交,只提交快捷留言信息,不会自动推荐:
jMsg.prototype.superPost = function(msg) { 
this.post(msg); 
//这里增加询问功能,不支持自动直接推荐 
if (confirm("您是否要同时推荐该篇文章呢?")) { 
this.recommend(); 
} 
}

作者:Justin
Javascript 相关文章推荐
表单项的name命名为submit、reset引起的问题
Dec 22 Javascript
JQuery1.6 使用方法三
Nov 23 Javascript
jqGrid增加时--判断开始日期与结束日期(实例解析)
Nov 08 Javascript
JavaScript中的this关键字使用方法总结
Mar 13 Javascript
JavaScript基本语法讲解
Jun 03 Javascript
jQuery webuploader分片上传大文件
Nov 07 Javascript
JavaScript-定时器0~9抽奖系统详解(代码)
Aug 16 Javascript
浅谈关于.vue文件中style的scoped属性
Aug 19 Javascript
vue-cli构建项目使用 less的方法
Oct 04 Javascript
如何根据业务封装自己的功能组件
Apr 19 Javascript
Vue项目接入Paypal实现示例详解
Jun 04 Javascript
多个Vue项目部署到服务器的步骤记录
Oct 22 Javascript
Javascript 类与静态类的实现
Apr 01 #Javascript
多浏览器支持的右下角浮动窗口
Apr 01 #Javascript
js 多浏览器分别判断代码
Apr 01 #Javascript
JS 遮照层实现代码
Mar 31 #Javascript
js压缩工具 yuicompressor 使用教程
Mar 31 #Javascript
jQuery 遍历json数组的实现代码
Sep 22 #Javascript
Javascript load Page,load css,load js实现代码
Mar 31 #Javascript
You might like
PHP session常见问题集锦及解决办法总结
2007/03/18 PHP
php 中文处理函数集合
2008/08/27 PHP
PHP5中实现多态的两种方法实例分享
2014/04/21 PHP
Codeigniter(CI)框架分页函数及相关知识
2014/11/03 PHP
php实现的农历算法实例
2015/08/11 PHP
Zend Framework校验器Zend_Validate用法详解
2016/12/09 PHP
javascript 常用关键字列表集合
2007/12/04 Javascript
jquery构造器的实现代码小结
2011/05/16 Javascript
JavaScript原型继承之基础机制分析
2011/08/26 Javascript
EasyUI的treegrid组件动态加载数据问题的解决办法
2011/12/11 Javascript
Javascript中的delete介绍
2012/09/02 Javascript
jQuery中index()方法用法实例
2014/12/27 Javascript
DOM基础教程之使用DOM设置文本框
2015/01/20 Javascript
jQuery Ajax Post 回调函数不执行问题的解决方法
2016/08/15 Javascript
Vue.js结合Ueditor富文本编辑器的实例代码
2017/07/11 Javascript
Vue中建立全局引用或者全局命令的方法
2017/08/21 Javascript
微信小程序实现鼠标拖动效果示例
2017/12/01 Javascript
对mac下nodejs 更新到最新版本的最新方法(推荐)
2018/05/17 NodeJs
浅探express路由和中间件的实现
2019/09/30 Javascript
JavaScript中break、continue和return的用法区别实例分析
2020/03/02 Javascript
springboot+vue+对接支付宝接口+二维码扫描支付功能(沙箱环境)
2020/10/15 Javascript
[02:53]DOTA2英雄基础教程 山岭巨人小小
2013/12/09 DOTA
python网络爬虫学习笔记(1)
2018/04/09 Python
Python基于win32ui模块创建弹出式菜单示例
2018/05/09 Python
在scrapy中使用phantomJS实现异步爬取的方法
2018/12/17 Python
Python基于BeautifulSoup和requests实现的爬虫功能示例
2019/08/02 Python
pycharm创建scrapy项目教程及遇到的坑解析
2019/08/15 Python
python+adb命令实现自动刷视频脚本案例
2020/04/23 Python
为什么是 Python -m
2020/06/19 Python
html5 input属性使用示例
2013/06/28 HTML / CSS
美国杰西潘尼官网:JCPenney
2019/06/12 全球购物
应届生自我鉴定
2013/12/11 职场文书
《燕子》教学反思
2014/02/18 职场文书
工作作风懒散检讨书
2014/10/29 职场文书
《刺客之王:C罗全景传记》:时代从来不会亏待手艺人
2019/11/28 职场文书
MySQL 数据类型详情
2021/11/11 MySQL