Javascript代码实现仿实例化类


Posted in Javascript onApril 03, 2015

Javascript能做的事情越发的多了起来,随之而来的问题即是Js代码量的增加,面对代码的加多,我选择了仿面向对像类实例化里的构造函数自动启动的方式,把所有的js代码,以注册的形式,类化了起来。

代码

/**
 * @version $Id$
 * @author xjiujiu <xjiujiu@foxmail.com>
 * @description HHJsLib Framework Apps
 * @copyright Copyright (c) 2011-2012 http://www.xjiujiu.com.All right reserved
 */
 
HHJsLib.register({
  init: function() {
    this.bindPreviewBtn();
    this.bindUploadEleImageBtn();
    this.bindUploadEleAudioBtn('a.audio-upload-btn');
    this.bindUploadEleVideoBtn('a.video-upload-btn');
    this.bindDownloadEleAudioBtn();
    this.bindNewConBtn();
    this.bindDelConBtn('a.btn-del-con');
    this.bindDelItemBtn('a.btn-del-item');
    this.bindNewItemBoxClose('div.item-box');
    this.bindPlusBtn('a.btn-plus');
    this.bindAppendNewElement('div.new-item-box ul li a');
    this.bindSetPreviewVideo();
    this.bindAddAnswerBtn('a.btn-add-answer');
    this.bindDelAnswerBtn('a.btn-del-answer');
    this.bindDelImageBtn('a.btn-del-image');
    this.bindDelAudioBtn('a.btn-del-audio');
    this.initPlusBtn();
  },
  bindUploadEleVideoBtn: function(dom) {
    var self    = this;
    $(dom).click(function() {
      var $this  = $(this);
      var t    = HHJsLib.modal.confirm(
        '上传本地视频',
        '<div class="text-center">'
        + ' <p>浏览您电脑里,从中选择一个视频文件。</p>'
        + ' <div class="btn-box btn btn-blue">'
        + ' <div id="upload-btn">从电脑上传</div>'
        + ' </div>'
        + ' </div>'
      );
      var uploader  = HJZUploader.createVideo(
        '#upload-btn', 
        { 
          formData: {model: 'timeline'},
        },
        function(response) {
          if(false == response.rs) {
            self.setDemoBoxInit($this);
            return HHJsLib.warn(response.message);
          }
          self.setDemoAudioInfo($this, response.data);
          $('#dialog-box-' + t).modal('hide');
        }
      );
      uploader.on('uploadProgress', function(file) {
        self.setDemoBoxLoading($this);
      });
 
      return uploader;
    });
  },
  bindDelAudioBtn: function(dom) {
    this.bindDelFileBtn(dom, '真的要删除这个音频吗?');
  },
  bindDelImageBtn: function(dom) {
    this.bindDelFileBtn(dom, '真的要删除这个图片吗?');
  },
  bindDelFileBtn: function(dom, msg) {
    var self  = this;
    $(dom).click(function() {
      var $target   = $(this);
      var t      = HHJsLib.initPopover($(this), msg);
      $('#btn-sure-' + t).click(function() {
        if(1 != $target.attr('data-new')) {
          $.get(
            queryUrl + 'timelineele/adel',
            {id: $target.attr('data-id')},
            function(response) {
              if(false === response.rs) {
                return HHJsLib.warn(response.message);
              }
              self.delDemoFieldInfo($target);
              $target.popover('destroy');
            }
          );
          return;
        }
        self.delDemoFieldInfo($target);
        $target.popover('destroy');
      });
    });
  },
  delDemoFieldInfo: function($target) {
    $($target.attr('data-demo-box')).html('');
    $($target.attr('data-box')).removeClass('uploaded').addClass('no-file');
    $($target.attr('data-field')).attr('data-id', '').attr('data-src', '');
  },
  bindAddAnswerBtn: function(dom) {
    var self  = this;
    $(dom).click(function() {
      var id     = $(this).attr('data-id');
      var answerHtml = eleTplMap.answerTpl.replace(/{id}/g, id);
      $('#answer-box-' + id).append(answerHtml);
      self.bindDelAnswerBtn('#answer-box-' + id + ' a.btn-del-answer');
    });
  },
  bindDelAnswerBtn: function(dom) {
    var self  = this;
    $(dom).click(function() {
      var $target = $(this);
      if(2 > $target.parent().parent().find('textarea.answer-editor').length) {
        return HHJsLib.warn('至少需要有一个答案!');
      }
      var t    = HHJsLib.initPopover($target, '您确定要删除这个答案吗?');
      $('#btn-sure-' + t).click(function() {
        $target.parent().remove();
      });
    });
  },
  bindAppendNewElement: function(dom) {
    var self    = this;
    $(dom).unbind('click').click(function() {
      var type  = $(this).attr('data-type');
      var heading   = $(this).parent().parent().attr('data-heading-id');
      if('heading' == type) {
        self.addNewElePartBox();
        $("#new-item-box-" + heading).hide();
        return;
      }
      self.addNewEleToPartBox(heading, type);
    });
  },
  addNewElePartBox: function() {
    var t      = this.getTimestamp();
    var partBoxHtml = eleTplMap.partBox.replace(/{t}/g, t);
    var headingHtml = this.initItemTplByType('heading', t, t);
    var itemHtml  = this.initItemTplByType('text', t, t);
    var itemBoxHtml = this.initItemBoxTpl(itemHtml, t, t, 'left', 'text');
    partBoxHtml   = partBoxHtml.replace(/{heading}/g, headingHtml);
    partBoxHtml   = partBoxHtml.replace(/{item}/g, itemBoxHtml);
    $("#main-box").append(partBoxHtml);
    this.bindDelItemBtn('#item-' + t + ' a.btn-del-item');
    this.movePlusBtnBox(t);
  },
  addNewEleToPartBox: function(heading, type) {
    var total    = $('#ele-part-box-' + heading + ' div.item-ele-box').length;
    var side    = total % 2 === 0 ? 'left' : 'right';
    var t      = this.getTimestamp();
    var itemHtml  = this.initItemTplByType(type, t, heading);
    var itemBoxHtml = this.initItemBoxTpl(itemHtml, heading, t, side, type);
    //清掉原有高度DIV
    $('#clearfix-' + heading).remove();
    $('#ele-part-box-' + heading).find('div.eles-box').append(itemBoxHtml);
    //绑定Dom事件
    this.bindDelItemBtn('#item-' + t + ' a.btn-del-item');
    this.movePlusBtnBox(heading);
    this.bindNewEleUpload(type);
  },
  bindNewEleUpload: function(type) {
    var self  = this;
    switch(type) {
      case 'image':
      case 'question':
      case 'know':
      self.bindUploadModal('a.btn-upload');
      break;
      case 'audio':
      self.bindUploadEleAudioBtn('a.audio-upload-btn');
      self.bindDelAudioBtn('a.btn-del-audio');
      break;
    }
  },
  initItemTplByType: function(type, t, heading) {
    var itemHtml  = eleTplMap[type].replace(/{t}/g, t);
    itemHtml    = itemHtml.replace(/{sort_num}/g, this.getNewEleSortNum(heading));
 
    return itemHtml.replace(/{headingId}/g, heading);
  },
  initItemBoxTpl: function(content, heading, t, side, type) {
    var itemBoxHtml = eleTplMap.itemBox.replace(/{t}/g, t);
    itemBoxHtml   = itemBoxHtml.replace(/{headingId}/g, heading);
    itemBoxHtml   = itemBoxHtml.replace(/{side}/g, side);
    itemBoxHtml   = itemBoxHtml.replace(/{content}/g, content);
    itemBoxHtml   = itemBoxHtml.replace(/{hash}/g, hex_md5(t));
    itemBoxHtml   += '<div class="clearfix" id="clearfix-' + heading + '"></div>';
     
    return itemBoxHtml.replace(/{type}/g, type);
  },
  movePlusBtnBox: function(heading) {
    //删除原有
    $('#new-item-box-' + heading).remove();
    //加入新
    var plusBtnHtml   = eleTplMap.plusBtn.replace(/{headingId}/g, heading);
    $(plusBtnHtml).insertBefore('#clearfix-' + heading);
    var $items     = $('#ele-part-box-' + heading).find('div.item-ele-box');
    if($items.length < 2) {
      $($items[0]).find('a.btn-del-item').hide();
    } else {
      $($items[0]).find('a.btn-del-item').show();
    }
    //绑定事件
    this.bindAppendNewElement('#new-item-box-' + heading + " ul.new-item-list-box li a");
    this.bindPlusBtn('#btn-plus-' + heading);
  },
  bindNewItemBoxClose: function(dom) {
    $(dom).click(function() {
      $('div.new-item-box').hide();
    });
  },
  bindPlusBtn: function(dom) {
    $(dom).click(function(event) {
      $('div.new-item-box').hide();
      var id = $(this).attr('data-heading-id');
      $('#new-item-box-' + id + ' div.new-item-box').removeClass('hide').attr('data-show', '1').show();
      event.preventDefault();
    });
  },
  initPlusBtn: function() {
    var self  = this;
    $('div.ele-part-box').each(function() {
      var dataId   = $(this).attr('data-heading');
      self.movePlusBtnBox(dataId);
    });
  },
  bindDelItemBtn: function(dom) {
    var self  = this;
    $(dom).click(function() {
      var $target = $(this);
      var t    = HHJsLib.initPopover($target, '您确定要删除这项吗?');
      var id   = $target.attr('data-id');
      var heading = $('#item-' + id).attr('data-heading-id');
      $('#btn-sure-' + t).click(function() {
        if(1 == $target.attr('data-new')) {
          $.get(
            queryUrl + 'timelineele/adel',
            {id: $target.attr('data-id')},
            function(response) {
              if(false === response.rs) {
                return HHJsLib.warn(response.message);
              }
              $('#item-' + id).fadeOut('fast', function() {
                $(this).remove();
                self.movePlusBtnBox(heading);
                self.reArrangeItem(heading);
              });
              $target.popover('destroy');
            }
          );
          return;
        }
        $target.popover('destroy');
        $('#item-' + id).fadeOut('fast', function() {
          $(this).remove();
          self.movePlusBtnBox(heading);
          self.reArrangeItem(heading);
        });
      });
    });
  },
  reArrangeItem: function(heading) {
    var rank  = 1;
    $('#ele-part-box-' + heading).find('div.item-ele-box').each(function() {
      if(rank % 2 === 0) {
        $(this).removeClass('pull-left item-left')
        .addClass('pull-right item-right');
      } else {
        $(this).removeClass('pull-right item-right')
        .addClass('pull-left item-left');
      }
      rank ++;
    });
  },
  bindNewConBtn: function() {
    var self  = this;
    $('#btn-new-con-item').click(function() {
      var t  = self.getTimestamp();
      var conItemHtml   = eleTplMap.conItemTpl.replace(/{t}/g, t);
      $('#conclusion-box').append(conItemHtml);
      self.bindDelConBtn('#btn-del-con-' + t);
      self.bindUploadModal('a.btn-upload');
    });
  },
  bindDelConBtn: function(dom) {
    var self  = this;
    $(dom).click(function() {
      var $target = $(this);
      var t    = HHJsLib.initPopover($target, '您确定要删除这个结论吗?');
      var id   = $target.attr('data-id');
      $('#btn-sure-' + t).click(function() {
        if(1 == $target.attr('data-new')) {
          $.get(
            queryUrl + 'timelineele/adel',
            {id: $target.attr('data-id')},
            function(response) {
              if(false === response.rs) {
                return HHJsLib.warn(response.message);
              }
              $('#item-con-' + id).fadeOut('fast', function() {
                $(this).remove();
              });
              $target.popover('destroy');
            }
          );
          return;
        }
        $target.popover('destroy');
        $('#item-con-' + id).fadeOut('fast', function() {
          $(this).remove();
        });
      });
    });
  },
  getNewEleSortNum: function(heading) {
    return parseInt(this.getMaxSortNum(heading)) + 1;
  },
  getMaxSortNum: function(heading) {
    var sortNums  = [];
    $('.ele-sort-' + heading).each(function() {
      sortNums.push($(this).val());
    });
    sortNums    = sortNums.sort(function(a, b) {
      if (a === b) {
         return 0;
      }
      if (typeof a === typeof b) {
        return a > b ? -1 : 1;
      }
      return typeof a > typeof b ? -1 : 1;
    });
 
    return sortNums[0] == null ? 0 : sortNums[0];
  },
  bindUploadEleImageBtn: function() {
    this.bindUploadModal('a.btn-upload');
  },
  bindUploadEleAudioBtn: function(dom) {
    var self    = this;
    $(dom).click(function() {
      var $this  = $(this);
      var t    = HHJsLib.modal.confirm(
        '上传音频',
        '<div class="text-center">'
        + ' <p>浏览您电脑里,从中选择一个音频文件。</p>'
        + ' <div class="btn-box btn btn-blue">'
        + ' <div id="upload-btn">从电脑上传</div>'
        + ' </div>'
        + ' </div>'
      );
      var uploader  = HJZUploader.createAudio(
        '#upload-btn', 
        { 
          formData: {model: 'timeline'},
        },
        function(response) {
          if(false == response.rs) {
            self.setDemoBoxInit($this);
            return HHJsLib.warn(response.message);
          }
          self.setDemoAudioInfo($this, response.data);
          $('#dialog-box-' + t).modal('hide');
        }
      );
      uploader.on('uploadProgress', function(file) {
        self.setDemoBoxLoading($this);
      });
 
      return uploader;
    });
  },
  setDemoAudioInfo: function($target, data) {
    var audioHtml  = '<audio controls="controls"><source src="' + siteUrl + data.src + '" /></audio>';
    $($target.attr('data-demo-box')).html(audioHtml).show();
    $($target.attr('data-field')).attr('data-id', data.id).attr('data-src', data.src);
  },
  bindUploadModal: function(dom) {
    var self    = this;
    $(dom).unbind('click').click(function() {
      var $this  = $(this);
      var t    = HHJsLib.modal.confirm(
        '上传图片',
        '<div class="text-center">'
        + ' <p>浏览您电脑里的图片,从中选择一张。</p>'
        + '<div class="btn-box btn btn-blue">'
        + ' <div id="upload-btn">从电脑上传</div>'
        + ' </div>'
        + ' </div>'
      );
      var uploader  = HJZUploader.createImage(
        '#upload-btn', 
        { 
          formData: {model: 'timeline'}
        },
        function(response) {
          if(false == response.rs) {
            self.setDemoBoxInit($this);
            return HHJsLib.warn(response.message);
          }
          var imgHtml   = '<img src="'
            + siteUrl + response.data.src
            + '" alt="' + response.data.name + '" />';
          $($this.attr('data-demo-box')).html(imgHtml).show();
          $($this.attr('data-field')).val(response.data.id).attr('data-src', response.data.src);
          $('#dialog-box-' + t).modal('hide');
        }
      );
      uploader.on('uploadProgress', function(file) {
        self.setDemoBoxLoading($this);
      });
      self.bindDelImageBtn('a.btn-del-image');
 
      return uploader;
    });
  },
  bindPreviewBtn: function() {
    var self  = this;
    $('#edit-btn, #preview-btn').click(function() {
      try{
        self.verifyBaseInfo();
        self.verifyEleInfo();
        self.verifyConclusionInfo();
        $('#timeline-form').submit();
      }catch(e) {
        return HHJsLib.warn(e);
      }
    });
  },
  verifyBaseInfo: function() {
    HHJsLib.isEmptyByDom('#image-path', '时间轴大图');
    HHJsLib.isEmptyByDom('#cover', '时间轴封面');
    HHJsLib.isEmptyByDom('#name', '标题');
    HHJsLib.isEmptyByDom('#description', '描述');
  },
  verifyEleInfo: function() {
    this.verifyHeaderEleInfo();
    this.verifyTextEleInfo();
    this.verifyImageEleInfo();
    this.verifyVideoEleInfo();
    this.verifyAudioEleInfo();
    this.verifyQuestionEleInfo();
    this.verifyKnowEleInfo();
  },
  verifyHeaderEleInfo: function() {
    $('div.item-heading-box').each(function() {
      HHJsLib.isEmpty($(this).find('textarea').val(), '头条内容');      
    });
  },
  verifyTextEleInfo: function() {
    $('div.item-text-box').each(function() {
      HHJsLib.isEmptyByDom('#ele-text-' + $(this).attr('data-id'), '文本内容元素');
    });
  },
  verifyImageEleInfo: function() {
    $('div.item-image-box').each(function() {
      HHJsLib.isEmptyByDom('#ele-image-hash-' + $(this).attr('data-id'), '图片地址');
      HHJsLib.isEmptyByDom('#ele-image-content-' + $(this).attr('data-id'), '图片介绍');
    });
  },
  verifyVideoEleInfo: function() {
    $('div.item-video-box').each(function() {
      HHJsLib.isEmptyByDom('#ele-video-hash-' + $(this).attr('data-id'), '视频地址');
      HHJsLib.isEmptyByDom('#ele-video-content-' + $(this).attr('data-id'), '视频介绍');
    });
  },
  verifyAudioEleInfo: function() {
    $('div.item-audio-box').each(function() {
      HHJsLib.isEmptyByDom('#ele-audio-hash-' + $(this).attr('data-id'), '音频地址');
      HHJsLib.isEmptyByDom('#ele-audio-content-' + $(this).attr('data-id'), '音频介绍');
    });
  },
  verifyQuestionEleInfo: function() {
    $('div.item-question-box').each(function() {
      HHJsLib.isEmptyByDom('#ele-question-content-' + $(this).attr('data-id'), '问题内容');
      HHJsLib.isEmptyByDom('#ele-question-extend-' + $(this).attr('data-id'), '问题答案解释');
      HHJsLib.isEmpty(answerLen, '问题答案');
      $('#answer-box-' + $(this).attr('data-id')).find('textarea').each(function() {
        HHJsLib.isEmpty($(this).val(), '问题答案');
      });
    });
  },
  verifyKnowEleInfo: function() {
    $('div.item-know-box').each(function() { 
      HHJsLib.isEmptyByDom('#ele-know-hash-' + $(this).attr('data-id'), '知道图片地址');
      HHJsLib.isEmptyByDom('#ele-know-content-' + $(this).attr('data-id'), '知道介绍');
    });
  },
  verifyConclusionInfo: function() {
    var length     = $('#conclusion-box div.item-con').length;
    HHJsLib.isEmpty(length, '总结');
    $('#conclusion-box div.item-con').each(function() {
      var dataId = $(this).attr('data-id');
      HHJsLib.isEmptyByDom('#ele-con-hash-' + dataId, '总结图片');
      HHJsLib.isEmptyByDom('#ele-con-content-' + dataId, '总结详情');
    });
  },
  bindDownloadEleAudioBtn: function() {
    var self  = this;
    $('a.download-audio-btn').click(function() {
      var $this    = $(this);
      try{
        HHJsLib.isEmptyByDom("#item-audio-upload-hash-" + $this.attr('data-id'), '下载地址');
        var url   = $("#item-audio-upload-hash-" + $this.attr('data-id')).val();
        if('mp3' != url.substring(url.lastIndexOf('.') + 1).toLowerCase()) {
          return HHJsLib.warn('格式不支持,必须是Mp3格式!');
        } 
        var t    = HHJsLib.modal.info(
          '下载音频',
          '<p class="text-center">正在下载音频文件中,请稍等...<p>'
        );
        self.setDemoBoxLoading($this);
        $.getJSON(
          siteUrl + 'index.php/public/resource/adownload', 
          {url: encodeURIComponent(url)}, 
          function(response) {
            if(false == response.rs) {
              self.setDemoBoxInit($this);
              return HHJsLib.warn(response.message);
            }
            $('#dialog-box-' + t).modal('hide');
            self.setDemoAudioInfo($this, response.data);
          }
        );
      } catch(e) {
        return HHJsLib.warn(e);
      }
    });
  },
  setDemoBoxLoading: function($target) {
    $($target.attr('data-box')).removeClass('no-file').addClass('uploaded');
    $($target.attr('data-file-box')).html('');
  },
  setDemoBoxInit: function($target) {
    $($target.attr('data-box')).removeClass('uploaded').addClass('no-file');
    $($target.attr('data-file-box')).html('');
  },
  bindSetPreviewVideo: function() {
    $('input.ele-video').change(function() {
      var url   = $(this).val();
      if(url != '') {
        if('swf' != url.substring(url.lastIndexOf('.') +1 ).toLowerCase()) {
          return HHJsLib.warn('视频地址不合法,请输入有效的在线观看Flash地址!');
        }
        var previewHtml   = '<embed src="' + url + '" quality="high" width="495" height="220" align="middle" allowScriptAccess="always" allowFullScreen="true" mode="transparent" type="application/x-shockwave-flash"></embed>';
        $($(this).attr('data-demo-box')).html(previewHtml);
      }
    });
  },
  bindDelEleBtnFormEdit: function() {
     this.bindDelUploadImgBtn();
  },
   getTimestamp: function() {
     return (new Date()).getTime();
   }
});

