锁定老帖子 主题:【JS优化系列】一个通用公告系统的实现
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-08-17
最后修改:2009-09-12
之前一篇《【JS优化系列】从一个计时器的写法探讨js多种实现方式的优劣》的讨论让我学到不少东西,现在再来一篇,抛砖引玉。
站点的很多页面经常需要发一些公告,而每次发公告都需要开发同学手工来操作是很麻烦的,而且经常不够实时。因此写了一个通用公告系统,希望能将这份工作交由产品同学来操作。这里只写了“小黄条”一种形式的公告,其他形式实现方法类似。实现了可以“定时自动关闭”,“所有页面每次打开都显示小黄条”,“仅在第一次打开的页面显示一次”,“用户手动关闭后不再显示”功能。以此基本能满足日常运营需求。 先将代码和实现方式贴出,邀请大家一起探讨优化。
/** * 通用公告系统 * * @package pub_notice.js * @author jessezhang <jianguang.qq@gmail.com> * @date 2009-08-15 * @version 1.0.0 */ var LIB = LIB || {}; LIB .pubNotice = (function(){ var $id = function(id){return document.getElementById(id);} var $ = LIB ; /** * 小黄条 * * @access public * @param {json} json 小黄条属性 */ function yellowTips(json){ this._id = json["id"]; this._text = json["text"]; this._showType = json["showType"]; this._timeout = json["timeout"]; this._domId = "QQVIP_pubNotice_yellowTips_" + json["id"]; this._timer = null; } yellowTips.prototype = (function(){ /** * create一个小黄条 * * @access public */ function create(){ if(!_checkShowType.call(this))return ; //container标签为必须,诺没有container,则不显示小黄条 if(!$id("container"))return; var _nBox = document.createElement("div"); _nBox.id = this._domId; _nBox.className = "bulletin"; _nBox.innerHTML = "<button type=\"button\" class=\"bt_close_bulletin\" title=\"关闭\" onclick=\"javascript:document.getElementById('"+this._domId +"').style.display='none';QQVIP.cookie.set('" + this._domId + "', '2');\">X</button>" + this._text; document.body.insertBefore(_nBox,$id("container")); this._timeout && this.hide(this._timeout); $.cookie.set(this._domId,"1");//1:表示已经显示过该小黄条 } /** * 显示小黄条 * * @access public */ function show(){ $id(this.domId).style.display = ""; } /** * 隐藏小黄条的接口 * * @access public */ function hide() { var _this = this; if (this._timeout) { this._timer && clearTimeout(this._timer); this._timer = setTimeout(function(){_hide.call(_this);}, this._timeout); } else { _hide.call(_this); } } /** * 内部实现隐藏小黄条 * * @access private */ function _hide(){ this._timer && clearTimeout(this._timer); $id(this._domId).style.display = "none"; } /** * showType : 显示方式 * 1:所有页面每次打开都显示 * 2:只在第一次打开的页面显示一次 * 3:用户手动关闭后不显示 * * cookieValue : cookie存储的状态 * 1:已经显示过 * 2:用户手动关闭 */ function _checkShowType(){ if(this._showType == "1") return true; var cookieValue = $.cookie.get(this._domId); return (this._showType == "2" && cookieValue != "1" && cookieValue != "2") || (this._showType == "3" && cookieValue != "2"); } return { create : create, show : show, hide : hide } })() /** * 浮出层,建设中... * */ function floatLayer(obj){} /** * 弹出窗口,建设中... * */ function openWindow(obj){} /** * 将设置的url转化成验证页面地址的正则表达式 * * @access private * @param {istring} url 设置的url * @return {RegExp} 验证页面地址的正则表达式 */ function _regURL(url){ if (/^\^/.test(url)) { //以符号"^"开头的url都看成本身已经是正则表达式的形式了,不需要再处理 return new RegExp(url); } else { //不是以符号"^"开头的url都需要处理成正则表达式的形式, //主要对符号"/"和index.html、index.htm、index.php进行处理, //使得"http://vip.lib.com/index.html"、"http://vip.lib.com/"都可以被正确识别 var RegStr = url.replace(/(^[\w-:\/\.]*).*/, function($0, $1){ var ret = $1.replace(/\//g, "\/").replace(/\?/g, "\?"); var reg = new RegExp("(index.html|index.htm|index.php)$"); if (reg.test($1)) { ret = ret.replace(reg, function(a,b){ return "(("+b+")+|$|\\?|\\#)"; }); } else { ret = $1+"((index.html|index.htm|index.php)+|$|\\?|\\#)"; } return ret; }); return new RegExp(RegStr); } } /** * 判断当前页面的url是否符合要求 * * @access public * @param {istring} str 设置的验证url的字符串 */ function checkUrl(str){ var loaction = window.location; str = str.replace(/^\||\|$/g,""); var urls = str.split("|"); for(var j=0; j<urls.length; j++){ if(_regURL(urls[j]).test(loaction)){ return true; } } return false; } return { yellowTips : yellowTips, floatLayer : floatLayer, openWindow : openWindow, checkUrl : checkUrl }; })(); (function(){ var yellowTips = [ {id:1, url:'^http://vip.LIB .com/|', text:'<strong>LIB 宣:</strong><p>这是世界上最强大的紧急公告系统!</p>', showType:1, timeout:3*1000}, {id:2, url:'http://vip.LIB .com/mall/mall.php|http://vip.LIB .com/freedom_act/act.html|http://vip.LIB .com/my_status/my_status_index.php', text:'<strong>LIB 专区问题</strong><p>LIB 专区问题</p>', showType:2, timeout:0*1000}, {id:3, url:'http://vip.LIB .com/qq.html|http://vip.LIB .com/life.html|', text:'<strong>[LIB ]</strong><p>LIB 频道,生活公告ffff</p>', showType:3, timeout:0*1000} ] for(var i=0; i<yellowTips.length; i++){ if(LIB.pubNotice.checkUrl(yellowTips[i]["url"])){ new LIB.pubNotice.yellowTips(yellowTips[i]).create(); } } })() 目前的实现方式是,所有页面都在自身加载完成之后去加载这段代码。代码会通过页面的url来判断是否显示公告,以及显示哪几条公告。而设置的时候有两种方式,一种是输入特定页面的完全url,另一种是通过正则来匹配。在本实现中以传入的url是否以“^”符号其起始来判断是否当正则来处理(这种方式好坏大家可以一起探讨),如“^http://vip.lib.com/”表示发布到vip.lib.com域名下的所有页面,“http://vip.lib.com/”或者“http://vip.lib.com/index.html”表示仅仅发布到lib首页一个页面。 这里的代码将由管理后台生成,若没有没有公告,则所有代码为空,以节省流量。 在本例中应该有很多地方可以优化的,希望大家一起探讨优化。比如_regURL()这个函数的实现,我并没有做很多的考虑,肯定有很多可以优化的地方。还有实现方式上也有很多地方值得探讨,比如这样做所有页面都多了个请求,所有页面都会引入所有的公告内容,这样实现是否是最好的。代码是由管理后台生成的,那么产品同学输入内容的,在后台输出的时候是不是需要过滤处理那些特殊字符,等等。。。还有很多其他需要周全考虑的地方。 希望大家一起来探讨,让代码达到最“优雅”。当然大家的探讨不仅仅是代码上,还可以是整个公告实现的方式上的。
【本人发帖抛砖引玉,希望能够引出更多的“玉”来,希望所写的每一段代码都能够得到一种最“优雅”的实现方式。以后本人会抛出更多的“砖”,希望能引来更多的“玉”,以供大家一起学习进步】
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
浏览 1960 次