美文网首页
node.js搭建在线便利贴--2

node.js搭建在线便利贴--2

作者: zy懒人漫游 | 来源:发表于2018-02-27 16:06 被阅读0次

    node.js搭建在线便利贴--1
    在上一次中,已经搭建好了express和webpack,现在我们要做的是编写前端模块了。
    前端模块主要写在src>js>mod里,以及src>less>less文件

    event.js

    
      var EventCenter = (function(){
    
        var events = {};
    
        function on(evt, handler){
          events[evt] = events[evt] || []; 
    
          events[evt].push({
            handler: handler
          });
        }
    
        function fire(evt, args){
          if(!events[evt]){
            return;
          }
          for(var i=0; i<events[evt].length; i++){
            events[evt][i].handler(args);
          }
          
        }
    
        return {
          on: on,
          fire: fire
        }
      })();
      module.exports = EventCenter;
    

    note-manager.js

    var Toast = require('./toast.js').Toast;
    var Note = require('./note.js').Note;
    var Toast = require('./toast.js').Toast;
    var Event = require('mod/event.js');
    
    var NoteManager = (function(){
      function load() {
        $.get('/api/notes')
          .done(function(ret){
            if(ret.status == 0){
              $.each(ret.data, function(idx, article) {
                  new Note({
                    id: article.id,
                    context: article.text,
                    username: article.username
                  });
              });
              Event.fire('waterfall');
            }else{
              Toast(ret.errorMsg);
            }
          })
          .fail(function(){
            Toast('网络异常');
          });
      }
      function add(){
        new Note();
      }
      return {
        load: load,
        add: add
      }
    })();
    module.exports.NoteManager = NoteManager
    

    note.js

    require('less/note.less');
    
    var Toast = require('./toast.js').Toast;
    var Event = require('mod/event.js');
    
    function Note(opts){
      this.initOpts(opts);
      this.createNote();
      this.setStyle();
      this.bindEvent();
    }
    Note.prototype = {
      colors: [
        ['#ea9b35','#efb04e'], // headColor, containerColor
        ['#dd598b','#e672a2'],
        ['#eee34b','#f2eb67'],
        ['#c24226','#d15a39'],
        ['#c1c341','#d0d25c'],
        ['#3f78c3','#5591d2']
      ],
    
      defaultOpts: {
        id: '',   //Note的 id
        $ct: $('#content').length>0?$('#content'):$('body'),  //默认存放 Note 的容器
        context: 'input here'  //Note 的内容
      },
    
      initOpts: function (opts) {
        this.opts = $.extend({}, this.defaultOpts, opts||{});
        if(this.opts.id){
           this.id = this.opts.id;
        }
      },
    
      createNote: function () {
        var tpl =  '<div class="note">'
                  + '<div class="note-head"><span class="username"></span><span class="delete">&times;</span></div>'
                  + '<div class="note-ct" contenteditable="true"></div>'
                  +'</div>';
        this.$note = $(tpl);
        this.$note.find('.note-ct').text(this.opts.context);
        this.$note.find('.username').text(this.opts.username);
        this.opts.$ct.append(this.$note);
        if(!this.id)  this.$note.css('bottom', '10px');  //新增放到右边
      },
    
      setStyle: function () {
        var color = this.colors[Math.floor(Math.random()*6)];
        this.$note.find('.note-head').css('background-color', color[0]);
        this.$note.find('.note-ct').css('background-color', color[1]);
      },
    
      setLayout: function(){
        var self = this;
        if(self.clk){
          clearTimeout(self.clk);
        }
        self.clk = setTimeout(function(){
          Event.fire('waterfall');
        },100);
      },
    
      bindEvent: function () {
        var self = this,
            $note = this.$note,
            $noteHead = $note.find('.note-head'),
            $noteCt = $note.find('.note-ct'),
            $delete = $note.find('.delete');
    
        $delete.on('click', function(){
          self.delete();
        })
    
        //contenteditable没有 change 事件,所有这里做了模拟通过判断元素内容变动,执行 save
        $noteCt.on('focus', function() {
          if($noteCt.html()=='input here') $noteCt.html('');
          $noteCt.data('before', $noteCt.html());
        }).on('blur paste', function() {
          if( $noteCt.data('before') != $noteCt.html() ) {
            $noteCt.data('before',$noteCt.html());
            self.setLayout();
            if(self.id){
              self.edit($noteCt.html())
            }else{
              self.add($noteCt.html())
            }
          }
        });
    
        //设置笔记的移动
        $noteHead.on('mousedown', function(e){
          var evtX = e.pageX - $note.offset().left,   //evtX 计算事件的触发点在 dialog内部到 dialog 的左边缘的距离
              evtY = e.pageY - $note.offset().top;
          $note.addClass('draggable').data('evtPos', {x:evtX, y:evtY}); //把事件到 dialog 边缘的距离保存下来
        }).on('mouseup', function(){
           $note.removeClass('draggable').removeData('pos');
        });
    
        $('body').on('mousemove', function(e){
          $('.draggable').length && $('.draggable').offset({
            top: e.pageY-$('.draggable').data('evtPos').y,    // 当用户鼠标移动时,根据鼠标的位置和前面保存的距离,计算 dialog 的绝对位置
            left: e.pageX-$('.draggable').data('evtPos').x
          });
        });
      },
    
      edit: function (msg) {
        var self = this;
        $.post('/api/notes/edit',{
            id: this.id,
            note: msg
          }).done(function(ret){
          if(ret.status === 0){
            Toast('update success');
          }else{
            Toast(ret.errorMsg);
          }
        })
      },
    
      add: function (msg){
        console.log('addd...');
        var self = this;
        $.post('/api/notes/add', {note: msg})
          .done(function(ret){
            if(ret.status === 0){
              Toast('add success');
            }else{
              self.$note.remove();
              Event.fire('waterfall')
              Toast(ret.errorMsg);
            }
          });
        //todo
      },
    
      delete: function(){
        var self = this;
        $.post('/api/notes/delete', {id: this.id})
          .done(function(ret){
            if(ret.status === 0){
              Toast('delete success');
              self.$note.remove();
              Event.fire('waterfall')
            }else{
              Toast(ret.errorMsg);
            }
        });
    
      }
    
    };
    
    module.exports.Note = Note;
    

    taost.js

    require('less/toast.less');
    
    function toast(msg, time){
      this.msg = msg;
      this.dismissTime = time||1000;  //ms
      this.createToast();
      this.showToast();
    }
    toast.prototype = {
      createToast: function(){
        var tpl = '<div class="toast">'+this.msg+'</div>';
        this.$toast = $(tpl);
        $('body').append(this.$toast);
      },
      showToast: function(){
        var self = this;
        this.$toast.fadeIn(300, function(){
          setTimeout(function(){
             self.$toast.fadeOut(300,function(){
               self.$toast.remove();
             });
          }, self.dismissTime);
        });
    
      }
    };
    
    function Toast(msg,time){
      return new toast(msg, time);
    }
    
    module.exports.Toast = Toast;
    

    waterfall.js

    
    var WaterFall = (function(){
      var $ct;
      var $items;
    
      function render($c){
        $ct = $c;
        $items = $ct.children();
    
        var nodeWidth = $items.outerWidth(true),
          colNum = parseInt($(window).width()/nodeWidth),
          colSumHeight = [];
    
        for(var i = 0; i<colNum;i++){
          colSumHeight.push(0);
        }
    
        $items.each(function(){
          var $cur = $(this);
    
          //colSumHeight = [100, 250, 80, 200]
    
          var idx = 0,
            minSumHeight = colSumHeight[0];
    
          for(var i=0;i<colSumHeight.length; i++){
            if(colSumHeight[i] < minSumHeight){
              idx = i;
              minSumHeight = colSumHeight[i];
            }
          }
    
          $cur.css({
            left: nodeWidth*idx,
            top: minSumHeight
          });
          colSumHeight[idx] = $cur.outerHeight(true) + colSumHeight[idx];
        });
      }
    
    
      $(window).on('resize', function(){
        render($ct);
      })
    
    
      return {
        init: render
      }
    })();
    
    module.exports = WaterFall
    

    在views文件下的index.ejs我们可以这么写

    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <title><%= title %></title>
    </head>
    <body>
      <div id="header">
        <a class="add-note" title="添加笔记" href="#">
          <span class="fa fa-plus"></span>添加便利贴</a>
        <ul class="user-area">
        <li>
          <a class="login" title="GitHub登录" href="/auth/github"> GitHub登录</a>
        </ul>
      </div>
      <div id="content">
      </div>
      <div class="stars"></div>
      <script src="/js/index.js"></script>
      <!--     <div class="twinkling"></div> -->
    </body>
    </html>
    

    终端在该文件下输入npm start,打开localhost:8000,可以看到如下页面

    1519724042(1).jpg

    具体的前端代码可以参考这里,这是我的GitHub。

    相关文章

      网友评论

          本文标题:node.js搭建在线便利贴--2

          本文链接:https://www.haomeiwen.com/subject/kgnuxftx.html