-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy path前端小项目之在线便利贴.html
1 lines (1 loc) · 87 KB
/
前端小项目之在线便利贴.html
1
<!doctype html><html class="theme-next mist"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1"><meta name="google-site-verification" content="PBwskePkFkRAnqisXEBN7FyYihV0DkOHyvEC2eDt6Gg"><meta name="referrer" content="never"><script src="/lib/pace/pace.min.js?v=1.0.2"></script><link href="/lib/pace/pace-theme-minimal.min.css?v=1.0.2" rel="stylesheet"><meta http-equiv="Cache-Control" content="no-transform"><meta http-equiv="Cache-Control" content="no-siteapp"><meta name="baidu-site-verification" content="haLEFmuOYV"><script>!function(e,t,o,c,i,a,n){e.DaoVoiceObject=i,e[i]=e[i]||function(){(e[i].q=e[i].q||[]).push(arguments)},e[i].l=1*new Date,a=t.createElement(o),n=t.getElementsByTagName(o)[0],a.async=1,a.src=c,a.charset="utf-8",n.parentNode.insertBefore(a,n)}(window,document,"script",("https:"==document.location.protocol?"https:":"http:")+"//widget.daovoice.io/widget/0f81ff2f.js","daovoice"),daovoice("init",{app_id:"0f81ff2f"}),daovoice("update")</script><link href="/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css"><link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css"><link href="/css/main.css?v=5.0.2" rel="stylesheet" type="text/css"><meta name="keywords" content="express"><link rel="alternate" href="/atom.xml" title="Moorez" type="application/atom+xml"><link rel="shortcut icon" type="image/x-icon" href="/images/favicon.ico?v=5.0.2"><meta name="description" content="实现的效果如下:界面可能不是太好看😁,考虑到容器的高度会被拉长,因此没有用图片做背景。预览便利贴"><meta name="keywords" content="express"><meta property="og:type" content="article"><meta property="og:title" content="前端小项目之在线便利贴"><meta property="og:url" content="http://www.shenzekun.cn/前端小项目之在线便利贴.html"><meta property="og:site_name" content="Moorez"><meta property="og:description" content="实现的效果如下:界面可能不是太好看😁,考虑到容器的高度会被拉长,因此没有用图片做背景。预览便利贴"><meta property="og:image" content="https://ws3.sinaimg.cn/large/006tKfTcly1fjhulxqhxuj31kw0j976o.jpg"><meta property="og:image" content="https://ws1.sinaimg.cn/large/006tKfTcly1fjhuypg0s6j31co0v6439.jpg"><meta property="og:image" content="https://ws3.sinaimg.cn/large/006tKfTcly1fjhv8g9apcj30au0cqq30.jpg"><meta property="og:image" content="https://ws1.sinaimg.cn/large/006tKfTcly1fji1acleqhj30ba0k0mxg.jpg"><meta property="og:image" content="https://ws3.sinaimg.cn/large/006tKfTcly1fjhvfxr6p3j319i0qq42h.jpg"><meta property="og:image" content="https://ws2.sinaimg.cn/large/006tKfTcly1fjhvj4lwtgj316a0cgjrb.jpg"><meta property="og:image" content="https://ws1.sinaimg.cn/large/006tKfTcly1fji3f1ap39j30ik03cglh.jpg"><meta property="og:image" content="https://ws3.sinaimg.cn/large/006tKfTcly1fji3x6gw2oj30i005q748.jpg"><meta property="og:image" content="https://ws2.sinaimg.cn/large/006tKfTcly1fji3q8xe7tj310i068js2.jpg"><meta property="og:image" content="https://ws4.sinaimg.cn/large/006tKfTcly1fji43t9rgej31b20ug0y0.jpg"><meta property="og:image" content="https://ws1.sinaimg.cn/large/006tKfTcly1fji626ceeuj30r40p8t96.jpg"><meta property="og:image" content="https://ws1.sinaimg.cn/large/006tKfTcly1fji7u6i1v0j30jm06y0t6.jpg"><meta property="og:updated_time" content="2018-10-21T12:51:44.852Z"><meta name="twitter:card" content="summary"><meta name="twitter:title" content="前端小项目之在线便利贴"><meta name="twitter:description" content="实现的效果如下:界面可能不是太好看😁,考虑到容器的高度会被拉长,因此没有用图片做背景。预览便利贴"><meta name="twitter:image" content="https://ws3.sinaimg.cn/large/006tKfTcly1fjhulxqhxuj31kw0j976o.jpg"><script type="text/javascript" id="hexo.configuration">var NexT=window.NexT||{},CONFIG={scheme:"Mist",sidebar:{position:"left",display:"post"},fancybox:!0,motion:!1,duoshuo:{userId:"0",author:"Author"}}</script><link rel="canonical" href="http://www.shenzekun.cn/前端小项目之在线便利贴.html"><title>前端小项目之在线便利贴 | Moorez</title></head><body itemscope itemtype="//schema.org/WebPage" lang="zh-Hans"><div class="container one-collumn sidebar-position-left page-post-detail"><div class="headband"></div><a href="https://github.com/shenzekun" class="github-corner" aria-label="View source on Github"><svg width="92" height="92" viewBox="0 0 250 250" style="fill:#151513;color:#fff;position:absolute;top:0;border:0;right:0" aria-hidden="true"><path d="M0 0 115 115 130 115 142 142 250 250 250 0Z"></path><path d="M128.3 109C113.8 99.7 119 89.6 119 89.6 122 82.7 120.5 78.6 120.5 78.6 119.2 72 123.4 76.3 123.4 76.3 127.3 80.9 125.5 87.3 125.5 87.3 122.9 97.6 130.6 101.9 134.4 103.2" fill="currentColor" style="transform-origin:130px 106px" class="octo-arm"></path><path d="M115 115C114.9 115.1 118.7 116.5 119.8 115.4L133.7 101.6C136.9 99.2 139.9 98.4 142.2 98.6 133.8 88 127.5 74.4 143.8 58 148.5 53.4 154 51.2 159.7 51 160.3 49.4 163.2 43.6 171.4 40.1 171.4 40.1 176.1 42.5 178.8 56.2 183.1 58.6 187.2 61.8 190.9 65.4 194.5 69 197.7 73.2 200.1 77.6 213.8 80.2 216.3 84.9 216.3 84.9 212.7 93.1 206.9 96 205.4 96.6 205.1 102.4 203 107.8 198.3 112.5 181.9 128.9 168.3 122.5 157.7 114.1 157.9 116.9 156.7 120.9 152.7 124.9L141 136.5C139.8 137.7 141.6 141.9 141.8 141.8Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style><header id="header" class="header" itemscope itemtype="//schema.org/WPHeader"><div class="header-inner"><div class="site-meta"><div class="custom-logo-site-title"><a href="/" class="brand" rel="start"><span class="logo-line-before"><i></i></span> <span class="site-title">Moorez</span><span class="logo-line-after"><i></i></span></a></div><p class="site-subtitle"></p></div><div class="site-nav-toggle"><button><span class="btn-bar"></span><span class="btn-bar"></span><span class="btn-bar"></span></button></div><nav class="site-nav"><ul id="menu" class="menu"><li class="menu-item menu-item-home"><a href="/" rel="section"><i class="menu-item-icon fa fa-fw fa-home"></i><br>首页</a></li><li class="menu-item menu-item-categories"><a href="/categories" rel="section"><i class="menu-item-icon fa fa-fw fa-th"></i><br>分类</a></li><li class="menu-item menu-item-about"><a href="/about" rel="section"><i class="menu-item-icon fa fa-fw fa-user"></i><br>关于</a></li><li class="menu-item menu-item-archives"><a href="/archives" rel="section"><i class="menu-item-icon fa fa-fw fa-archive"></i><br>归档</a></li><li class="menu-item menu-item-tags"><a href="/tags" rel="section"><i class="menu-item-icon fa fa-fw fa-tags"></i><br>标签</a></li><li class="menu-item menu-item-search"><a href="javascript:;" class="popup-trigger"><i class="menu-item-icon fa fa-search fa-fw"></i><br>搜索</a></li></ul><div class="site-search"><div class="popup"><span class="search-icon fa fa-search"></span> <input type="text" id="local-search-input"><div id="local-search-result"></div><span class="popup-btn-close">close</span></div></div></nav></div></header><main id="main" class="main"><div class="main-inner"><div class="content-wrap"><div id="content" class="content"><div id="posts" class="posts-expand"><article class="post post-type-normal" itemscope itemtype="http://schema.org/Article"><link itemprop="mainEntityOfPage" href="http://www.shenzekun.cn/前端小项目之在线便利贴.html"><span hidden itemprop="author" itemscope itemtype="http://schema.org/Person"><meta itemprop="name" content="shenzekun"><meta itemprop="description" content=""><meta itemprop="image" content="https://blog-1257878287.cos.ap-chengdu.myqcloud.com/avatar1.jpg"></span><span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization"><meta itemprop="name" content="Moorez"></span><header class="post-header"><h1 class="post-title" itemprop="name headline">前端小项目之在线便利贴</h1><div class="post-meta"><span class="post-time"><span class="post-meta-item-icon"><i class="fa fa-calendar-o"></i></span> <span class="post-meta-item-text">发表于</span> <time itemprop="dateCreated" datetime="2017-09-13T20:48:33+08:00" content="2017-09-13">2017-09-13</time></span> <span class="post-category"> | <span class="post-meta-item-icon"><i class="fa fa-folder-o"></i></span> <span class="post-meta-item-text">分类于</span> <span itemprop="about" itemscope itemtype="https://schema.org/Thing"><a href="/categories/前端/" itemprop="url" rel="index"><span itemprop="name">前端</span></a></span></span> <span id="/前端小项目之在线便利贴.html" class="leancloud_visitors" data-flag-title="前端小项目之在线便利贴"> | <span class="post-meta-item-icon"><i class="fa fa-eye"></i></span> <span class="post-meta-item-text">热度</span><span class="leancloud-visitors-count"></span> <span>℃</span></span><div class="post-wordcount"><span class="post-meta-divider">|</span><span class="post-meta-item-icon"><i class="fa fa-file-word-o"></i></span> <span class="post-meta-item-text">字数统计</span> <span title="字数统计">2,972 字</span> <span class="post-meta-divider">|</span><span class="post-meta-item-icon"><i class="fa fa-clock-o"></i></span> <span class="post-meta-item-text">阅读时长</span> <span title="阅读时长">14 分钟</span></div></div></header><div class="post-body" itemprop="articleBody"><hr><h2 id="实现的效果如下:"><a href="#实现的效果如下:" class="headerlink" title="实现的效果如下:"></a>实现的效果如下:</h2><p><img src="https://ws3.sinaimg.cn/large/006tKfTcly1fjhulxqhxuj31kw0j976o.jpg" alt=""></p><p>界面可能不是太好看😁,考虑到容器的高度会被拉长,因此没有用图片做背景。</p><h2 id="预览"><a href="#预览" class="headerlink" title="预览"></a>预览</h2><p><a href="http://note.shenzekun.cn" target="_blank" rel="external">便利贴</a></p><a id="more"></a><h2 id="涉及的知识点"><a href="#涉及的知识点" class="headerlink" title="涉及的知识点"></a>涉及的知识点</h2><ul><li><code>sass</code>(css 预编译器)</li><li><code>webpack</code>(自动化构建工具,实现LESS,CSS,JS编译和压缩代码)</li><li><code>express</code> (基于 Node.js 平台的 web 开发框架)</li><li><code>html+css</code></li><li><code>Node.js</code>(基于 Chrome V8 引擎的 JavaScript 运行环境)</li><li><code>jQuery</code>(一个快速、简洁的JavaScript框架)</li><li><code>sequelize</code>(Node的ORM框架Sequelize操作数据库)</li><li><code>passport</code>(实现第三方登录)</li></ul><h2 id="实现功能"><a href="#实现功能" class="headerlink" title="实现功能"></a>实现功能</h2><ul><li>github第三方登录</li><li>添加笔记(登录成功后)</li><li>删除笔记</li><li>修改笔记</li><li>使用 markdown(类似 typroa)</li><li>笔记拖拽</li></ul><h2 id="准备工作"><a href="#准备工作" class="headerlink" title="准备工作"></a>准备工作</h2><ul><li><strong>必要条件</strong>:已经安装好了node环境,还没安装的可以去<a href="http://nodejs.cn/download/" target="_blank" rel="external">node</a>中文官网下载</li><li><strong>小提示</strong>:如果用 npm 下载感觉慢的话,可以下载一个切换镜像源的工具<code>nrm</code>,在终端输入:</li></ul><figure class="highlight stylus"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">npm <span class="selector-tag">i</span> nrm -g</div></pre></td></tr></table></figure><p>然后如下操作:</p><p><img src="https://ws1.sinaimg.cn/large/006tKfTcly1fjhuypg0s6j31co0v6439.jpg" alt=""></p><p><strong>开始!!</strong></p><p>1.<strong>新建一个文件夹,名字自己起,打开终端,切换到自己新建文件夹,如</strong>:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="built_in">cd</span> (文件夹名称)</div></pre></td></tr></table></figure><p>2.<strong>生成 <code>package.json</code></strong></p><figure class="highlight coffeescript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="built_in">npm</span> init -y</div></pre></td></tr></table></figure><p>3.<strong>安装 express</strong></p><figure class="highlight maxima"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">npm i <span class="built_in">express</span> --<span class="built_in">save</span></div></pre></td></tr></table></figure><p>4.<strong>安装 <a href="http://www.expressjs.com.cn/starter/generator.html" target="_blank" rel="external">express生成器</a>:</strong></p><figure class="highlight maxima"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">npm install <span class="built_in">express</span>-generator --<span class="built_in">save</span></div></pre></td></tr></table></figure><p>5.<strong>生成 ejs 模板(类似 jsp 的写法)</strong></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">express <span class="_">-f</span> <span class="_">-e</span></div><div class="line">npm i</div></pre></td></tr></table></figure><p><img src="https://ws3.sinaimg.cn/large/006tKfTcly1fjhv8g9apcj30au0cqq30.jpg" alt=""></p><p>其中<code>public</code>用来存放编译后的js文件以及编译好的css文件等,<code>routes</code>用来存放处理 ajax 的请求文件,views就是存放视图文件<br>然后新建 database 和 src:</p><p><img src="https://ws1.sinaimg.cn/large/006tKfTcly1fji1acleqhj30ba0k0mxg.jpg" alt=""></p><p>其中 src/js 里面 app 代表不同页面的入口文件,lib 就是一些常用的库,mod 就是你写的一些模块,database 用来存放数据库数据的</p><p>6.<strong>输入:</strong></p><figure class="highlight coffeescript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="built_in">npm</span> start</div></pre></td></tr></table></figure><p>如果有出现下面的错误:</p><p><img src="https://ws3.sinaimg.cn/large/006tKfTcly1fjhvfxr6p3j319i0qq42h.jpg" alt=""></p><p>出现这个错误是因为你没有下载模块,只需在终端输入:</p><figure class="highlight stylus"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">npm <span class="selector-tag">i</span> (模块名) --save</div></pre></td></tr></table></figure><p>就可以了</p><p>7.<strong>打开浏览器,输入<code>localhost:3000</code></strong><br>出现下面这样就说明成功了:</p><p><img src="https://ws2.sinaimg.cn/large/006tKfTcly1fjhvj4lwtgj316a0cgjrb.jpg" alt=""></p><p>8.<strong>接下来安装webpack和相关依赖</strong></p><figure class="highlight maxima"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">npm i webpack --<span class="built_in">save</span>-dev</div><div class="line">npm i --<span class="built_in">save</span> css-loader <span class="built_in">style</span>-loader <span class="built_in">express</span>-session <span class="built_in">express</span>-flash node-sass passport sass sass-loader sequelize sqlite3 extract-text-webpack-plugin onchange</div></pre></td></tr></table></figure><p>9.<strong>在 src 里建一个 webpack.config.js,配置如下</strong>:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> webpack = <span class="built_in">require</span>(<span class="string">'webpack'</span>);</div><div class="line"><span class="keyword">var</span> path = <span class="built_in">require</span>(<span class="string">'path'</span>);</div><div class="line"><span class="keyword">var</span> ExtractTextPlugin = <span class="built_in">require</span>(<span class="string">'extract-text-webpack-plugin'</span>)</div><div class="line"><span class="keyword">var</span> autoprefixer = <span class="built_in">require</span>(<span class="string">'autoprefixer'</span>);</div><div class="line"> </div><div class="line"><span class="built_in">module</span>.exports = {</div><div class="line"> entry: path.join(__dirname, <span class="string">"js/app/index"</span>),</div><div class="line"> output: {</div><div class="line"> path: path.join(__dirname, <span class="string">"../public"</span>),</div><div class="line"> filename: <span class="string">"js/index.js"</span></div><div class="line"> },</div><div class="line"> <span class="keyword">module</span>: {</div><div class="line"> rules: [{</div><div class="line"> test: <span class="regexp">/(\.scss)$/</span>,</div><div class="line"> use: ExtractTextPlugin.extract({</div><div class="line"> fallback: <span class="string">"style-loader"</span>,</div><div class="line"> use: [<span class="string">"css-loader"</span>, <span class="string">"sass-loader"</span>]</div><div class="line"> }) <span class="comment">//把 css 抽离出来生成一个文件</span></div><div class="line"> }]</div><div class="line"> },</div><div class="line"> resolve: {</div><div class="line"> alias: {</div><div class="line"> jquery: path.join(__dirname, <span class="string">"js/lib/jquery-2.0.3.min.js"</span>),</div><div class="line"> mod: path.join(__dirname, <span class="string">"js/mod"</span>),</div><div class="line"> sass: path.join(__dirname, <span class="string">"sass"</span>)</div><div class="line"> }</div><div class="line"> },</div><div class="line"> plugins: [</div><div class="line"> <span class="keyword">new</span> webpack.ProvidePlugin({</div><div class="line"> $: <span class="string">"jquery"</span></div><div class="line"> }),</div><div class="line"> <span class="keyword">new</span> ExtractTextPlugin(<span class="string">"css/index.css"</span>),</div><div class="line"> <span class="keyword">new</span> webpack.LoaderOptionsPlugin({</div><div class="line"> options: {</div><div class="line"> css: [</div><div class="line"> autoprefixer(),</div><div class="line"> ]</div><div class="line"> }</div><div class="line"> }),</div><div class="line"> <span class="keyword">new</span> webpack.optimize.UglifyJsPlugin({</div><div class="line"> compress: {</div><div class="line"> warnings: <span class="literal">false</span></div><div class="line"> }</div><div class="line"> })</div><div class="line"> ]</div><div class="line">}</div></pre></td></tr></table></figure><p>说明</p><ul><li>entry:入口文件,也就是 src/js/app里面的index.js,其中__dirname是获得当前文件所在目录的完整目录名</li><li>output:输出编译后的文件 index.js,输出到 public/js 里面</li><li>module:配置Loaders,通过使用不同的loader,webpack有能力调用外部的脚本或工具,实现对不同格式的文件的处理,比如说分析转换scss为css,或者把下一代的JS文件</li><li>resolve.alias:设置模块别名,便于我们更方便引用,比如说我在 js里面的文件需要 jquery,在里面的文件直接写 require(“jquery”) 就行了</li><li><p>如果所有文件都需要 jquery,那么直接在 plugins里面写成这样:</p><p><img src="https://ws1.sinaimg.cn/large/006tKfTcly1fji3f1ap39j30ik03cglh.jpg" alt=""></p><p>就不需要 require 了</p><p><img src="https://ws3.sinaimg.cn/large/006tKfTcly1fji3x6gw2oj30i005q748.jpg" alt=""><br>这个是压缩文件的</p></li></ul><p>10.<strong>在 package.json 中,增加如下两条:</strong><br><img src="https://ws2.sinaimg.cn/large/006tKfTcly1fji3q8xe7tj310i068js2.jpg" alt=""></p><p>写成这样,你在终端就可以写成<code>npm run webpack</code> 来编译文件,<br><code>npm run watch</code>来监控 src 里面的 js 和 scss 的变化,只要一修改,进行编译,提高了效率</p><p>11.<strong>测试</strong></p><p>你可以试试在 js 里面的 index.js写点东西,然后 npm run webpack,如果终端显示是这样:</p><p><img src="https://ws4.sinaimg.cn/large/006tKfTcly1fji43t9rgej31b20ug0y0.jpg" alt=""></p><p>就证明成功了</p><h2 id="项目思路"><a href="#项目思路" class="headerlink" title="项目思路"></a>项目思路</h2><p>逻辑比较简单</p><ol><li>首先用户必须登录才能添加笔记,当用户失焦的时候,将数据插入数据库,并且重新布局(瀑布流)</li><li>用户不能更改其他用户的笔记,除了管理员😄</li><li>用户更新笔记之后,数据库的数据重新更新,重新布局</li><li>用户可以删除笔记,数据从数据库中删除,重新布局</li><li>用户可以拖拽笔记,但不将位置存入数据库</li></ol><h2 id="实现"><a href="#实现" class="headerlink" title="实现"></a>实现</h2><p>html,css就不讲了,可以看看我的<a href="https://github.com/shenzekun/sticky-note" target="_blank" rel="external">源码</a>,主要讲 js。</p><p>1.<strong>瀑布流的实现</strong></p><p>思路:(前提是必须绝对定位)</p><blockquote><ol><li>获取元素的宽度</li><li>通过窗口的宽度除以元素的宽度来获取列数</li><li>初始化一个数组来获取每列的高度,初始化每列的高度为0</li><li>遍历元素,获取最小的的列数的高度和索引,对当前元素进行定位,列数高度加等于当前元素的高度</li></ol></blockquote><p>知道思路后,代码很快就写出来了:</p><figure class="highlight php"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> WaterFall = (<span class="function"><span class="keyword">function</span> <span class="params">()</span> </span>{</div><div class="line"> <span class="keyword">var</span> $ct, $items;</div><div class="line"> <span class="function"><span class="keyword">function</span> <span class="title">render</span><span class="params">($c)</span> </span>{</div><div class="line"> $ct = $c;</div><div class="line"> $items = $ct.children();</div><div class="line"> <span class="keyword">var</span> nodeWidth = $items.outerWidth(<span class="keyword">true</span>),</div><div class="line"> windowHeight = $(window).height(),</div><div class="line"> colNum = parseInt($(window).width() / nodeWidth), <span class="comment">//获取列数</span></div><div class="line"> colSumHeight = []; <span class="comment">//获取每列的高度</span></div><div class="line"> <span class="comment">//对每列的高度进行初始化</span></div><div class="line"> <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i < colNum; i++) {</div><div class="line"> colSumHeight[i] = <span class="number">0</span>;</div><div class="line"> }</div><div class="line"> $items.each(<span class="function"><span class="keyword">function</span> <span class="params">()</span> </span>{</div><div class="line"> <span class="keyword">var</span> $current = $(this);</div><div class="line"> <span class="keyword">var</span> index = <span class="number">0</span>,</div><div class="line"> minSumHeight = colSumHeight[<span class="number">0</span>];</div><div class="line"> <span class="comment">//获取最小的的列数的高度和索引</span></div><div class="line"> <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i < colSumHeight.length; i++) {</div><div class="line"> <span class="keyword">if</span> (minSumHeight > colSumHeight[i]) {</div><div class="line"> index = i;</div><div class="line"> minSumHeight = colSumHeight[i];</div><div class="line"> }</div><div class="line"> } </div><div class="line"> <span class="comment">//改变窗口高度</span></div><div class="line"> <span class="keyword">if</span> (windowHeight < minSumHeight) {</div><div class="line"> $(<span class="string">"body"</span>).height(minSumHeight);</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> $(<span class="string">"body"</span>).height(windowHeight - <span class="number">72</span>);</div><div class="line"> }</div><div class="line"> <span class="comment">//对当前元素进行定位</span></div><div class="line"> $current.animate({</div><div class="line"> left: nodeWidth * index,</div><div class="line"> top: minSumHeight</div><div class="line"> }, <span class="number">5</span>);</div><div class="line"> colSumHeight[index] += $current.outerHeight(<span class="keyword">true</span>);</div><div class="line"> </div><div class="line"> });</div><div class="line"> }</div><div class="line"> <span class="comment">//当窗口发生变化时,重新渲染</span></div><div class="line"> $(window).on(<span class="string">'resize'</span>, <span class="function"><span class="keyword">function</span> <span class="params">()</span> </span>{</div><div class="line"> render($ct);</div><div class="line"> });</div><div class="line"> <span class="keyword">return</span> {</div><div class="line"> init: render</div><div class="line"> }</div><div class="line"> })();</div></pre></td></tr></table></figure><p>2.<strong>笔记的拖拽</strong></p><p>我们先看个图</p><p><img src="https://ws1.sinaimg.cn/large/006tKfTcly1fji626ceeuj30r40p8t96.jpg" alt=""></p><p>因此代码如下:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div></pre></td><td class="code"><pre><div class="line"><span class="comment">//设置笔记的移动</span></div><div class="line"> $noteHead.on(<span class="string">'mousedown'</span>, <span class="function"><span class="keyword">function</span> (<span class="params">e</span>) </span>{</div><div class="line"> <span class="keyword">var</span> evtX = e.pageX - $note.offset().left, <span class="comment">//evtX 计算事件的触发点在 dialog内部到 dialog 的左边缘的距离</span></div><div class="line"> evtY = e.pageY - $note.offset().top;</div><div class="line"> $note.addClass(<span class="string">'draggable'</span>).data(<span class="string">'evtPos'</span>, {</div><div class="line"> <span class="attr">x</span>: evtX,</div><div class="line"> <span class="attr">y</span>: evtY</div><div class="line"> }); <span class="comment">//把事件到 dialog 边缘的距离保存下来</span></div><div class="line"> }).on(<span class="string">'mouseup'</span>, <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</div><div class="line"> $note.removeClass(<span class="string">'draggable'</span>).removeData(<span class="string">'pos'</span>);</div><div class="line"> });</div><div class="line"> </div><div class="line"> $(<span class="string">'body'</span>).on(<span class="string">'mousemove'</span>, <span class="function"><span class="keyword">function</span> (<span class="params">e</span>) </span>{</div><div class="line"> $(<span class="string">'.draggable'</span>).length && $(<span class="string">'.draggable'</span>).offset({</div><div class="line"> <span class="attr">top</span>: e.pageY - $(<span class="string">'.draggable'</span>).data(<span class="string">'evtPos'</span>).y, <span class="comment">// 当用户鼠标移动时,根据鼠标的位置和前面保存的距离,计算 dialog 的绝对位置</span></div><div class="line"> left: e.pageX - $(<span class="string">'.draggable'</span>).data(<span class="string">'evtPos'</span>).x</div><div class="line"> });</div><div class="line"> });</div><div class="line"> },</div></pre></td></tr></table></figure><p>3.<strong>提示模块</strong></p><p>这个比较容易:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div></pre></td><td class="code"><pre><div class="line"><span class="comment">/* </span></div><div class="line">提示模块</div><div class="line">参数:状态(1表示成功,0表示失败),消息,出现时间(不写默认是1s)</div><div class="line"> */</div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">toast</span>(<span class="params">status, msg, time</span>) </span>{</div><div class="line"> <span class="keyword">this</span>.status = status;</div><div class="line"> <span class="keyword">this</span>.msg = msg;</div><div class="line"> <span class="keyword">this</span>.time = time || <span class="number">1000</span>;</div><div class="line"> <span class="keyword">this</span>.createToast();</div><div class="line"> <span class="keyword">this</span>.showToast();</div><div class="line">}</div><div class="line"></div><div class="line">toast.prototype = {</div><div class="line"> <span class="attr">createToast</span>: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</div><div class="line"> <span class="keyword">if</span> (<span class="keyword">this</span>.status === <span class="number">1</span>) {</div><div class="line"> <span class="keyword">var</span> html = <span class="string">'<div class="toast"><img src="../../imgs/1.png" class="toast_icon"></img><span class="toast_word">'</span> + <span class="keyword">this</span>.msg + <span class="string">'</span></div>'</span>;</div><div class="line"> <span class="keyword">this</span>.$toast = $(html);</div><div class="line"> $(<span class="string">'body'</span>).append(<span class="keyword">this</span>.$toast);</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> <span class="keyword">var</span> html = <span class="string">'<div class="toast"><img src="../../imgs/0.png" class="toast_icon"></img><span class="toast_word">'</span> + <span class="keyword">this</span>.msg + <span class="string">'</span></div>'</span>;</div><div class="line"> <span class="keyword">this</span>.$toast = $(html);</div><div class="line"> $(<span class="string">'body'</span>).append(<span class="keyword">this</span>.$toast);</div><div class="line"> }</div><div class="line"> },</div><div class="line"> <span class="attr">showToast</span>: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</div><div class="line"> <span class="keyword">var</span> _this = <span class="keyword">this</span>;</div><div class="line"> <span class="keyword">this</span>.$toast.fadeIn(<span class="number">300</span>, <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</div><div class="line"> setTimeout(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</div><div class="line"> _this.$toast.fadeOut(<span class="number">300</span>, <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</div><div class="line"> _this.$toast.remove();</div><div class="line"> });</div><div class="line"> }, _this.time);</div><div class="line"> })</div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">Toast</span>(<span class="params">status, msg, time</span>) </span>{</div><div class="line"> <span class="keyword">return</span> <span class="keyword">new</span> toast(status, msg, time);</div><div class="line">}</div></pre></td></tr></table></figure><p>4.<strong>笔记模块</strong></p><p>思路:</p><blockquote><ol><li>初始化(如 id,username 等等)</li><li>创建节点</li><li>设置颜色</li><li>绑定事件</li></ol></blockquote><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div><div class="line">57</div><div class="line">58</div><div class="line">59</div><div class="line">60</div><div class="line">61</div><div class="line">62</div><div class="line">63</div><div class="line">64</div><div class="line">65</div><div class="line">66</div><div class="line">67</div><div class="line">68</div><div class="line">69</div><div class="line">70</div><div class="line">71</div><div class="line">72</div><div class="line">73</div><div class="line">74</div><div class="line">75</div><div class="line">76</div><div class="line">77</div><div class="line">78</div><div class="line">79</div><div class="line">80</div><div class="line">81</div><div class="line">82</div><div class="line">83</div><div class="line">84</div><div class="line">85</div><div class="line">86</div><div class="line">87</div><div class="line">88</div><div class="line">89</div><div class="line">90</div><div class="line">91</div><div class="line">92</div><div class="line">93</div><div class="line">94</div><div class="line">95</div><div class="line">96</div><div class="line">97</div><div class="line">98</div><div class="line">99</div><div class="line">100</div><div class="line">101</div><div class="line">102</div><div class="line">103</div><div class="line">104</div><div class="line">105</div><div class="line">106</div><div class="line">107</div><div class="line">108</div><div class="line">109</div><div class="line">110</div><div class="line">111</div><div class="line">112</div><div class="line">113</div><div class="line">114</div><div class="line">115</div><div class="line">116</div><div class="line">117</div><div class="line">118</div><div class="line">119</div><div class="line">120</div><div class="line">121</div><div class="line">122</div><div class="line">123</div><div class="line">124</div><div class="line">125</div><div class="line">126</div><div class="line">127</div><div class="line">128</div><div class="line">129</div><div class="line">130</div><div class="line">131</div><div class="line">132</div><div class="line">133</div><div class="line">134</div><div class="line">135</div><div class="line">136</div><div class="line">137</div><div class="line">138</div><div class="line">139</div><div class="line">140</div><div class="line">141</div><div class="line">142</div><div class="line">143</div><div class="line">144</div><div class="line">145</div><div class="line">146</div><div class="line">147</div><div class="line">148</div><div class="line">149</div><div class="line">150</div><div class="line">151</div><div class="line">152</div><div class="line">153</div><div class="line">154</div><div class="line">155</div><div class="line">156</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">Note</span>(<span class="params">opts</span>) </span>{</div><div class="line"> <span class="keyword">this</span>.initOpts(opts);</div><div class="line"> <span class="keyword">this</span>.createNode();</div><div class="line"> <span class="keyword">this</span>.setColor();</div><div class="line"> <span class="keyword">this</span>.bind();</div><div class="line">}</div><div class="line"></div><div class="line">Note.prototype = {</div><div class="line"> <span class="attr">colors</span>: [</div><div class="line"> [<span class="string">'#ea9b35'</span>, <span class="string">'#efb04e'</span>], <span class="comment">// headColor, containerColor</span></div><div class="line"> [<span class="string">'#dd598b'</span>, <span class="string">'#e672a2'</span>],</div><div class="line"> [<span class="string">'#c24226'</span>, <span class="string">'#d15a39'</span>],</div><div class="line"> [<span class="string">'#c1c341'</span>, <span class="string">'#d0d25c'</span>],</div><div class="line"> [<span class="string">'#3f78c3'</span>, <span class="string">'#5591d2'</span>]</div><div class="line"> ],</div><div class="line"> <span class="attr">defaultOpts</span>: {</div><div class="line"> <span class="attr">id</span>: <span class="string">''</span>, <span class="comment">//Note的 id</span></div><div class="line"> $ct: $(<span class="string">'#content'</span>).length > <span class="number">0</span> ? $(<span class="string">'#content'</span>) : $(<span class="string">'body'</span>), <span class="comment">//默认存放 Note 的容器</span></div><div class="line"> context: <span class="string">'请输入内容'</span>, <span class="comment">//Note 的内容</span></div><div class="line"> createTime: <span class="keyword">new</span> <span class="built_in">Date</span>().toLocaleDateString().replace(<span class="regexp">/\//g</span>, <span class="string">'-'</span>).match(<span class="regexp">/^\d{4}-\d{1,2}-\d{1,2}/</span>),</div><div class="line"> <span class="attr">username</span>: <span class="string">'admin'</span></div><div class="line"> },</div><div class="line"> <span class="attr">initOpts</span>: <span class="function"><span class="keyword">function</span> (<span class="params">opts</span>) </span>{</div><div class="line"> <span class="keyword">this</span>.opts = $.extend({}, <span class="keyword">this</span>.defaultOpts, opts || {});</div><div class="line"> <span class="keyword">if</span> (<span class="keyword">this</span>.opts.id) {</div><div class="line"> <span class="keyword">this</span>.id = <span class="keyword">this</span>.opts.id;</div><div class="line"> }</div><div class="line"> <span class="keyword">this</span>.createTime = <span class="keyword">this</span>.opts.createTime ? <span class="keyword">this</span>.opts.createTime : <span class="keyword">new</span> <span class="built_in">Date</span>().toLocaleDateString().replace(<span class="regexp">/\//g</span>, <span class="string">'-'</span>).match(<span class="regexp">/^\d{4}-\d{1,2}-\d{1,2}/</span>);</div><div class="line"> <span class="keyword">this</span>.username = <span class="keyword">this</span>.opts.username ? <span class="keyword">this</span>.opts.username : <span class="string">'admin'</span></div><div class="line"> },</div><div class="line"> <span class="attr">createNode</span>: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</div><div class="line"> <span class="keyword">var</span> tpl = <span class="string">'<div class="note">'</span> +</div><div class="line"> <span class="string">'<div class="note-head"><span class="delete">&times;</span></div>'</span> +</div><div class="line"> <span class="string">'<div class="note-ct" contenteditable="true"></div>'</span> +</div><div class="line"> <span class="string">'<div class="note-info"><div class="note-name">'</span> + <span class="keyword">this</span>.username + <span class="string">'</div><div class="note-time">'</span> + <span class="keyword">this</span>.createTime + <span class="string">'</div>'</span> +</div><div class="line"> <span class="string">'</div>'</span>;</div><div class="line"> <span class="keyword">this</span>.$note = $(tpl);</div><div class="line"> <span class="keyword">this</span>.$note.find(<span class="string">'.note-ct'</span>).html(<span class="keyword">this</span>.opts.context);</div><div class="line"> <span class="keyword">this</span>.opts.$ct.append(<span class="keyword">this</span>.$note);</div><div class="line"> <span class="comment">//if (!this.id) this.$note.css('bottom', '10px'); //新增放到右边</span></div><div class="line"> Event.fire(<span class="string">'waterfall'</span>);</div><div class="line"> },</div><div class="line"></div><div class="line"> <span class="attr">setColor</span>: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</div><div class="line"> <span class="keyword">var</span> color = <span class="keyword">this</span>.colors[<span class="built_in">Math</span>.floor(<span class="built_in">Math</span>.random() * <span class="number">5</span>)];</div><div class="line"> <span class="keyword">this</span>.$note.find(<span class="string">".note-head"</span>).css(<span class="string">'background-color'</span>, color[<span class="number">0</span>]);</div><div class="line"> <span class="keyword">this</span>.$note.find(<span class="string">'.note-ct'</span>).css(<span class="string">'background-color'</span>, color[<span class="number">1</span>]);</div><div class="line"> <span class="keyword">this</span>.$note.find(<span class="string">'.note-info'</span>).css(<span class="string">'background-color'</span>, color[<span class="number">1</span>]);</div><div class="line"> },</div><div class="line"> <span class="attr">setLayout</span>: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</div><div class="line"> <span class="keyword">var</span> self = <span class="keyword">this</span>;</div><div class="line"> <span class="keyword">if</span> (self.clock) {</div><div class="line"> clearTimeout(self.clock);</div><div class="line"> }</div><div class="line"> self.clock = setTimeout(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</div><div class="line"> Event.fire(<span class="string">'waterfall'</span>);</div><div class="line"> }, <span class="number">100</span>);</div><div class="line"> },</div><div class="line"> <span class="attr">bind</span>: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</div><div class="line"> <span class="keyword">var</span> _this = <span class="keyword">this</span>, <span class="comment">//记录下坑,之前末尾是分号不是逗号后面都变成了全局变量结果造成了最后一个才能修改😂</span></div><div class="line"> $note = <span class="keyword">this</span>.$note,</div><div class="line"> $noteHead = $note.find(<span class="string">'.note-head'</span>),</div><div class="line"> $noteCt = $note.find(<span class="string">'.note-ct'</span>),</div><div class="line"> $close = $note.find(<span class="string">'.delete'</span>);</div><div class="line"></div><div class="line"> $close.on(<span class="string">'click'</span>, <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</div><div class="line"> _this.delete();</div><div class="line"> });</div><div class="line"></div><div class="line"> $noteCt.on(<span class="string">'focus'</span>, <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</div><div class="line"> <span class="keyword">if</span> ($noteCt.html() === <span class="string">'请输入内容'</span>) $noteCt.html(<span class="string">''</span>);</div><div class="line"> $noteCt.data(<span class="string">'before'</span>, $noteCt.html());</div><div class="line"> }).on(<span class="string">'blur paste'</span>, <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</div><div class="line"> <span class="keyword">if</span> ($noteCt.data(<span class="string">'before'</span>) != $noteCt.html()) {</div><div class="line"> $noteCt.data(<span class="string">'before'</span>, $noteCt.html());</div><div class="line"> _this.setLayout();</div><div class="line"> <span class="keyword">if</span> (_this.id) { <span class="comment">//判断是否有这个id,如果有就更新,如果没有就添加</span></div><div class="line"> _this.edit($noteCt.html())</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> _this.add($noteCt.html())</div><div class="line"> }</div><div class="line"> }</div><div class="line"> });</div><div class="line"></div><div class="line"> <span class="comment">//设置笔记的移动</span></div><div class="line"> $noteHead.on(<span class="string">'mousedown'</span>, <span class="function"><span class="keyword">function</span> (<span class="params">e</span>) </span>{</div><div class="line"> <span class="keyword">var</span> evtX = e.pageX - $note.offset().left, <span class="comment">//evtX 计算事件的触发点在 dialog内部到 dialog 的左边缘的距离</span></div><div class="line"> evtY = e.pageY - $note.offset().top;</div><div class="line"> $note.addClass(<span class="string">'draggable'</span>).data(<span class="string">'evtPos'</span>, {</div><div class="line"> <span class="attr">x</span>: evtX,</div><div class="line"> <span class="attr">y</span>: evtY</div><div class="line"> }); <span class="comment">//把事件到 dialog 边缘的距离保存下来</span></div><div class="line"> }).on(<span class="string">'mouseup'</span>, <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</div><div class="line"> $note.removeClass(<span class="string">'draggable'</span>).removeData(<span class="string">'pos'</span>);</div><div class="line"> });</div><div class="line"></div><div class="line"> $(<span class="string">'body'</span>).on(<span class="string">'mousemove'</span>, <span class="function"><span class="keyword">function</span> (<span class="params">e</span>) </span>{</div><div class="line"> $(<span class="string">'.draggable'</span>).length && $(<span class="string">'.draggable'</span>).offset({</div><div class="line"> <span class="attr">top</span>: e.pageY - $(<span class="string">'.draggable'</span>).data(<span class="string">'evtPos'</span>).y, <span class="comment">// 当用户鼠标移动时,根据鼠标的位置和前面保存的距离,计算 dialog 的绝对位置</span></div><div class="line"> left: e.pageX - $(<span class="string">'.draggable'</span>).data(<span class="string">'evtPos'</span>).x</div><div class="line"> });</div><div class="line"> });</div><div class="line"> },</div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"> <span class="comment">/* 添加笔记到数据库 */</span></div><div class="line"> add: <span class="function"><span class="keyword">function</span> (<span class="params">msg</span>) </span>{</div><div class="line"> <span class="keyword">var</span> _this = <span class="keyword">this</span>;</div><div class="line"> $.post(<span class="string">'/api/notes/add'</span>, {</div><div class="line"> <span class="attr">note</span>: msg</div><div class="line"> }).done(<span class="function"><span class="keyword">function</span> (<span class="params">res</span>) </span>{</div><div class="line"> <span class="keyword">if</span> (res.status === <span class="number">1</span>) {</div><div class="line"> _this.id = res.id;</div><div class="line"> Toast(<span class="number">1</span>, <span class="string">'添加成功!'</span>);</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> _this.$note.remove();</div><div class="line"> Event.fire(<span class="string">'waterfall'</span>);</div><div class="line"> Toast(<span class="number">0</span>, res.errorMsg);</div><div class="line"> }</div><div class="line"> })</div><div class="line"> },</div><div class="line"> <span class="comment">/* 编辑笔记数据库 */</span></div><div class="line"> edit: <span class="function"><span class="keyword">function</span> (<span class="params">msg</span>) </span>{</div><div class="line"> <span class="keyword">var</span> _this = <span class="keyword">this</span>;</div><div class="line"> $.post(<span class="string">'/api/notes/edit'</span>, {</div><div class="line"> <span class="attr">id</span>: <span class="keyword">this</span>.id,</div><div class="line"> <span class="attr">note</span>: msg</div><div class="line"> }).done(<span class="function"><span class="keyword">function</span> (<span class="params">res</span>) </span>{</div><div class="line"> <span class="keyword">if</span> (res.status === <span class="number">1</span>) {</div><div class="line"> Toast(<span class="number">1</span>, <span class="string">'更新成功!'</span>);</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> Toast(<span class="number">0</span>, res.errorMsg);</div><div class="line"> }</div><div class="line"> });</div><div class="line"> },</div><div class="line"> <span class="comment">/* 删除笔记 */</span></div><div class="line"> <span class="keyword">delete</span>: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</div><div class="line"> <span class="keyword">var</span> _this = <span class="keyword">this</span>;</div><div class="line"> <span class="keyword">if</span> (confirm(<span class="string">"确认要删除吗?"</span>)) {</div><div class="line"> $.post(<span class="string">'/api/notes/delete'</span>, {</div><div class="line"> <span class="attr">id</span>: <span class="keyword">this</span>.id</div><div class="line"> }).done(<span class="function"><span class="keyword">function</span> (<span class="params">res</span>) </span>{</div><div class="line"> <span class="keyword">if</span> (res.status === <span class="number">1</span>) {</div><div class="line"> Toast(<span class="number">1</span>, <span class="string">'删除成功!'</span>);</div><div class="line"> _this.$note.remove();</div><div class="line"> Event.fire(<span class="string">'waterfall'</span>)</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> Toast(<span class="number">0</span>, res.errorMsg);</div><div class="line"> }</div><div class="line"> });</div><div class="line"> }</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure><p>5.<strong>笔记管理模块</strong></p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> NoteManager = (<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</div><div class="line"> <span class="comment">//页面加载</span></div><div class="line"> <span class="function"><span class="keyword">function</span> <span class="title">load</span>(<span class="params"></span>) </span>{</div><div class="line"> $.get(<span class="string">'api/notes'</span>).done(<span class="function"><span class="keyword">function</span> (<span class="params">res</span>) </span>{</div><div class="line"> <span class="keyword">if</span> (res.status === <span class="number">1</span>) {</div><div class="line"> $.each(res.data, <span class="function"><span class="keyword">function</span> (<span class="params">index, msg</span>) </span>{</div><div class="line"> <span class="keyword">new</span> Note({</div><div class="line"> <span class="attr">id</span>: msg.id,</div><div class="line"> <span class="attr">context</span>: msg.text,</div><div class="line"> <span class="attr">createTime</span>: msg.createdAt.match(<span class="regexp">/^\d{4}-\d{1,2}-\d{1,2}/</span>),</div><div class="line"> <span class="attr">username</span>: msg.username</div><div class="line"> });</div><div class="line"> });</div><div class="line"></div><div class="line"> Event.fire(<span class="string">'waterfall'</span>);</div><div class="line"></div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> Toast(<span class="number">0</span>, res.errorMsg);</div><div class="line"> }</div><div class="line"> }).fail(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</div><div class="line"> Toast(<span class="number">0</span>, <span class="string">"网络异常"</span>);</div><div class="line"> });</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">/* 添加笔记 */</span></div><div class="line"> <span class="function"><span class="keyword">function</span> <span class="title">add</span>(<span class="params"></span>) </span>{</div><div class="line"> $.get(<span class="string">'/login'</span>).then(<span class="function"><span class="keyword">function</span> (<span class="params">res</span>) </span>{<span class="comment">//判断是否登录</span></div><div class="line"> <span class="keyword">if</span> (res.status === <span class="number">1</span>) {</div><div class="line"> <span class="keyword">new</span> Note({</div><div class="line"> <span class="attr">username</span>: res.username</div><div class="line"> });</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> Toast(<span class="number">0</span>, res.errorMsg);</div><div class="line"> }</div><div class="line"> });</div><div class="line"> }</div><div class="line"> <span class="keyword">return</span> {</div><div class="line"> <span class="attr">load</span>: load,</div><div class="line"> <span class="attr">add</span>: add</div><div class="line"> }</div><div class="line">})();</div></pre></td></tr></table></figure><p>6.<strong>发布订阅模式</strong></p><figure class="highlight qml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div></pre></td><td class="code"><pre><div class="line"><span class="comment">/* 发布订阅模式 */</span></div><div class="line"><span class="built_in">var</span> Event = (<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</div><div class="line"> <span class="built_in">var</span> events = {};</div><div class="line"></div><div class="line"> <span class="function"><span class="keyword">function</span> <span class="title">on</span>(<span class="params">evt, handler</span>) </span>{</div><div class="line"> events[evt] = events[evt] || [];</div><div class="line"> events[evt].push({</div><div class="line"> <span class="attribute">handler</span>: handler</div><div class="line"> });</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="function"><span class="keyword">function</span> <span class="title">fire</span>(<span class="params">evt, args</span>) </span>{</div><div class="line"> <span class="keyword">if</span> (!events[evt]) {</div><div class="line"> <span class="keyword">return</span>;</div><div class="line"> }</div><div class="line"> <span class="keyword">for</span> (<span class="built_in">var</span> i = <span class="number">0</span>; i < events[evt].length; i++) {</div><div class="line"> events[evt][i].handler(args);</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="function"><span class="keyword">function</span> <span class="title">off</span>(<span class="params">name</span>) </span>{</div><div class="line"> <span class="keyword">delete</span> events[name];</div><div class="line"> }</div><div class="line"> <span class="keyword">return</span> {</div><div class="line"> <span class="attribute">on</span>: <span class="keyword">on</span>,</div><div class="line"> <span class="attribute">fire</span>: fire,</div><div class="line"> <span class="attribute">off</span>: off</div><div class="line"> }</div><div class="line">})();</div></pre></td></tr></table></figure><p>写完模块后,写入口文件index.js</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div></pre></td><td class="code"><pre><div class="line"><span class="built_in">require</span>(<span class="string">'sass/index.scss'</span>);</div><div class="line"><span class="keyword">var</span> Toast = <span class="built_in">require</span>(<span class="string">'mod/toast.js'</span>).Toast;</div><div class="line"><span class="keyword">var</span> WaterFall = <span class="built_in">require</span>(<span class="string">'mod/waterfall.js'</span>);</div><div class="line"><span class="keyword">var</span> NoteManager = <span class="built_in">require</span>(<span class="string">'mod/note-manager'</span>);</div><div class="line"><span class="keyword">var</span> Event = <span class="built_in">require</span>(<span class="string">'mod/event.js'</span>);</div><div class="line"></div><div class="line"></div><div class="line">NoteManager.load();</div><div class="line">$(<span class="string">'.add-note'</span>).on(<span class="string">'click'</span>, <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</div><div class="line"> NoteManager.add();</div><div class="line">})</div><div class="line"></div><div class="line">Event.on(<span class="string">'waterfall'</span>, <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</div><div class="line"> WaterFall.init($(<span class="string">"#content"</span>));</div><div class="line">})</div></pre></td></tr></table></figure><p>到这就差不多完成了70%了,接下来就创建数据库,连接数据库了</p><figure class="highlight lua"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div><div class="line">57</div><div class="line">58</div><div class="line">59</div><div class="line">60</div><div class="line">61</div><div class="line">62</div><div class="line">63</div></pre></td><td class="code"><pre><div class="line">/*创建数据库 运行 node note.js*/</div><div class="line"></div><div class="line">var Sequelize = <span class="built_in">require</span>(<span class="string">'sequelize'</span>);</div><div class="line">var path = <span class="built_in">require</span>(<span class="string">'path'</span>);</div><div class="line"></div><div class="line">var sequelize = new Sequelize(undefined, undefined, undefined, {</div><div class="line"> host: <span class="string">'localhost'</span>,</div><div class="line"> dialect: <span class="string">'sqlite'</span>,</div><div class="line"> // SQLite only</div><div class="line"> storage: path.join(__dirname, <span class="string">'../database/database.sqlite'</span>)</div><div class="line">});</div><div class="line"></div><div class="line">/* 测试连接是否成功</div><div class="line">node note.js</div><div class="line"></div><div class="line">sequelize.authenticate()</div><div class="line"> .<span class="keyword">then</span>(() => {</div><div class="line"> console.log(<span class="string">'Connection has been established successfully.'</span>);</div><div class="line"> })</div><div class="line"> .catch(err => {</div><div class="line"> console.<span class="built_in">error</span>(<span class="string">'Unable to connect to the database:'</span>, err);</div><div class="line"> });</div><div class="line"></div><div class="line">*/</div><div class="line"></div><div class="line"></div><div class="line">var Note = sequelize.define(<span class="string">'note'</span>, {</div><div class="line"> text: {</div><div class="line"> <span class="built_in">type</span>: Sequelize.STRING</div><div class="line"> },</div><div class="line"> userid: {</div><div class="line"> <span class="built_in">type</span>: Sequelize.INTEGER</div><div class="line"> },</div><div class="line"> username: {</div><div class="line"> <span class="built_in">type</span>: Sequelize.STRING</div><div class="line"> }</div><div class="line">});</div><div class="line"></div><div class="line">Note.sync();</div><div class="line"></div><div class="line">/*</div><div class="line">删除表</div><div class="line">Note.drop();</div><div class="line">*/</div><div class="line"></div><div class="line"></div><div class="line">/*</div><div class="line">//创建数据库</div><div class="line"></div><div class="line">Note.sync().<span class="keyword">then</span>(<span class="function"><span class="keyword">function</span><span class="params">()</span></span>{</div><div class="line"> Note.create({text:<span class="string">"sdsdsdsd"</span>});</div><div class="line">}).<span class="keyword">then</span>(<span class="function"><span class="keyword">function</span><span class="params">()</span></span>{</div><div class="line"> //查询表</div><div class="line"> Note.findAll({raw:<span class="keyword">true</span>}).<span class="keyword">then</span>(<span class="function"><span class="keyword">function</span><span class="params">(notes)</span></span>{</div><div class="line"> console.log(notes);</div><div class="line"> })</div><div class="line">});</div><div class="line">*/</div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"><span class="built_in">module</span>.exports = Note;</div></pre></td></tr></table></figure><p>然后是在routes 里处理 ajax 请求,处理登录信息,获取 id,用户名等等,到这就基本完成了</p><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>经过一星期的开发,了解了前后端联调,模块化开发方式、webpack 及loader和插件的使用、npm 的使用,Express的使用、路由、中间件、sqlite3、nodejs,在开发过程中还是有遇到许多问题,例如在连续声明变量的时候,不小心把逗号写成了分号,其他变量就变成了全局变量,于是就出错了,查了好久😂<br><img src="https://ws1.sinaimg.cn/large/006tKfTcly1fji7u6i1v0j30jm06y0t6.jpg" alt=""><br>不过在这过程之中还是学到了许多,重要的是过程,继续往前端的路走下去😄</p></div><div><div><div style="text-align:center;color:#ccc;font-size:14px">-------------本文结束<i class="fa fa-paw"></i>感谢您的阅读-------------</div></div></div><div><div class="my_post_copyright"><script src="//cdn.bootcss.com/clipboard.js/1.5.10/clipboard.min.js"></script><script src="https://cdn.bootcss.com/jquery/2.0.0/jquery.min.js"></script><script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script><p><span>本文标题:</span><a href="/前端小项目之在线便利贴.html">前端小项目之在线便利贴</a></p><p><span>文章作者:</span><a href="/" title="访问 shenzekun 的个人博客">shenzekun</a></p><p><span>发布时间:</span>2017年09月13日 - 20:48</p><p><span>最后更新:</span>2018年10月21日 - 20:51</p><p><span>原始链接:</span><a href="/前端小项目之在线便利贴.html" title="前端小项目之在线便利贴">http://www.shenzekun.cn/前端小项目之在线便利贴.html</a><span class="copy-path" title="点击复制文章链接"><i class="fa fa-clipboard" data-clipboard-text="http://www.shenzekun.cn/前端小项目之在线便利贴.html" aria-label="复制成功!"></i></span></p><p><span>许可协议:</span><i class="fa fa-creative-commons"></i> <a rel="license" href="https://creativecommons.org/licenses/by-nc-nd/4.0/" target="_blank" title="Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)">署名-非商业性使用-禁止演绎 4.0 国际</a> 转载请保留原文链接及作者。</p></div><script>var clipboard=new Clipboard(".fa-clipboard");$(".fa-clipboard").click(function(){clipboard.on("success",function(){swal({title:"",text:"复制成功",icon:"success",showConfirmButton:!0})})})</script></div><div></div><div><div style="padding:10px 0;margin:20px auto;width:90%;text-align:center"><div>您的支持将鼓励我继续创作!</div><button id="rewardButton" disable="enable" onclick='var qr=document.getElementById("QR");"none"===qr.style.display?qr.style.display="block":qr.style.display="none"'><span>赏</span></button><div id="QR" style="display:none"><div id="wechat" style="display:inline-block"><img id="wechat_qr" src="/image/wechat-reward-image.png" alt="shenzekun WeChat Pay"><p>微信打赏</p></div></div></div></div><footer class="post-footer"><div class="post-tags"><a href="/tags/js/" rel="tag"><i class="fa fa-tag"></i>js</a><a href="/tags/node/" rel="tag"><i class="fa fa-tag"></i> node</a></div><div class="post-nav"><div class="post-nav-next post-nav-item"><a href="/解决inline-block元素的bug.html" rel="next" title="解决inline-block元素的bug"><i class="fa fa-chevron-left"></i> 解决inline-block元素的bug</a></div><div class="post-nav-prev post-nav-item"><a href="/解决-webstrom-sass-注释中文出错问题.html" rel="prev" title="解决 webstrom sass 注释中文出错问题">解决 webstrom sass 注释中文出错问题<i class="fa fa-chevron-right"></i></a></div></div></footer></article><div class="post-spread"></div></div></div><div class="comments" id="comments"><div id="lv-container" data-id="city" data-uid="MTAyMC8yODgyMi81Mzky"></div></div></div><div class="sidebar-toggle"><div class="sidebar-toggle-line-wrap"><span class="sidebar-toggle-line sidebar-toggle-line-first"></span><span class="sidebar-toggle-line sidebar-toggle-line-middle"></span><span class="sidebar-toggle-line sidebar-toggle-line-last"></span></div></div><aside id="sidebar" class="sidebar"><div class="sidebar-inner"><ul class="sidebar-nav motion-element"><li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap">文章目录</li><li class="sidebar-nav-overview" data-target="site-overview">站点概览</li></ul><section class="site-overview sidebar-panel"><div class="site-author motion-element" itemprop="author" itemscope itemtype="//schema.org/Person"><img class="site-author-image" itemprop="image" src="https://blog-1257878287.cos.ap-chengdu.myqcloud.com/avatar1.jpg" alt="shenzekun"><p class="site-author-name" itemprop="name">shenzekun</p><p class="site-description motion-element" itemprop="description">Road endless its long and far, I will seek up and down!</p></div><nav class="site-state motion-element"><div class="site-state-item site-state-posts"><a href="/archives"><span class="site-state-item-count">39</span> <span class="site-state-item-name">日志</span></a></div><div class="site-state-item site-state-categories"><a href="/categories"><span class="site-state-item-count">6</span> <span class="site-state-item-name">分类</span></a></div><div class="site-state-item site-state-tags"><a href="/tags"><span class="site-state-item-count">19</span> <span class="site-state-item-name">标签</span></a></div></nav><div class="feed-link motion-element"><a href="/atom.xml" rel="alternate"><i class="fa fa-rss"></i> RSS</a></div><div class="links-of-author motion-element"><span class="links-of-author-item"><a href="https://github.com/shenzekun" target="_blank" rel="external nofollow" title="GitHub"><i class="fa fa-fw fa-github"></i> GitHub</a></span><span class="links-of-author-item"><a href="http://www.jianshu.com/u/b473784d730c" target="_blank" rel="external nofollow" title="简书"><i class="fa fa-fw fa-heartbeat"></i> 简书</a></span><span class="links-of-author-item"><a href="https://twitter.com/shenzekun" target="_blank" rel="external nofollow" title="Twitter"><i class="fa fa-fw fa-twitter"></i> Twitter</a></span><span class="links-of-author-item"><a href="https://segmentfault.com/u/juli_590dd17068b9e" target="_blank" rel="external nofollow" title="SegmentFault"><i class="fa fa-fw fa-meh-o"></i> SegmentFault</a></span><span class="links-of-author-item"><a href="http://blog.csdn.net/qq_33699981?viewmode=list" target="_blank" rel="external nofollow" title="csdn"><i class="fa fa-fw fa-crosshairs"></i> csdn</a></span><span class="links-of-author-item"><a href="https://juejin.im/user/5866ed77ac502e00612f1949" target="_blank" rel="external nofollow" title="掘金"><i class="fa fa-fw fa-spinner"></i> 掘金</a></span></div><div class="links-of-blogroll motion-element links-of-blogroll-inline"><div class="links-of-blogroll-title"><i class="fa fa-fw fa-globe"></i> 推荐阅读</div><ul class="links-of-blogroll-list"><li class="links-of-blogroll-item"><a href="http://www.uisdc.com/" title="优设" target="_blank">优设</a></li><li class="links-of-blogroll-item"><a href="http://www.zhangxinxu.com/" title="张鑫旭" target="_blank">张鑫旭</a></li><li class="links-of-blogroll-item"><a href="http://www.alloyteam.com/nav/" title="Web前端导航" target="_blank">Web前端导航</a></li><li class="links-of-blogroll-item"><a href="http://www.36zhen.com/t?id=3448" title="前端书籍资料" target="_blank">前端书籍资料</a></li><li class="links-of-blogroll-item"><a href="http://ife.baidu.com/" title="百度前端技术学院" target="_blank">百度前端技术学院</a></li><li class="links-of-blogroll-item"><a href="http://wf.uisdc.com/cn/" title="google前端开发基础" target="_blank">google前端开发基础</a></li></ul></div></section><section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active"><div class="post-toc"><div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#实现的效果如下:"><span class="nav-number">1.</span> <span class="nav-text">实现的效果如下:</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#预览"><span class="nav-number">2.</span> <span class="nav-text">预览</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#涉及的知识点"><span class="nav-number">3.</span> <span class="nav-text">涉及的知识点</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#实现功能"><span class="nav-number">4.</span> <span class="nav-text">实现功能</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#准备工作"><span class="nav-number">5.</span> <span class="nav-text">准备工作</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#项目思路"><span class="nav-number">6.</span> <span class="nav-text">项目思路</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#实现"><span class="nav-number">7.</span> <span class="nav-text">实现</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#总结"><span class="nav-number">8.</span> <span class="nav-text">总结</span></a></li></ol></div></div></section></div></aside></div></main><footer id="footer" class="footer"><div class="footer-inner"><div class="copyright">© <span itemprop="copyrightYear">2020</span><span class="with-love"><i class="fa fa-heart"></i></span> <span class="author" itemprop="copyrightHolder">shenzekun</span></div><div class="theme-info"><i class="fa fa-pencil"></i> <span class="post-count">博客全站共 40.7k 字</span></div></div></footer><div class="back-to-top"><i class="fa fa-arrow-up"></i></div></div><script type="text/javascript">"[object Function]"!==Object.prototype.toString.call(window.Promise)&&(window.Promise=null)</script><script type="text/javascript" src="/lib/jquery/index.js?v=2.1.3"></script><script type="text/javascript" src="/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script><script type="text/javascript" src="/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script><script type="text/javascript" src="/lib/velocity/velocity.min.js?v=1.2.1"></script><script type="text/javascript" src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script><script type="text/javascript" src="/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script><script type="text/javascript" src="/js/src/utils.js?v=5.0.2"></script><script type="text/javascript" src="/js/src/motion.js?v=5.0.2"></script><script type="text/javascript" src="/js/src/scrollspy.js?v=5.0.2"></script><script type="text/javascript" src="/js/src/post-details.js?v=5.0.2"></script><script type="text/javascript" src="/js/src/bootstrap.js?v=5.0.2"></script><script type="text/javascript">!function(e,t){var n,c=e.getElementsByTagName(t)[0];"function"!=typeof LivereTower&&((n=e.createElement(t)).src="https://cdn-city.livere.com/js/embed.dist.js",n.async=!0,c.parentNode.insertBefore(n,c))}(document,"script")</script><script type="text/javascript">function proceedsearch(){$("body").append('<div class="popoverlay">').css("overflow","hidden"),$(".popup").toggle()}var isfetched=!1,search_path="search.xml";0==search_path.length&&(search_path="search.xml");var path="/"+search_path,searchFunc=function(e,t,a){"use strict";$.ajax({url:e,dataType:"xml",async:!0,success:function(e){isfetched=!0,$(".popup").detach().appendTo(".header-inner");var r=$("entry",e).map(function(){return{title:$("title",this).text(),content:$("content",this).text(),url:$("url",this).text()}}).get(),c=document.getElementById(t),n=document.getElementById(a);c.addEventListener("input",function(){var e=0,t='<ul class="search-result-list">',a=this.value.trim().toLowerCase().split(/[\s\-]+/);n.innerHTML="",this.value.trim().length>1&&r.forEach(function(r){var c=!1,n=r.title.trim().toLowerCase(),s=r.content.trim().replace(/<[^>]+>/g,"").toLowerCase(),o=decodeURIComponent(r.url),i=-1,l=-1,p=-1;if(""!=n&&a.forEach(function(e,t){i=n.indexOf(e),l=s.indexOf(e),(i>=0||l>=0)&&(c=!0,0==t&&(p=l))}),c){e+=1,t+="<li><a href='"+o+"' class='search-result-title'>"+n+"</a>";var h=r.content.trim().replace(/<[^>]+>/g,"");if(p>=0){var u=p-20,d=p+80;u<0&&(u=0),0==u&&(d=50),d>h.length&&(d=h.length);var f=h.substring(u,d);a.forEach(function(e){var t=new RegExp(e,"gi");f=f.replace(t,'<b class="search-keyword">'+e+"</b>")}),t+='<p class="search-result">'+f+"...</p>"}t+="</li>"}}),t+="</ul>",0==e&&(t='<div id="no-result"><i class="fa fa-frown-o fa-5x" /></div>'),""==a&&(t='<div id="no-result"><i class="fa fa-search fa-5x" /></div>'),n.innerHTML=t}),proceedsearch()}})};$(".popup-trigger").click(function(e){e.stopPropagation(),0==isfetched?searchFunc(path,"local-search-input","local-search-result"):proceedsearch()}),$(".popup-btn-close").click(function(e){$(".popup").hide(),$(".popoverlay").remove(),$("body").css("overflow","")}),$(".popup").click(function(e){e.stopPropagation()})</script><script src="https://cdn1.lncld.net/static/js/av-core-mini-0.6.1.js"></script><script>AV.initialize("Cc9hxvKgB63w6aMIIBCV2Bfz-gzGzoHsz","mBmolCuukl1GN11A7m8VQj9f")</script><script>function showTime(e){var t=new AV.Query(e),n=[],o=$(".leancloud_visitors");o.each(function(){n.push($(this).attr("id").trim())}),t.containedIn("url",n),t.find().done(function(e){if(0!==e.length){for(c=0;c<e.length;c++){var t=e[c],i=t.get("url"),s=t.get("time"),l=document.getElementById(i);$(l).find(".leancloud-visitors-count").text(s)}for(var c=0;c<n.length;c++){var i=n[c],l=document.getElementById(i),r=$(l).find(".leancloud-visitors-count");""==r.text()&&r.text(0)}}else o.find(".leancloud-visitors-count").text(0)}).fail(function(e,t){console.log("Error: "+t.code+" "+t.message)})}function addCount(e){var t=$(".leancloud_visitors"),n=t.attr("id").trim(),o=t.attr("data-flag-title").trim(),i=new AV.Query(e);i.equalTo("url",n),i.find({success:function(t){if(t.length>0){var i=t[0];i.fetchWhenSave(!0),i.increment("time"),i.save(null,{success:function(e){$(document.getElementById(n)).find(".leancloud-visitors-count").text(e.get("time"))},error:function(e,t){console.log("Failed to save Visitor num, with error message: "+t.message)}})}else{var s=new e,l=new AV.ACL;l.setPublicReadAccess(!0),l.setPublicWriteAccess(!0),s.setACL(l),s.set("title",o),s.set("url",n),s.set("time",1),s.save(null,{success:function(e){$(document.getElementById(n)).find(".leancloud-visitors-count").text(e.get("time"))},error:function(e,t){console.log("Failed to create")}})}},error:function(e){console.log("Error:"+e.code+" "+e.message)}})}$(function(){var e=AV.Object.extend("Counter");1==$(".leancloud_visitors").length?addCount(e):$(".post-title-link").length>1&&showTime(e)})</script><script>!function(){var t=document.createElement("script"),e=window.location.protocol.split(":")[0];t.src="https"===e?"https://zz.bdstatic.com/linksubmit/push.js":"http://push.zhanzhang.baidu.com/push.js";var s=document.getElementsByTagName("script")[0];s.parentNode.insertBefore(t,s)}()</script></body></html>