以上所述就是本文给大家分享的全部内容了,希望能够对大家学习javascript有所帮助。

Javascript 相关文章推荐
JSON语法五大要素图文介绍
Dec 04 Javascript
jquery实现效果比较好的table选中行颜色
Mar 25 Javascript
Javascript封装DOMContentLoaded事件实例
Jun 12 Javascript
JavaScript模拟深蓝vs卡斯帕罗夫的国际象棋对局示例
Apr 22 Javascript
Windows系统下Node.js的简单入门教程
Jun 23 Javascript
jQuery搜索框效果实现代码(百度关键词联想)
Feb 25 Javascript
Bootstrap Table从服务器加载数据进行显示的实现方法
Sep 29 Javascript
js 数据存储和DOM编程
Feb 09 Javascript
vue-cli启动本地服务局域网不能访问的原因分析
Jan 22 Javascript
vue多次循环操作示例
Feb 08 Javascript
在vue项目中引入vue-beauty操作方法
Feb 11 Javascript
JS中的算法与数据结构之列表(List)实例详解
Aug 16 Javascript
使用Jquery实现每日签到功能
Apr 03 #Javascript
JavaScript获取按钮所在form表单id的方法
Apr 02 #Javascript
JavaScript获取表单内所有元素值的方法
Apr 02 #Javascript
jQuery简单实现QQ空间点赞已经取消点赞
Apr 02 #Javascript
JavaScript获取网页支持表单字符集的方法
Apr 02 #Javascript
JavaScript获取网页表单action属性的方法
Apr 02 #Javascript
使用jquery清空、复位整个输入域
Apr 02 #Javascript
You might like
php截取后台登陆密码的代码
2012/05/05 PHP
PHP cdata 处理(详细介绍)
2013/07/05 PHP
PHP的中使用非缓冲模式查询数据库的方法
2017/02/05 PHP
JavaScript 对象模型 执行模型
2009/12/06 Javascript
IE7中javascript操作CheckBox的checked=true不打勾的解决方法
2009/12/07 Javascript
基于JavaScript 类的使用详解
2013/05/07 Javascript
纯js实现重发验证码按钮倒数功能
2015/04/21 Javascript
js获取页面及个元素高度、宽度的代码
2016/04/26 Javascript
jQuery模仿京东/天猫商品左侧分类导航菜单效果
2016/06/29 Javascript
把多个JavaScript函数绑定到onload事件处理函数上的方法
2016/09/04 Javascript
JavaScript实现格式化字符串函数String.format
2016/12/16 Javascript
assert()函数用法总结(推荐)
2017/01/25 Javascript
[05:28]刀塔密之一:团结则存
2014/07/03 DOTA
Python Web框架Flask中使用七牛云存储实例
2015/02/08 Python
小议Python中自定义函数的可变参数的使用及注意点
2016/06/21 Python
Python 包含汉字的文件读写之每行末尾加上特定字符
2016/12/12 Python
python matplotlib 在指定的两个点之间连线方法
2018/05/25 Python
python抖音表白程序源代码
2019/04/07 Python
python中下标和切片的使用方法解析
2019/08/27 Python
pytorch如何冻结某层参数的实现
2020/01/10 Python
python将unicode和str互相转化的实现
2020/05/11 Python
python实现自动打卡的示例代码
2020/10/10 Python
Python文件名匹配与文件复制的实现
2020/12/11 Python
python3判断IP地址的方法
2021/03/04 Python
英国No.1文具和办公用品在线:Euroffice
2016/09/21 全球购物
美国亚马逊旗下时尚女装网店:SHOPBOP(支持中文)
2020/10/17 全球购物
中专毕业生自我鉴定
2014/02/02 职场文书
高中历史教学反思
2014/02/08 职场文书
矿泉水广告词
2014/03/20 职场文书
合作意向协议书范本
2014/03/31 职场文书
民主评议党员个人自我评价
2015/03/03 职场文书
社会实践单位意见
2015/06/05 职场文书
2015年校本培训工作总结
2015/07/24 职场文书
Canvas如何做个雪花屏版404的实现
2021/09/25 HTML / CSS
django 认证类配置实现
2021/11/11 Python
小程序实现侧滑删除功能
2022/06/25 Javascript