组件开发小例子——网页右下角消息弹出框的实现
前端开发小例子——网页右下角消息弹出框的实现:包括数据请求及事件功能的实现。在某个指定网页的右下角,每当刷新时,弹出提示框,若有点击“已阅”,后再刷新就不再提醒。
效果图:
【设计思路】
1、创建组件:notice-sxl
2、在notice-sxl -->package.json 中引入依赖
3、在notice-sxl -->template -->notice-sxl.html写模板 ,使用nunjucks进行模板渲染
4、在notice-sxl.js 中使用common-model 获取接口数据
5、在notice-sxl -->example -->notice-sxl.html 中创建实例
具体:
1、创建组件:notice-sxl
方法详见:使用SPM创建新组件
2、在notice-sxl -->package.json 中引入依赖
package.json:
{ "name": "notice-sxl", "version": "0.1.0", "root": "#", "description": "", "keywords":[], "homepage": "", "author": "sxl<sxl@strongsoft.net>", "main": "./src/notice-sxl.js", "repository": { "type": "git", "url": "" }, "bugs": { "url": "" }, "license": "", "devDependencies": {}, "tplDependencies": {}, "dependencies": { "jquery": "<=1.9", "backbone": "~1", "moment": "~2", "observer": "~0", "lodash": "~3", "moment": "~2", "nunjucks-slim":"~1.1", "common-model":"~0" }, "scripts": {}, "tests": ["notice-sxl"], "buildArgs": "cmd", "output": { "notice-sxl.js": "." }, "hostModule": null, "assets":null, "options": null, "optionalDependencies": null }
3、在notice-sxl -->template -->notice-sxl.html写模板 ,使用nunjucks进行模板渲染
notice-sxl.html:
<div class="message-push-box-container" id="message-push-box-{{key}}" style="bottom: {{bottom}}px"> <div class="message_push_title" id="message_push_title"> <div class="title_l"></div> <div class="title_c"> <div class="em">事件提醒</div> <span> <a msg="关闭" title="关闭" class="message_push_close closeIcon" key="{{key}}"></a> </span> </div> <div class="title_r"></div> </div> <div class="message_push_body" id="message_push_body"> <div class="body_l"> <div class="body_r"> <div class="body_c"> <div class="message_push_container"> <div class="message_push_container_content">{{content}}</div> <div class="message_push_container_time">{{time}}</div> <button class="message_push_container_readbtn ss-btn ss-btn-mini ss-btn-primary" key="{{key}}">标为已阅</button> </div> </div> </div> </div> </div> <div class="message_push_bottom"> <div class="bottom_l"></div> <div class="bottom_c"></div> <div class="bottom_r"></div> </div> </div>
样式:notice-sxl-theme-base.css:
element.style { bottom: 30px; } .message-push-box-container { position:fixed; height: 170px; width: 325px; z-index: 9999; right: 10px; bottom: 30px; } body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, textarea, p, blockquote, th, td, hr, button, article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { margin: 0; padding: 0; } body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, textarea, p, blockquote, th, td, hr, button, article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { margin: 0; padding: 0; } div { display: block; } .message-push-box-container .message_push_title { height: 34px; } .message_push_title { position: relative; height: 29px; _bottom: -2px; } .message-push-box-container .message_push_title .title_l { width: 8px; height: 34px; background: url(../assets/notice-sxl/message/tilemap-legtop-left.png) no-repeat left top; } .message_push_title .title_l { position: absolute; left: 0; top: 0; width: 8px; height: 29px; overflow: hidden; } .message-push-box-container .message_push_title .title_c { margin: 0 12px 0 8px; height: 34px; background: url(../assets/notice-sxl/message/tilemap-legtop-center.png) repeat-x; } .message_push_title .title_c { position: relative; margin: 0 8px; height: 29px; } .message-push-box-container .message_push_title .title_c .em { height: 34px; line-height: 34px; color: #ffffff; background: url(../assets/notice-sxl/message/gblb.png) no-repeat; } .message_push_title .title_c .em { position: absolute; width: 100%; height: 29px; line-height: 29px; font-weight: bold; margin-left: 3px; text-indent: 35px; font-size: 14px; } .message_push_title .title_c span { float: right; position: relative; } /*body, button, input, select, textarea { font-size: 12px; line-height: 1.5; font-family: tahoma,arial,Hiragino Sans GB,5b8b4f53; }*/ .message-push-box-container .message_push_title .title_c span a.closeIcon { width: 21px; height: 21px; background: url(../assets/notice-sxl/message/Close.gif) no-repeat; background-position: 50% 50%; margin: 6px 2px 0 0; } .message-push-box-container .message_push_title .title_c span a { width: 34px; height: 34px; } .message_push_title .title_c span a { float: left; cursor: pointer; width: 28px; height: 25px; } a:hover { text-decoration: underline; } .message-push-box-container .message_push_title .title_r { width: 12px; height: 34px; background: url(../assets/notice-sxl/message/tilemap-legtop-right.png) no-repeat right top; } .message_push_title .title_r { position: absolute; right: 0; top: 0; width: 8px; height: 29px; overflow: hidden; } .message_push_body { position: relative; overflow: hidden; } .message-push-box-container .message_push_body .body_l { background-image: url(../assets/notice-sxl/message/tilemap-legmid-left.png); } .message_push_body .body_l { overflow: hidden; background-repeat: repeat-y; background-position: left; } .message-push-box-container .message_push_body .body_r { background-image: url(../assets/notice-sxl/message/tilemap-legmid-right.png); } .message_push_body .body_r { overflow: hidden; background-repeat: repeat-y; background-position: right; } .message-push-box-container .message_push_body .body_c { margin: 0 12px 0 8px; } .message_push_body .body_c { margin: 0 8px; overflow: hidden; } .message-push-box-container .message_push_body .message_push_container { background-color: #fff; } .message-push-box-container .message_push_container { height: 120px; } .message-push-box-container .message_push_container_content { height: 89px; line-height: 25px; font-size: 14px; font-family: 微软雅黑; color: rgb(0, 52, 92); padding: 0px 5px; overflow: auto; } .message-push-box-container .message_push_container_time { height: 30px; line-height: 30px; font-size: 14px; font-family: 微软雅黑; color: rgb(0, 52, 92); text-align: right; padding: 4px 10px 4px 0px; overflow: hidden; } button.ss-btn.ss-btn-mini, input[type="submit"].ss-btn.ss-btn-mini { } button.ss-btn.ss-btn-mini, input[type="submit"].ss-btn.ss-btn-mini { } .message-push-box-container .message_push_container_readbtn { position: absolute; left: 15px; bottom: 5px; padding-left: 10px; } button.ss-btn, input[type="submit"].ss-btn { } button.ss-btn, input[type="submit"].ss-btn { } .ss-btn { border-color: rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25); } .ss-btn-mini { padding: 0 6px; font-size: 10.5px; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; } .ss-btn { display: inline-block; padding: 4px 12px; margin-bottom: 0; font-size: 14px; line-height: 20px; color: #333333; text-align: center; text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); vertical-align: middle; cursor: pointer; background-color: #f5f5f5; background-image: linear-gradient(to bottom, #ffffff, #e6e6e6); background-repeat: repeat-x; border: 1px solid #bbbbbb; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); border-bottom-color: #a2a2a2; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); } .ss-btn-primary { color: #ffffff; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); background-color: #006dcc; background-image: linear-gradient(to bottom, #0088cc, #0044cc); background-repeat: repeat-x; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); } .message-push-box-container .message_push_bottom { height: 13px; } .message_push_bottom { position: relative; height: 8px; overflow: hidden; } .message-push-box-container .message_push_bottom .bottom_l { width: 8px; height: 13px; background-image: url(../assets/notice-sxl/message/tilemap-legfoot-left.png); } .message_push_bottom .bottom_l { font-size: 0; position: absolute; top: 0; left: 0; width: 8px; height: 8px; overflow: hidden; background-repeat: no-repeat; background-position: left bottom; } .message-push-box-container .message_push_bottom .bottom_c { margin: 0 12px 0 8px; height: 13px; background: url(../assets/notice-sxl/message/tilemap-legfoot-center.png) repeat-x; } .message_push_bottom .bottom_c { font-size: 0; position: relative; height: 8px; margin: 0 8px; overflow: hidden; background-repeat: repeat-x; background-position: center bottom; } .message-push-box-container .message_push_bottom .bottom_r { width: 12px; height: 13px; background-image: url(../assets/notice-sxl/message/tilemap-legfoot-right.png); } .message_push_bottom .bottom_r { font-size: 0; position: absolute; top: 0; right: 0; width: 8px; height: 8px; overflow: hidden; background-repeat: no-repeat; background-position: right bottom; }
4、在notice-sxl -->src -->notice-sxl.js 中使用common-model 获取接口数据
notice-sxl.js:
var $ = require('jquery'); /*工具类组件,同underscore*/ var _ = require('lodash'); /*前端mvc组件*/ var backbone = require('backbone'); /*模板组件*/ var nunjucks = require('nunjucks-slim'); /*第三方时间数据处理组件*/ var moment = require('moment'); var CommonModel = require('common-model'); //引入样式文件 require('../css/notice-sxl-theme-base.css'); var NoticeModule = backbone.View.extend({ initialize: function(options) { //缓存参数 this.options = options || {}; //这句参数相关。 //渲染模板 // //this.$el集成自backbone,具体参见backbone相关api // this.$el.html(nunjucks.render('notice-sxl.html')); this._initModel(); this._initOptions(); this._distance();//计算距离 }, events:{ "click .message_push_close":"_bindClickClose", "click .message_push_container_readbtn":"_readBtnClick" }, //计算距离 _distance:function(){ this._dialogHeight = 170; this._dialogBottom = 30; //弹框数组 this._dialogArray = []; }, _initModel:function(){ //请求接口数据的commonModel this.commonModel= new CommonModel('basic.data',{isFixedStruct:true}); //修改接口数据的commonModel(点击已阅) this.upEventModel= new CommonModel('basic.basicManage',{isFixedStruct:true}); }, _initOptions:function(){ //common-model实例化 //这是interface_common_model.json里面的接口。 var that = this; //发起请求 this.commonModel.fetch({ basicData:{ params:{ key: 's_comapi_event_notice', unit_id:'1090' //tic:'123' } } },function(data){ //数据判断 var dataArr=data[0]&& data[0].length>0?data[0]:[]; if (!dataArr&&dataArr.length===0) { return; } //循环遍历 // 1.处理 // 2.位置的计算 // 3.渲染 _.each(dataArr,function(data){ data.content="已加入"+data.event_unit+"启动的紧急事件:"+data.title; data.time=moment(data.send_time).format("YYYY-MM-DD HH:mm:ss"); data.id=data.id; data.bottom = that._dialogBottom; data.key=data.id; // 1.处理 // 2.位置的计算 // this._dialogHeight=170; // this._dialog // 3.渲染 that.$el.append(nunjucks.render('notice-sxl.html', data)); // var html=nunjucks.render('notice-sxl.html',data); // $("body").append(html); var params = { key: data.id, bottom: that._dialogBottom }; that._dialogArray.push(params); that._dialogBottom += that._dialogHeight; }); // that._renderResult(); }); // 日期格式: // [YYYY-MM-DDTHH:mm:ss,YYYY-MM-DDTHH:mm:ss] // ['2016-12-01T08:00:00,2016-12-01T22:00:00'] }, /** * 标为已读 * @param {[type]} e [description] * @return {[type]} [description] */ _readBtnClick: function(e) { var key = $(e.currentTarget).attr("key"); //获取得到当前的DOM对象 key = +key; //累加获取DOM对象的最外层 var basicData = { basicManage: { params: { key: "u_comapi_event_notice" }, options: { sendData: { id: key, time: moment().format("YYYY-MM-DDTHH:mm:ss"), is_read: 1 }, method: "PUT" //PUT方法 } } }; var that = this; this.upEventModel.fetch(basicData, function(data) { //console.log(data); that._bindClickClose(e); //点击已阅,后,则关闭消息弹出框 }); }, //关闭消息窗口 _bindClickClose: function(e) { var key = $(e.currentTarget).attr("key"); //获取得到当前的DOM对象 var flag = 0; var that = this; _.each(this._dialogArray, function(v, k) { if (!flag && v.key === +key) { //如果点击的是当前对象的关闭按钮 $("#message-push-box-" + v.key).remove(); //则将当前消息框移除 v.removeFlag = true; flag = 1; that._dialogBottom -= that._dialogHeight; //相对应的其余消息框往下堆叠 } if (flag) { //消息框的堆叠效果 that._boxAnimate(v, that); } }); this._dialogArray = _.filter(this._dialogArray, function(v) { return !v.removeFlag; //消息框关闭成功的话,从后台数据库缓存中移除相关记录 }); }, //box下降的动画效果 _boxAnimate: function(v, that) { $("#message-push-box-" + v.key).animate({ bottom: v.bottom - that._dialogHeight }, 500, function() { v.bottom = v.bottom - that._dialogHeight; }); }, render: function() { //this._renderResult(); }, /** * 渲染结果 */ _renderResult: function( ) { //var datas = this.options.datas || []; /*var result = { datas: datas };*/ //this.$el.html(nunjucks.render('notice-sxl.html', result)); }, dispose: function() { //继承自backbone this.remove(); } }); module.exports = NoticeModule;
5、在notice-sxl -->example -->index.html 中创建实例
index.html :
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> 消息提醒 </title> <link rel="stylesheet" type="text/css" href=""> </head> <body> <script id="seajsnode" src="../sea-modules/sea.js"></script> <script src="../sea-modules/seajs-helper.js"></script> <script> seajs.use(['../dist/notice-sxl-debug','jquery'],function(NoticeSxl,$){ //TODO 示例代码 var main = new NoticeSxl({el:'body'}); main.render(); }); </script> </body> </html>
6. 使用spm引入依赖,以及编译和运行:
步骤如下:
1)安装依赖:spm install -e
2)编译:spm build
(编译好的东西会放在trunk-dist里面)
3)发布:spm app -d
(会出来一个export端口,一般是:4745)
4)在浏览器中输入:http://localhost:4745/examples/index.html 即可运行
如果出错了,出bug了,修改完,重新操作2)步骤。