前端開發小例子——網頁右下角消息彈出框的實現:包括數據請求及事件功能的實現。在某個指定網頁的右下角,每當刷新時,彈出提示框,若有點擊“已閱”,后再刷新就不再提醒。
效果圖:
【設計思路】
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,\5b8b\4f53; }*/ .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)步驟。