<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>博闻</title>
  
  
  <link href="/atom.xml" rel="self"/>
  
  <link href="http://yoursite.com/"/>
  <updated>2019-01-14T03:08:44.215Z</updated>
  <id>http://yoursite.com/</id>
  
  <author>
    <name>songtao</name>
    
  </author>
  
  <generator uri="http://hexo.io/">Hexo</generator>
  
  <entry>
    <title>CSS学习笔记-滚动视差</title>
    <link href="http://yoursite.com/2019/01/14/CSS%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-%E6%BB%9A%E5%8A%A8%E8%A7%86%E5%B7%AE/"/>
    <id>http://yoursite.com/2019/01/14/CSS学习笔记-滚动视差/</id>
    <published>2019-01-14T02:37:18.000Z</published>
    <updated>2019-01-14T03:08:44.215Z</updated>
    
    <content type="html"><![CDATA[<p><img src="https://user-gold-cdn.xitu.io/2018/8/10/16521e61a172b7d3?imageslim" alt="转载"></p><p>如图，在页面滚动时，要实现这样的效果应该怎么做？</p><h3 id="准备"><a href="#准备" class="headerlink" title="准备"></a>准备</h3><p><code>background-attachment</code></p><blockquote><p>它主要是解决如何设置固定的背景图像</p><p>可以点击<a href="http://www.w3school.com.cn/cssref/pr_background-attachment.asp" target="_blank" rel="noopener"><strong>w3c</strong></a>，查看详细说明</p></blockquote><p><code>background-attachment: scroll</code></p><p><strong>scroll</strong> 此关键字表示背景相对于元素本身固定， 而不是随着它的内容滚动。</p><p><code>background-attachment: local</code></p><p><strong>local</strong> 此关键字表示背景相对于元素的内容固定。如果一个元素拥有滚动机制，背景将会随着元素的内容滚动， 并且背景的绘制区域和定位区域是相对于可滚动的区域而不是包含他们的边框。</p><p><code>background-attachment: fixed</code></p><p><strong>fixed</strong> 此关键字表示背景相对于视口固定。即使一个元素拥有滚动机制，背景也不会随着元素的内容滚动。</p><blockquote><p>注意一下 scroll 与 fixed，一个是相对元素本身固定，一个是相对视口固定，有点类似 <code>position</code> 定位的 <code>absolute</code> 和 <code>fixed</code>。</p></blockquote><h2 id="使用-background-attachment-fixed-实现滚动视差"><a href="#使用-background-attachment-fixed-实现滚动视差" class="headerlink" title="使用 background-attachment: fixed 实现滚动视差"></a>使用 <code>background-attachment: fixed</code> 实现滚动视差</h2><p>首先，我们使用 <code>background-attachment: fixed</code> 来实现滚动视差。<strong>fixed</strong> 此关键字表示背景相对于视口固定。即使一个元素拥有滚动机制，背景也不会随着元素的内容滚动。</p><p>这里的关键在于，即使一个元素拥有滚动机制，背景也不会随着元素的内容滚动。也就是说，背景图从一开始就已经被固定死在初始所在的位置。</p><p>我们使用，图文混合排布的方式，实现滚动视差，HTML 结构如下，<code>.g-word</code> 表示内容结构，<code>.g-img</code> 表示背景图片结构：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">&lt;section class=&quot;g-word&quot;&gt;Header&lt;/section&gt;</span><br><span class="line">&lt;section class=&quot;g-img&quot;&gt;IMG1&lt;/section&gt;</span><br><span class="line">&lt;section class=&quot;g-word&quot;&gt;Content1&lt;/section&gt;</span><br><span class="line">&lt;section class=&quot;g-img&quot;&gt;IMG2&lt;/section&gt;</span><br><span class="line">&lt;section class=&quot;g-word&quot;&gt;Content2&lt;/section&gt;</span><br><span class="line">&lt;section class=&quot;g-img&quot;&gt;IMG3&lt;/section&gt;</span><br><span class="line">&lt;section class=&quot;g-word&quot;&gt;Footer&lt;/section&gt;</span><br><span class="line">复制代码</span><br></pre></td></tr></table></figure><p>关键 CSS：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">section &#123;</span><br><span class="line">    height: 100vh;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">.g-img &#123;</span><br><span class="line">    background-image: url(...);</span><br><span class="line">    background-attachment: fixed;</span><br><span class="line">    background-size: cover;</span><br><span class="line">    background-position: center center;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>效果如下：</p><p><img src="https://user-gold-cdn.xitu.io/2018/8/10/16521e893d1a43ee?imageslim" alt="转载"></p><h3 id="background-attachment-fixed-实现图片点击水纹效果"><a href="#background-attachment-fixed-实现图片点击水纹效果" class="headerlink" title="background-attachment: fixed 实现图片点击水纹效果"></a><code>background-attachment: fixed</code> 实现图片点击水纹效果</h3><p>利用图片相对视口固定，可以有很多有趣的效果，譬如下面这个，来源于这篇文章<a href="https://www.oxxostudio.tw/articles/201407/css-water-wave.html" target="_blank" rel="noopener">CSS Water Wave (水波效果)</a>：</p><p><img src="http://bwblog.oss-cn-hangzhou.aliyuncs.com/blogimg/20140729_1_03.gif" alt="转载"></p><p>HTML:</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"wave wave5"</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"wave wave4"</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"wave wave3"</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"wave wave2"</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"wave wave1"</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"wave wave0"</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure><p>CSS:</p><figure class="highlight scss"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.wave</span>&#123;</span><br><span class="line">  <span class="attribute">position</span>:absolute;</span><br><span class="line">  <span class="attribute">top</span>:calc((<span class="number">100%</span> - <span class="number">30px</span>)/<span class="number">2</span>);</span><br><span class="line">  <span class="attribute">left</span>:calc((<span class="number">100%</span> - <span class="number">30px</span>)/<span class="number">2</span>);</span><br><span class="line">  <span class="attribute">width</span>:<span class="number">30px</span>;</span><br><span class="line">  <span class="attribute">height</span>:<span class="number">30px</span>;</span><br><span class="line">  <span class="attribute">border-radius</span>:<span class="number">300px</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-class">.wave0</span>&#123;</span><br><span class="line">  <span class="attribute">background</span>:<span class="number">#f00</span>;</span><br><span class="line">  <span class="attribute">z-index</span>:<span class="number">2</span>;</span><br><span class="line">  <span class="attribute">background-size</span>:auto <span class="number">106%</span>;</span><br><span class="line">  -webkit-<span class="attribute">animation</span>:w <span class="number">1s</span> forwards;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-class">.wave1</span>&#123;</span><br><span class="line">  <span class="attribute">background</span>:<span class="number">#d00</span>;</span><br><span class="line">  <span class="attribute">z-index</span>:<span class="number">3</span>;</span><br><span class="line">  -webkit-<span class="attribute">animation</span>:w <span class="number">1s</span> .<span class="number">2s</span> forwards;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-class">.wave2</span>&#123;</span><br><span class="line">  <span class="attribute">background</span>:<span class="number">#b00</span>;</span><br><span class="line">  <span class="attribute">z-index</span>:<span class="number">4</span>;</span><br><span class="line">  -webkit-<span class="attribute">animation</span>:w <span class="number">1s</span> .<span class="number">4s</span> forwards;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-class">.wave3</span>&#123;</span><br><span class="line">  <span class="attribute">background</span>:<span class="number">#900</span>;</span><br><span class="line">  <span class="attribute">z-index</span>:<span class="number">5</span>;</span><br><span class="line">  -webkit-<span class="attribute">animation</span>:w <span class="number">1s</span> .<span class="number">5s</span> forwards;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-class">.wave4</span>&#123;</span><br><span class="line">  <span class="attribute">background</span>:<span class="number">#700</span>;</span><br><span class="line">  <span class="attribute">z-index</span>:<span class="number">6</span>;</span><br><span class="line">  -webkit-<span class="attribute">animation</span>:w <span class="number">1s</span> .<span class="number">8s</span> forwards;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-class">.wave5</span>&#123;</span><br><span class="line">  <span class="attribute">background</span>:<span class="number">#500</span>;</span><br><span class="line">  <span class="attribute">z-index</span>:<span class="number">7</span>;</span><br><span class="line">  -webkit-<span class="attribute">animation</span>:w <span class="number">1s</span> <span class="number">1s</span> forwards;</span><br><span class="line">&#125;</span><br><span class="line">@-webkit-keyframes w&#123;</span><br><span class="line">  0%&#123;</span><br><span class="line">    <span class="attribute">top</span>:calc((<span class="number">100%</span> - <span class="number">30px</span>)/<span class="number">2</span>);</span><br><span class="line">    <span class="attribute">left</span>:calc((<span class="number">100%</span> - <span class="number">30px</span>)/<span class="number">2</span>);</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">30px</span>;</span><br><span class="line">    <span class="attribute">height</span>:<span class="number">30px</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  100%&#123;</span><br><span class="line">    <span class="attribute">top</span>:calc((<span class="number">100%</span> - <span class="number">300px</span>)/<span class="number">2</span>);</span><br><span class="line">    <span class="attribute">left</span>:calc((<span class="number">100%</span> - <span class="number">300px</span>)/<span class="number">2</span>);</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">300px</span>;</span><br><span class="line">    <span class="attribute">height</span>:<span class="number">300px</span>;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>效果：</p><p><img src="http://bwblog.oss-cn-hangzhou.aliyuncs.com/blogimg/20140729_1_02.gif" alt="转载"></p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;p&gt;&lt;img src=&quot;https://user-gold-cdn.xitu.io/2018/8/10/16521e61a172b7d3?imageslim&quot; alt=&quot;转载&quot;&gt;&lt;/p&gt;
&lt;p&gt;如图，在页面滚动时，要实现这样的效果应该怎么做？&lt;/p&gt;
&lt;h3 id=&quot;准备&quot;&gt;&lt;
      
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>CSS学习笔记-实现滚动进度条效果</title>
    <link href="http://yoursite.com/2019/01/11/CSS%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-%E5%AE%9E%E7%8E%B0%E6%BB%9A%E5%8A%A8%E8%BF%9B%E5%BA%A6%E6%9D%A1%E6%95%88%E6%9E%9C/"/>
    <id>http://yoursite.com/2019/01/11/CSS学习笔记-实现滚动进度条效果/</id>
    <published>2019-01-11T07:03:45.000Z</published>
    <updated>2019-01-14T03:12:43.754Z</updated>
    
    <content type="html"><![CDATA[<h3 id="准备"><a href="#准备" class="headerlink" title="准备"></a>准备</h3><p>在切入正题之前，先看两个与之相关的知识点：</p><p><strong>calc()</strong></p><blockquote><p>用于动态计算长度值</p><p>支持的版本：css3</p></blockquote><p>需要注意的是：</p><ul><li><p>运算符前后都要保留一个空格，例如：</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-tag">width</span>: <span class="selector-tag">calc</span>(100% <span class="selector-tag">-</span> 10<span class="selector-tag">px</span>);</span><br></pre></td></tr></table></figure></li><li><p>任何长度都可以使用calc()函数进行计算</p></li><li><p>calc()支持“+”，“-”，“*”，“/”运算</p></li><li><p>calc()函数遵循数学运算优先级规则</p></li></ul><p><strong>vh</strong></p><blockquote><p>相对于视口的高度</p><p>视口被均分为100个单位的vh</p></blockquote><p>例如：</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.bw</span> &#123;</span><br><span class="line">    <span class="attribute">font-size</span>: <span class="number">16vh</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>如果此时的视口高度为100px，那么上述的示例中的字体大小为(16/100) * 100,既为16px</p><h3 id="JS实现形式"><a href="#JS实现形式" class="headerlink" title="JS实现形式"></a>JS实现形式</h3><p><img src="http://bwblog.oss-cn-hangzhou.aliyuncs.com/blogimg/scroll-indicator-2.gif" alt="转载"></p><p>如图，可以看到滚动提示条的实现是通过控制<code>scroll-line</code>的宽度。也就是在滚动内容的时候，width的值从0%变化到100%，而要实现这一点，就得知道两个参数：</p><ul><li>文档的高度 <code>document.body.scrollHeight || $(document).height()</code></li><li>可视区域的高度 <code>document.body.clientHeight || $(window).height()</code></li></ul><p>如下图所示：</p><p><img src="http://bwblog.oss-cn-hangzhou.aliyuncs.com/blogimg/scroll-indicator-3.png" alt="转载"></p><p>文档高度和视口高度有一个差值max，而这个值是需要滚动的值，简单理解就是<code>scroll-line</code>宽度为100%时的值。这样我们就知道了，整个文档滚动的最大值。另外，我们还需要知道滚动条滚动的距离$(window).scrollTop(),有了这两个值，我们就可以算出进度条当前的宽度<code>($(window).scrollTop() / ($(document).height() - $(window).height())) * 100%</code></p><p><img src="http://bwblog.oss-cn-hangzhou.aliyuncs.com/blogimg/scroll-indicator-4.gif" alt="转载"></p><h3 id="CSS实现形式"><a href="#CSS实现形式" class="headerlink" title="CSS实现形式"></a>CSS实现形式</h3><p>首先，为了实现进度提示条的功能得用到<code>线性渐变</code></p><p><a href="https://juejin.im/post/5c35953ce51d45523f04b6d2?utm_source=gold_browser_extension" target="_blank" rel="noopener">原文地址</a></p><p><a href="https://codepen.io/youstde/pen/PXyaYQ" target="_blank" rel="noopener">demo</a></p><h3 id="拓展"><a href="#拓展" class="headerlink" title="拓展"></a>拓展</h3><p><strong>1、要获取当前页面的滚动条的纵坐标的位置，应该用：</strong>​      </p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">document.documentElement.scrollTop</span><br></pre></td></tr></table></figure><p>之所以不用document.body.scrollTop的原因是documentElement对应的是html标签,而body对应的是body标签</p><p><strong>2、关于document.body和document.documentElement的区别</strong></p><p>body是DOM对象中body的子节点,即<body>标签，而documentElement是整个节点树的根结点，即<html>标签。<br>即document.body.clientHeight获取到的是body的高度，而document.documentElement.clientHeight获取到的是   整个html的高度，然而当文档处于怪癖模式下时，我们使用document.documentElement.scrollTop获取到属性的值是为0的，而在w3c标准文档模式下，document.body.scrollTop的值是为0的，因此为了好的兼容性，我们可以这样写：</html></body></p><p><strong>var top = document.documentElement.scrollHeight || document.body.scrollHeight</strong></p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h3 id=&quot;准备&quot;&gt;&lt;a href=&quot;#准备&quot; class=&quot;headerlink&quot; title=&quot;准备&quot;&gt;&lt;/a&gt;准备&lt;/h3&gt;&lt;p&gt;在切入正题之前，先看两个与之相关的知识点：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;calc()&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;

      
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>JS学习笔记-Promise链式调用解析</title>
    <link href="http://yoursite.com/2018/11/13/JS%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-Promise%E9%93%BE%E5%BC%8F%E8%B0%83%E7%94%A8%E8%A7%A3%E6%9E%90/"/>
    <id>http://yoursite.com/2018/11/13/JS学习笔记-Promise链式调用解析/</id>
    <published>2018-11-13T06:24:08.000Z</published>
    <updated>2018-11-13T06:25:04.736Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Promise链式调用解析"><a href="#Promise链式调用解析" class="headerlink" title="Promise链式调用解析"></a>Promise链式调用解析</h2><p>关于Promise是做什么的我就不赘述了，当你看到这个文章的时候，我也就默认你是用过Promise的</p><p>首先，举个🌰：</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 获取用户id</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">getUserId</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span>(<span class="params">resolve, reject</span>) </span>&#123;</span><br><span class="line">      setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">        resolve(<span class="number">186</span>)</span><br><span class="line">      &#125;, <span class="number">1e3</span>)</span><br><span class="line">    &#125;)</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 通过用户id获取该用户的手机号</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">getMobileByUserId</span>(<span class="params">userId</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span>(<span class="params">resolve, reject</span>) </span>&#123;</span><br><span class="line">        setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">            resolve(userId + <span class="string">'****5836'</span>)</span><br><span class="line">        &#125;, <span class="number">1e3</span>)</span><br><span class="line">    &#125;)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>两个方法，getUserId(简称<strong>IDfun</strong>)和getMobileByUserId(简称<strong>MOfun</strong>),两者都是return了一个Promise实例，前者是获取用户id，后者是拿着用户id去换取手机号，MOfun的输出是依赖于IDfun的输出，这样两个异步的操作又得保证其是有序的执行</p><p>到这，应该都有一个对应的解决办法，我这里列举了一个示例：</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">IDfun()</span><br><span class="line">    .then(MOfun)</span><br><span class="line">    .then(<span class="function"><span class="keyword">function</span>(<span class="params">res</span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(res)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure><p>首先，调用了IDfun，在其Promise实例的then方法中传入MOfun，紧随其后又是一个then方法，里面传入了一个callback函数，此时，callback函数中打印的值是什么，又是为什么呢，一般情况下then方法里传的都是一个callback，而这个例子里传的却是一个包含Promise的函数，它内部是怎么做到将用户的id传递给MOfun中并打印出来</p><p>当然也可以有另外的写法</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//例2</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">getUserId</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span> (<span class="params">resolve</span>) </span>&#123;</span><br><span class="line">        resolve(getUserMobileById(<span class="number">9876</span>));</span><br><span class="line">    &#125;);</span><br><span class="line">&#125;</span><br><span class="line">getUserId().then(<span class="function"><span class="keyword">function</span>(<span class="params">res</span>)</span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(res);</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure><p>其实两种写法原理都是一样的，只是写的位置不同而已，今天要说的是第一种写法。</p><p>说到这，我先列举几个Promise中几个比较核心的方法：</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// this指向是Promise实例</span></span><br><span class="line"><span class="comment">// 只列举了几个关键的代码</span></span><br><span class="line"><span class="keyword">this</span>.then = <span class="function"><span class="keyword">function</span> (<span class="params">onFulfilled</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span> (<span class="params">resolve</span>) </span>&#123;</span><br><span class="line">        handle(&#123;</span><br><span class="line">            onFulfilled: onFulfilled || <span class="literal">null</span>,</span><br><span class="line">            resolve: resolve</span><br><span class="line">        &#125;);</span><br><span class="line">    &#125;);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">handle</span>(<span class="params">deferred</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (state === <span class="string">'pending'</span>) &#123;</span><br><span class="line">        deferreds.push(deferred);</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">var</span> ret = deferred.onFulfilled(value);</span><br><span class="line">    deferred.resolve(ret);</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 其中的state和value可以理解为全局定义的，只是放了一些代码段出来</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">resolve</span>(<span class="params">newValue</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (newValue &amp;&amp; (<span class="keyword">typeof</span> newValue === <span class="string">'object'</span> || <span class="keyword">typeof</span> newValue === <span class="string">'function'</span>)) &#123;</span><br><span class="line">        <span class="keyword">var</span> then = newValue.then;</span><br><span class="line">        <span class="keyword">if</span> (<span class="keyword">typeof</span> then === <span class="string">'function'</span>) &#123;</span><br><span class="line">            then.call(newValue, resolve);</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    state = <span class="string">'fulfilled'</span>;</span><br><span class="line">    value = newValue;     <span class="comment">// value这里可以理解为它是在全局定义的</span></span><br><span class="line">    setTimeout(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">        deferreds.forEach(<span class="function"><span class="keyword">function</span> (<span class="params">deferred</span>) </span>&#123;</span><br><span class="line">            handle(deferred);</span><br><span class="line">        &#125;);</span><br><span class="line">    &#125;, <span class="number">0</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>参照这几个方法，我们再回到刚才那个例子：</p><ul><li>1.执行IDfun返回一个Promise实例（<strong>IDPro</strong> ），执行IDPro中的代码，假设此时在异步发送请求，继续执行then方法，then方法中传入了MOfun</li><li>2.进入到then方法中，也是返回一个Promise实例（<strong>BridgePro1</strong>）,调用handle方法</li></ul><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">handle(&#123;</span><br><span class="line">    onFulfilled: onFulfilled || <span class="literal">null</span>,  <span class="comment">// 此时的onFulfilled === MOfun</span></span><br><span class="line">    resolve: resolve  <span class="comment">// resolve是BridgePro1的resolve</span></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><ul><li>3.进入handle中，如果是IDPro的then方法先执行，其resolve后执行，这个时候 <code>state</code> === <code>pending</code>,此时它会将传入的对象push到IDPro的deferreds数组中，然后返回</li><li>4.IDPro中异步操作完成，执行其resolve，并传入id为186</li><li>5.进入resolve方法中，此时newValue不满足if条件，跳过，继续向下执行，改变<code>state</code>===&gt; <code>fulfilled</code>,<code>value</code> ===&gt; <code>186</code>,setTimeout为0是为了把其内部的这段代码放到队列的最后，保证执行这段代码的时候then方法已经执行了,循环遍历IDPro的deferreds数组，将数组中的每一项传入handle中并执行</li></ul><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">resolve</span>(<span class="params">newValue</span>) </span>&#123;   <span class="comment">// newValue === 186</span></span><br><span class="line">    <span class="keyword">if</span> (newValue &amp;&amp; (<span class="keyword">typeof</span> newValue === <span class="string">'object'</span> || <span class="keyword">typeof</span> newValue === <span class="string">'function'</span>)) &#123;</span><br><span class="line">        <span class="keyword">var</span> then = newValue.then;</span><br><span class="line">        <span class="keyword">if</span> (<span class="keyword">typeof</span> then === <span class="string">'function'</span>) &#123;</span><br><span class="line">            then.call(newValue, resolve);</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    state = <span class="string">'fulfilled'</span>;</span><br><span class="line">    value = newValue;     <span class="comment">// value这里可以理解为它是在全局定义的</span></span><br><span class="line">    setTimeout(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">        <span class="comment">// deferreds里存放的是通过then传入的</span></span><br><span class="line">        <span class="comment">// [&#123;</span></span><br><span class="line">        <span class="comment">//    onFulfilled: MOfun,</span></span><br><span class="line">        <span class="comment">//    resolve: resolve</span></span><br><span class="line">        <span class="comment">// &#125;]</span></span><br><span class="line">        deferreds.forEach(<span class="function"><span class="keyword">function</span> (<span class="params">deferred</span>) </span>&#123;  </span><br><span class="line">            handle(deferred);</span><br><span class="line">        &#125;);</span><br><span class="line">    &#125;, <span class="number">0</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ul><li>6.进入handle中，此时state === fulfilled，执行deferred中的onFulfilled（MOfun）,传入value,返回一个Promise实例（<strong>MOPro</strong>）,此时的ret === MOPro，继续执行deferred中的resolve（BridgePro1的resolve），传入ret</li></ul><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// state === fulfilled</span></span><br><span class="line"><span class="comment">// deferred ===&gt; </span></span><br><span class="line"><span class="comment">//  &#123;</span></span><br><span class="line"><span class="comment">//    onFulfilled: MOfun,</span></span><br><span class="line"><span class="comment">//    resolve: resolve</span></span><br><span class="line"><span class="comment">//  &#125;</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">handle</span>(<span class="params">deferred</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (state === <span class="string">'pending'</span>) &#123;</span><br><span class="line">        deferreds.push(deferred);</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">var</span> ret = deferred.onFulfilled(value);  <span class="comment">// value === 186</span></span><br><span class="line">    deferred.resolve(ret);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ul><li>7.进入resolve中,此时newValue满足判断条件</li></ul><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">resolve</span>(<span class="params">newValue</span>) </span>&#123;   <span class="comment">// newValue === MOPro</span></span><br><span class="line">    <span class="keyword">if</span> (newValue &amp;&amp; (<span class="keyword">typeof</span> newValue === <span class="string">'object'</span> || <span class="keyword">typeof</span> newValue === <span class="string">'function'</span>)) &#123;</span><br><span class="line">        <span class="comment">// then 是MOPro的then</span></span><br><span class="line">        <span class="keyword">var</span> then = newValue.then;</span><br><span class="line">        <span class="keyword">if</span> (<span class="keyword">typeof</span> then === <span class="string">'function'</span>) &#123;</span><br><span class="line">            <span class="comment">// 调用then方法，设置其内部this指向为MOPro，并传入resolve，这个resolve为BridgePro1的resolve，然后返回</span></span><br><span class="line">            then.call(newValue, resolve);</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    state = <span class="string">'fulfilled'</span>;</span><br><span class="line">    value = newValue;     </span><br><span class="line">    setTimeout(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">        deferreds.forEach(<span class="function"><span class="keyword">function</span> (<span class="params">deferred</span>) </span>&#123;  </span><br><span class="line">            handle(deferred);</span><br><span class="line">        &#125;);</span><br><span class="line">    &#125;, <span class="number">0</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ul><li>8.进入到MOPro的then方法中，调用handle将对象传入，此时MOPro的deferreds数组中有两项，一项是上面通过resolve传入的，另一项是传入的callback函数</li></ul><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// ===&gt; callback</span></span><br><span class="line"><span class="function"><span class="keyword">function</span>(<span class="params">res</span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(res)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">this</span>.then = <span class="function"><span class="keyword">function</span> (<span class="params">onFulfilled</span>) </span>&#123;</span><br><span class="line">    <span class="comment">// onFulfilled为BridgePro1的resolve </span></span><br><span class="line">    <span class="comment">// 此时返回的Promise实例为BridgePro2</span></span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span> (<span class="params">resolve</span>) </span>&#123;</span><br><span class="line">        handle(&#123;</span><br><span class="line">            onFulfilled: onFulfilled || <span class="literal">null</span>,</span><br><span class="line">            resolve: resolve  <span class="comment">// BridgePro2</span></span><br><span class="line">        &#125;);</span><br><span class="line">    &#125;);</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><ul><li>9.当MOPro中异步操作执行完成，执行resolve并传入手机号<code>1865836</code>，进入resolve,将state设置为fulfilled，value设置成<code>1865836</code>，延迟循环MOPro的deferreds数组，此时数组为：</li></ul><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">[</span><br><span class="line">    &#123;</span><br><span class="line">        onFulfilled: resolve,   <span class="comment">// BridgePro1的resolve</span></span><br><span class="line">        resolve: resolve  <span class="comment">// BridgePro2的resolve</span></span><br><span class="line">    &#125;，</span><br><span class="line">    &#123;</span><br><span class="line">     onFulfilled: callback,</span><br><span class="line">        resolve: resolve  <span class="comment">// BridgePro3的resolve</span></span><br><span class="line">    &#125;</span><br><span class="line">]</span><br></pre></td></tr></table></figure><ul><li>10.进入handle方法中,循环第一个值时，此时deferred的onFulfilled为BridgePro1的resolve，调用该resolve，并传入value（<code>1865836</code>）,因为BridgePro1的deferreds为空，所以直接resolve掉BridgePro1，此时ret为undefined，再执行deferred的resolve（BridgePro2的resolve），同样，resolve掉BridgePro2，继续循环，传入第二个值，deferred的onFulfilled为callback，执行callback传入value，打印出手机号<code>1865836</code>,返回值为undefined ,因此ret为undefined，再执行deferred的resolve（BridgePro3的resolve），直接resolve掉BridgePro3</li></ul><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">handle</span>(<span class="params">deferred</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (state === <span class="string">'pending'</span>) &#123;</span><br><span class="line">        deferreds.push(deferred);</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">var</span> ret = deferred.onFulfilled(value);</span><br><span class="line">    deferred.resolve(ret);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ul><li>11.至此，执行完成，通过user的id换取了user的mobile number</li></ul><h4 id="后记："><a href="#后记：" class="headerlink" title="后记："></a>后记：</h4><p>如果我想按照下面的写法一直then下去：</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">IDfun()</span><br><span class="line">    .then(MOfun)</span><br><span class="line">    .then(callback)</span><br><span class="line">.then(callback)</span><br><span class="line">.then(callback)</span><br></pre></td></tr></table></figure><p>每个callback里都可以打印到手机号，应该怎么写</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// callback</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">callback</span>(<span class="params">res</span>) </span>&#123;</span><br><span class="line">    <span class="comment">// doing something</span></span><br><span class="line">    <span class="built_in">console</span>.log(res)</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h4 id="总结："><a href="#总结：" class="headerlink" title="总结："></a>总结：</h4><p>Promise是什么，从字面意思就是一个承诺，我给你了一个承诺，你记着呢，不知道什么时候兑现，但肯定会给你一个答复，打一个不太形象的比喻，我去银行办事，肯定是先取一个号，这个号就像一个承诺，什么时候叫到你，不确定，但肯定会叫你，然后这个时候你就会去办理你的事情</p><p>最后附上一个流程图（图片来源于美团）：</p><p><img src="http://ww1.sinaimg.cn/large/005QDhBjly1fx6ewjrnfhj30j90cdwfk.jpg" alt=""></p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h2 id=&quot;Promise链式调用解析&quot;&gt;&lt;a href=&quot;#Promise链式调用解析&quot; class=&quot;headerlink&quot; title=&quot;Promise链式调用解析&quot;&gt;&lt;/a&gt;Promise链式调用解析&lt;/h2&gt;&lt;p&gt;关于Promise是做什么的我就不赘述了，当你看到这
      
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>JS学习笔记-连等赋值</title>
    <link href="http://yoursite.com/2018/10/24/JS%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-%E8%BF%9E%E7%AD%89%E8%B5%8B%E5%80%BC/"/>
    <id>http://yoursite.com/2018/10/24/JS学习笔记-连等赋值/</id>
    <published>2018-10-24T07:20:33.000Z</published>
    <updated>2018-10-24T11:51:36.140Z</updated>
    
    <content type="html"><![CDATA[<p> <strong>今</strong>天看了前端网上关于JS的题目，其中有一道题目挺有意思的。如下</p><p><a href="javascript:void(0" target="_blank" rel="noopener"><img src="https://common.cnblogs.com/images/copycode.gif" alt="复制代码"></a>;)</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">1 var a = b =10;</span><br><span class="line">2      (function()&#123;</span><br><span class="line">3          var a = b = 20;</span><br><span class="line">4       &#125;)();</span><br><span class="line">5 console.log(a);</span><br><span class="line">6 console.log(b);</span><br><span class="line">7 问：输出的 a = ?    b = ?</span><br></pre></td></tr></table></figure><p><a href="javascript:void(0" target="_blank" rel="noopener"><img src="https://common.cnblogs.com/images/copycode.gif" alt="复制代码"></a>;)</p><p>你们想到的结果是什么？</p><p>也许绝大多数人和我一样认为是20、20 。然而答案是10、20，别急我们先来慢慢分析(<em>^__^</em>) 嘻嘻……，</p><p><strong>1</strong>.首先第一行的 var a = b = 10; 就是用了连等操作符，连等操作符是<strong>从右向左的</strong> 所以类似于b = 10; a = b;或者是 a = (b = 10);这样的顺序进行从右向左的赋值的。</p><p>变量<strong>a</strong>是用<strong>var</strong>进行声明并赋值的所以是<strong>局部变量</strong>，但是b是未声明而直接进行赋值的所以是<strong>全局变量</strong>。所以使用连等操作符的时候要不会出现全局变量要不就是使用作用域链后端的变量。</p><p><strong>2</strong>.从第二行开始使用匿名函数实现模仿块级作用于（私有作用域）:在里面声明的变量会在函数结束后被销毁除非被外部所使用。第三行进行连等操作，先使用外部局部变量b，b =20; 然后又重新声明了一个变量a</p><p>这是一个跨级作用域重新声明的a和外部没有任何一点关系，你可以把它看成任何其它变量不如说var x；</p><p><img src="https://images2015.cnblogs.com/blog/1026317/201703/1026317-20170330215946180-2013064846.png" alt="img">  <strong>|</strong><img src="https://images2015.cnblogs.com/blog/1026317/201703/1026317-20170330220055102-323581984.png" alt="img"></p><p>然后 var a = b;初始化后的 a为20.</p><p><strong>3</strong>.第四行声明定义一个匿名函数后随即执行，私有作用域中创建的变量a在结束后随即被销毁.所以最后改变的只有外部的变量b的值.</p><p><strong>趁热打铁</strong>，我们再来看一道类似的连等操作赋值问题. 如下</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">1 想想结果是多少吧？</span><br><span class="line">2 var a = &#123;n:1&#125;; </span><br><span class="line">3 var b = a;</span><br><span class="line">4 a.x = a = &#123;n:2&#125;;</span><br><span class="line">5 问：console.log(a.x);</span><br><span class="line">6    console.log(b.x);</span><br></pre></td></tr></table></figure><p> 也许有的人看到答案又疑惑的，看了上面的感觉自己掌握了，然后这道题却有出乎意料之外(⊙﹏⊙)b;</p><p>结果是<img src="https://images2015.cnblogs.com/blog/1026317/201703/1026317-20170330221145992-222405970.png" alt="img">,不知道有没有小伙伴答对呢…….</p><p>让我们再来分析一下</p><p><strong>1</strong>.首先第二行声明并且使用对象字面量语法创建了一个对象，有属性n = 1;第三行声明变量b，并且把a的对象引用赋值给b。所以现在变量b和a指向的是同一个对象，即他们现在共享。</p><p><strong>2</strong>.第四行问题来了，a.x = a = {n:2}; 先创建一个对象{n:2}并把他的引用送给变量a。因为a.x在执行前保留了对{n:1}的引用，所以给原对象增加一个属性a即对{n:2}的引用</p><p>而a现在为{n:2}并没有x的属性所以为undefined，而仍然指向原来的引用所以b.x = a;</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">b.x == a //true</span><br></pre></td></tr></table></figure><p>也许讲的有点不太清楚，希望你们能说出你们的观点，也希望自己能对JS理解更深刻</p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;p&gt; &lt;strong&gt;今&lt;/strong&gt;天看了前端网上关于JS的题目，其中有一道题目挺有意思的。如下&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;javascript:void(0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;img src=&quot;https://com
      
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title></title>
    <link href="http://yoursite.com/2018/10/24/%E5%B9%BF%E5%91%8AJSSDK%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3/"/>
    <id>http://yoursite.com/2018/10/24/广告JSSDK使用文档/</id>
    <published>2018-10-24T03:26:04.185Z</published>
    <updated>2018-10-24T03:26:04.185Z</updated>
    
    <content type="html"><![CDATA[<h2 id="广告JSSDK使用文档"><a href="#广告JSSDK使用文档" class="headerlink" title="广告JSSDK使用文档"></a>广告JSSDK使用文档</h2><h3 id="基本介绍"><a href="#基本介绍" class="headerlink" title="基本介绍"></a>基本介绍</h3><p>JSSDK适用于移动端H5页面</p><h3 id="使用方法"><a href="#使用方法" class="headerlink" title="使用方法"></a>使用方法</h3><h4 id="第一步：引入相关资源"><a href="#第一步：引入相关资源" class="headerlink" title="第一步：引入相关资源"></a>第一步：引入相关资源</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;script src=<span class="string">"http://pre.adbaitai.com/download/jssdk/btmjssdk.min.js"</span>&gt;<span class="xml"><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span></span><br><span class="line">    <span class="comment">//支持https,路径和http一样</span></span><br><span class="line">    <span class="comment">//尽量不要动态加载JS资源文件，容易被浏览器广告屏蔽插件过滤</span></span><br></pre></td></tr></table></figure><h4 id="第二步-调用请求广告的JS方法-需要放在页面底部或者放在onload中"><a href="#第二步-调用请求广告的JS方法-需要放在页面底部或者放在onload中" class="headerlink" title="第二步:调用请求广告的JS方法(需要放在页面底部或者放在onload中)"></a>第二步:调用请求广告的JS方法(需要放在页面底部或者放在onload中)</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">btmAd(&#123;</span><br><span class="line">    container: <span class="string">'.btm-media-container'</span>, <span class="comment">//需要将广告放入的位置</span></span><br><span class="line">    pid:<span class="string">'4_6_9'</span>,</span><br><span class="line">    app_key: <span class="string">'xinghun-ceshi-1'</span>, <span class="comment">//媒体app_key</span></span><br><span class="line">    app_secret:<span class="string">'1'</span>,</span><br><span class="line">    target: <span class="string">'_blank'</span>, <span class="comment">//广告的打开方式</span></span><br><span class="line">    success: <span class="function"><span class="keyword">function</span>(<span class="params">res</span>)</span>&#123;</span><br><span class="line">      <span class="comment">//广告成功加载后的回调方法</span></span><br><span class="line">        <span class="built_in">console</span>.log(res);</span><br><span class="line">    &#125;,</span><br><span class="line">    error: <span class="function"><span class="keyword">function</span>(<span class="params">data</span>) </span>&#123;</span><br><span class="line">      <span class="comment">//广告成功加载后的回调方法</span></span><br><span class="line">      <span class="built_in">console</span>.log(data);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure><h3 id="调用参数说明"><a href="#调用参数说明" class="headerlink" title="调用参数说明"></a>调用参数说明</h3><table><thead><tr><th>名称</th><th>必填</th><th>定义</th><th>类型</th><th>默认</th><th>说明</th></tr></thead><tbody><tr><td>container</td><td>否</td><td>广告位容器</td><td>String</td><td>body</td><td>需要将广告放入的位置                                            浮标广告为悬浮广告，填写则放入指定位置，不填写则放在默认位置                                                    插屏广告为悬浮广告，不需要填写，填写无效</td></tr><tr><td>app_key</td><td>是</td><td>应用Key</td><td>String</td><td>-</td><td>-</td></tr><tr><td>pid</td><td>是</td><td></td><td>String</td><td>-</td><td>-</td></tr><tr><td>app_secret</td><td>是</td><td></td><td>String</td><td>-</td><td>-</td></tr><tr><td>target</td><td>否</td><td>广告页面打开方式</td><td>String</td><td>_blank</td><td>_self:本页面打开_blank:新页面打开_top:顶级窗口打开</td></tr><tr><td>success</td><td>否</td><td>请求成功回调函数</td><td>Function</td><td>-</td><td>回调数据的所有参数可打印查看,如:success:function(res){                               console.log(res)                                                         }</td></tr><tr><td>error</td><td>否</td><td>请求失败回调函数</td><td>Function</td><td>-</td><td>-</td></tr></tbody></table><h3 id="回调参数说明-基础参数"><a href="#回调参数说明-基础参数" class="headerlink" title="回调参数说明[基础参数]"></a>回调参数说明[基础参数]</h3><table><thead><tr><th>名称</th><th>类型</th><th>定义</th></tr></thead><tbody><tr><td>picUrl</td><td>String</td><td>广告图片</td></tr><tr><td>pitType</td><td>String</td><td>广告类型</td></tr><tr><td>skipUrl</td><td>String</td><td>广告链接</td></tr><tr><td>pitWidth</td><td>Number</td><td>图片宽度</td></tr><tr><td>pitHeight</td><td>Number</td><td>图片高度</td></tr></tbody></table><h3 id="自定义广告高级用法说明"><a href="#自定义广告高级用法说明" class="headerlink" title="自定义广告高级用法说明"></a>自定义广告高级用法说明</h3><p>此方法只有非标准的多条素材的自定义广告需要使用，单条素材的自定义广告和标准广告一样支持渲染</p><p>多条素材的自定义广告与标准广告有所区别，多条素材的自定义广告只提供数据，并不做任何界面渲染，界面渲染部分由媒体方根据兑吧提供的数据自行定制</p><p>示例：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">"btm-media-container"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">img</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">TuiaMedia(&#123;</span><br><span class="line">  pid:<span class="string">'4_6_9'</span>,</span><br><span class="line">  app_key: <span class="string">'xinghun-ceshi-1'</span>, <span class="comment">//媒体app_key</span></span><br><span class="line">  app_secret:<span class="string">'1'</span>,</span><br><span class="line">  success:<span class="function"><span class="keyword">function</span>(<span class="params">res</span>)</span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(res)</span><br><span class="line">    <span class="comment">//将广告图片放入到网页中</span></span><br><span class="line">    <span class="built_in">document</span>.querySelector(<span class="string">'#tuia-media-container img'</span>)       .setAttribute(<span class="string">'src'</span>,res.material_list[<span class="number">0</span>].image_url); </span><br><span class="line">  &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure><h3 id="更新日志"><a href="#更新日志" class="headerlink" title="更新日志"></a>更新日志</h3><p>1.2.0</p><p>优化JS包体积大小</p><p>1.1.0</p><p>添加了开屏，banner和自定义的广告形式</p><p>1.0.0</p><p>JSSDK诞生</p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h2 id=&quot;广告JSSDK使用文档&quot;&gt;&lt;a href=&quot;#广告JSSDK使用文档&quot; class=&quot;headerlink&quot; title=&quot;广告JSSDK使用文档&quot;&gt;&lt;/a&gt;广告JSSDK使用文档&lt;/h2&gt;&lt;h3 id=&quot;基本介绍&quot;&gt;&lt;a href=&quot;#基本介绍&quot; class=&quot;
      
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>linux常用命令</title>
    <link href="http://yoursite.com/2018/05/25/linux%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4/"/>
    <id>http://yoursite.com/2018/05/25/linux常用命令/</id>
    <published>2018-05-25T08:01:43.000Z</published>
    <updated>2018-10-24T06:54:21.260Z</updated>
    
    <content type="html"><![CDATA[<h4 id="linux代码压缩上传"><a href="#linux代码压缩上传" class="headerlink" title="linux代码压缩上传"></a>linux代码压缩上传</h4><p>假如项目在Downloads文件夹下</p><p>项目目录为test</p><p>1.cd到项目文件夹的上层目录</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cd Downloads</span><br></pre></td></tr></table></figure><p>2.查看文件列表</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ls</span><br></pre></td></tr></table></figure><p>3.删除之前压缩过的文件（如果有的话）</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">rm test.tar</span><br></pre></td></tr></table></figure><p>4.同2</p><p>5.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">tar -cvf test.tar  test     (将项目打包)</span><br></pre></td></tr></table></figure><p>6.同2</p><p>7.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">scp test.tar root@adbaitai.com:/home/admin/lgweb/ssp</span><br></pre></td></tr></table></figure><p>8.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ssh root@adbaitai.com</span><br></pre></td></tr></table></figure><p>9.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">cd /home/admin/</span><br><span class="line">ls</span><br></pre></td></tr></table></figure><p>11.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">cd lgweb/ssp/</span><br><span class="line">ls</span><br></pre></td></tr></table></figure><p>12.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">cp test.tar ../    (复制文件到指定路径) 待定！</span><br><span class="line">cd ../</span><br><span class="line">ls</span><br><span class="line">cd ssp/</span><br><span class="line">ls</span><br><span class="line">rm -rf *(将线上项目目录下的所有文件都删除)</span><br><span class="line">cd ../</span><br><span class="line">ls</span><br><span class="line">tar -xvf test.tar  (解压项目压缩包)</span><br><span class="line">ls</span><br><span class="line">rm test.tar        (删除项目的压缩包)</span><br><span class="line">y</span><br><span class="line">ls</span><br><span class="line">cd ../</span><br><span class="line">ls</span><br><span class="line">cp -R test/* ssp   (将项目文件夹下的文件全部放到ssp文件夹下)</span><br><span class="line">ls</span><br><span class="line">cd ssp/</span><br><span class="line">ls</span><br><span class="line">cd ../</span><br><span class="line">ls</span><br><span class="line">rm -rf test/     (删除项目的解压包)</span><br></pre></td></tr></table></figure><p>先将项目打包，然后发到服务器上，然后解压到项目存放的上层目录中，将压缩包删除，把解压的文件附到项目目录中，最后删除项目解压的文件，完事</p><p>cd /etc/nginx/conf.d/</p><p> vim default.conf</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">scp -r * admin@robot.adbaitai.com:/home/admin/wx/</span><br></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h4 id=&quot;linux代码压缩上传&quot;&gt;&lt;a href=&quot;#linux代码压缩上传&quot; class=&quot;headerlink&quot; title=&quot;linux代码压缩上传&quot;&gt;&lt;/a&gt;linux代码压缩上传&lt;/h4&gt;&lt;p&gt;假如项目在Downloads文件夹下&lt;/p&gt;
&lt;p&gt;项目目录为tes
      
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>工作笔记</title>
    <link href="http://yoursite.com/2018/05/25/%E5%B7%A5%E4%BD%9C%E7%AC%94%E8%AE%B0/"/>
    <id>http://yoursite.com/2018/05/25/工作笔记/</id>
    <published>2018-05-25T07:58:04.000Z</published>
    <updated>2018-10-24T03:26:04.183Z</updated>
    
    <content type="html"><![CDATA[<p>1.Charles代理的时候，将目标地址生成短链</p><p>2.复杂请求在跨域的情况下会发送预请求（包括子域）</p><p>解决办法：放在同一个域下面，如果没办法放在同一个域下可以将预请求进行缓存，不用每次都发预请求</p><p>3.因为canvas中的getImageData方法不支持跨域，所以当参数fillStyle=image时，fillContent填的图片地址必须与主文件同域，否则程序会把自动涂抹功能改为刮了【percent/10】次之后自动抹去。<br>如果图片不得不跨域，则考虑以下两种解决方案</p><ul><li>通过一个自定义接口，把图片转换成base64编码后再引用</li><li>从网络层面设置图片服务器的响应头 Access-Control-Allow-Origin:*</li></ul>]]></content>
    
    <summary type="html">
    
      
      
        &lt;p&gt;1.Charles代理的时候，将目标地址生成短链&lt;/p&gt;
&lt;p&gt;2.复杂请求在跨域的情况下会发送预请求（包括子域）&lt;/p&gt;
&lt;p&gt;解决办法：放在同一个域下面，如果没办法放在同一个域下可以将预请求进行缓存，不用每次都发预请求&lt;/p&gt;
&lt;p&gt;3.因为canvas中的getIma
      
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>JS学习笔记-算法</title>
    <link href="http://yoursite.com/2018/05/15/JS%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-%E7%AE%97%E6%B3%95/"/>
    <id>http://yoursite.com/2018/05/15/JS学习笔记-算法/</id>
    <published>2018-05-15T02:10:46.000Z</published>
    <updated>2018-10-24T07:08:47.141Z</updated>
    
    <content type="html"><![CDATA[<h4 id="1-二维数组的全排列组合"><a href="#1-二维数组的全排列组合" class="headerlink" title="1.二维数组的全排列组合"></a><strong>1.二维数组的全排列组合</strong></h4><blockquote><p>如输入[[1,2],[3,4],[5,6]]</p><p>  输出：</p><p>  [ 1, 3, 5 ]</p><p>  [ 1, 3, 6 ]</p><p>  [ 1, 4, 5 ]</p><p>  [ 1, 4, 6 ]</p><p>  [ 2, 3, 5 ]</p><p>  [ 2, 3, 6 ]</p><p>  [ 2, 4, 5 ]</p><p>  [ 2, 4, 6 ]</p></blockquote><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">printArr</span>(<span class="params">arr,n,res</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i = <span class="number">0</span>; i&lt;arr[i].length;i++)&#123;</span><br><span class="line">        <span class="keyword">if</span>(n == <span class="number">0</span>)&#123;</span><br><span class="line">            res = []</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(n&lt;arr.length)&#123;</span><br><span class="line">            <span class="keyword">var</span> _res = res.slice()</span><br><span class="line">            _res.push(arr[n][i])</span><br><span class="line">            <span class="keyword">if</span>(n == arr.length<span class="number">-1</span>)&#123;</span><br><span class="line">                <span class="built_in">console</span>.log(_res)</span><br><span class="line">            &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">                printArr(arr,n+<span class="number">1</span>,_res)</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 测试：</span></span><br><span class="line"><span class="keyword">var</span> arr = [[<span class="number">1</span>,<span class="number">2</span>],[<span class="number">3</span>,<span class="number">4</span>],[<span class="number">5</span>,<span class="number">6</span>]]</span><br><span class="line">printArr(arr,<span class="number">0</span>);</span><br></pre></td></tr></table></figure><h4 id="2-打印青蛙跳台阶的所有方式"><a href="#2-打印青蛙跳台阶的所有方式" class="headerlink" title="2.打印青蛙跳台阶的所有方式"></a><strong>2.打印青蛙跳台阶的所有方式</strong></h4><blockquote><p>注意 不是求方式的个数，而是打印每种情况   台阶数为10，每次跳1格或两格</p></blockquote><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">step</span>(<span class="params">n,res</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(n==<span class="number">0</span>)&#123;</span><br><span class="line">        res=[]</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> i=<span class="number">1</span></span><br><span class="line">    <span class="keyword">while</span>(i&lt;<span class="number">3</span>)&#123;</span><br><span class="line">        <span class="keyword">if</span>(n+i&lt;=<span class="number">10</span>)&#123;</span><br><span class="line">            <span class="keyword">var</span> _res = res.slice()</span><br><span class="line">            _res.push(i)</span><br><span class="line">            <span class="keyword">if</span>(n+i == <span class="number">10</span>) &#123;</span><br><span class="line">                <span class="built_in">console</span>.log(_res)</span><br><span class="line">            &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">                step(n+i, _res)</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        i++</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line">step(<span class="number">0</span>)</span><br></pre></td></tr></table></figure><h4 id="3-统计一个字符串出现最多的字母"><a href="#3-统计一个字符串出现最多的字母" class="headerlink" title="3.统计一个字符串出现最多的字母"></a><strong>3.统计一个字符串出现最多的字母</strong></h4><blockquote><p>输入 ： afjghdfraaaasdenas</p><p>输出：a</p></blockquote><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">findMaxDuplicateChar</span>(<span class="params">str</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (str.length == <span class="number">1</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> str;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> charObj = &#123;&#125;;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; str.length; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (!charObj[str.charAt(i)]) &#123;</span><br><span class="line">            charObj[str.charAt(i)] = <span class="number">1</span>;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            charObj[str.charAt(i)] += <span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> maxChar = <span class="string">''</span>,</span><br><span class="line">        maxValue = <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">var</span> k <span class="keyword">in</span> charObj) &#123;</span><br><span class="line">        <span class="keyword">if</span> (charObj[k] &gt;= maxValue) &#123;</span><br><span class="line">            maxChar = k;</span><br><span class="line">            maxValue = charObj[k];</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> maxChar;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 测试：</span></span><br><span class="line">findMaxDuplicateChar(<span class="string">'afjghdfraaaasdenas'</span>)</span><br></pre></td></tr></table></figure><h3 id="排序算法"><a href="#排序算法" class="headerlink" title="排序算法"></a>排序算法</h3><p>排序算法有很多种，而经典的和用的比较多的就是冒泡和快排，<a href="http://jsdo.it/norahiko/oxIy/fullscreen" target="_blank" rel="noopener">动画演示</a></p><h4 id="4-冒泡排序"><a href="#4-冒泡排序" class="headerlink" title="4.冒泡排序"></a><strong>4.冒泡排序</strong></h4><blockquote><p>输入 ： [33,1,4,23,12,43,54,34]</p><p>输出：[1, 4, 12, 23, 33, 34, 43, 54]</p></blockquote><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">bubble</span>(<span class="params">arr</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i= <span class="number">0</span>; i&lt; arr.length <span class="number">-1</span>; i++) &#123;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">var</span> j= i; j&lt; arr.length <span class="number">-1</span>; j++) &#123;</span><br><span class="line">            <span class="keyword">if</span>(arr[j] &gt; arr[j+<span class="number">1</span>]) &#123;</span><br><span class="line">                <span class="keyword">var</span> tmp = arr[j];</span><br><span class="line">                arr[j] = arr[j+<span class="number">1</span>];</span><br><span class="line">                arr[j+<span class="number">1</span>] = tmp;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> arr;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//测试:</span></span><br><span class="line"><span class="built_in">console</span>.log(bubble([<span class="number">33</span>, <span class="number">1</span>, <span class="number">4</span>, <span class="number">23</span>, <span class="number">12</span>, <span class="number">43</span>, <span class="number">54</span>, <span class="number">34</span>]));</span><br></pre></td></tr></table></figure><h4 id="5-快速排序"><a href="#5-快速排序" class="headerlink" title="5.快速排序"></a><strong>5.快速排序</strong></h4><blockquote><p>输入 ： [33,1,4,23,12,43,54,34]</p><p>输出：[1, 4, 12, 23, 33, 34, 43, 54]</p></blockquote><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">quick</span>(<span class="params">arr</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (arr.length &lt;= <span class="number">1</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> arr;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> middleIndex = <span class="built_in">Math</span>.floor(arr.length / <span class="number">2</span>);</span><br><span class="line">    <span class="keyword">var</span> middle = arr.splice(middleIndex, <span class="number">1</span>)[<span class="number">0</span>];</span><br><span class="line">    <span class="keyword">var</span> leftArr = [],</span><br><span class="line">        rightArr = [];</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; arr.length; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (arr[i] &lt; middle) &#123;</span><br><span class="line">            leftArr.push(arr[i]);</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            rightArr.push(arr[i]);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> quick(leftArr).concat([middle], quick(rightArr));</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(quick([<span class="number">33</span>,<span class="number">1</span>,<span class="number">4</span>,<span class="number">23</span>,<span class="number">12</span>,<span class="number">43</span>,<span class="number">54</span>,<span class="number">34</span>]));</span><br></pre></td></tr></table></figure><h4 id="6-生成指定范围内的随机数"><a href="#6-生成指定范围内的随机数" class="headerlink" title="6.生成指定范围内的随机数"></a><strong>6.生成指定范围内的随机数</strong></h4><blockquote><p>输入 ： 5，10</p><p>输出：5，7，9，8，6，10……</p></blockquote><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">randomNum</span>(<span class="params">min, max</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">Math</span>.floor(<span class="built_in">Math</span>.random() * (max - min + <span class="number">1</span>)) + min;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">setInterval(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(randomNum(<span class="number">5</span>, <span class="number">10</span>));</span><br><span class="line">&#125;,<span class="number">1000</span>)</span><br></pre></td></tr></table></figure><h4 id="7-利用一个for循环找出一个数组中第二大的数"><a href="#7-利用一个for循环找出一个数组中第二大的数" class="headerlink" title="7.利用一个for循环找出一个数组中第二大的数"></a><strong>7.利用一个for循环找出一个数组中第二大的数</strong></h4><blockquote><p>输入 ： [1, 3, 6, 4, 8, 23, 54, 11]</p><p>输出：23</p></blockquote><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">getSecond</span>(<span class="params">arr</span>) </span>&#123;</span><br><span class="line">        <span class="keyword">var</span> largestNum = arr[<span class="number">0</span>] &gt; arr[<span class="number">1</span>]? arr[<span class="number">0</span>] : arr[<span class="number">1</span>];</span><br><span class="line">        <span class="keyword">var</span> secondNum = arr[<span class="number">0</span>] &lt;= arr[<span class="number">1</span>]? arr[<span class="number">0</span>] : arr[<span class="number">1</span>];</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">var</span> i =<span class="number">2</span>; i&lt; arr.length; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span>(arr[i] &gt; largestNum) &#123;</span><br><span class="line">                secondNum = largestNum;</span><br><span class="line">                largestNum = arr[i];</span><br><span class="line">            &#125;<span class="keyword">else</span> <span class="keyword">if</span>(arr[i] &gt; secondNum) &#123;</span><br><span class="line">                secondNum = arr[i];</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> secondNum;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="built_in">console</span>.log(getSecond([<span class="number">1</span>, <span class="number">3</span>, <span class="number">6</span>, <span class="number">4</span>, <span class="number">8</span>, <span class="number">23</span>, <span class="number">54</span>, <span class="number">11</span>]));</span><br></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h4 id=&quot;1-二维数组的全排列组合&quot;&gt;&lt;a href=&quot;#1-二维数组的全排列组合&quot; class=&quot;headerlink&quot; title=&quot;1.二维数组的全排列组合&quot;&gt;&lt;/a&gt;&lt;strong&gt;1.二维数组的全排列组合&lt;/strong&gt;&lt;/h4&gt;&lt;blockquote&gt;
&lt;p&gt;
      
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>JS学习笔记-Promise</title>
    <link href="http://yoursite.com/2018/05/09/JS%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-Promise/"/>
    <id>http://yoursite.com/2018/05/09/JS学习笔记-Promise/</id>
    <published>2018-05-09T07:19:12.000Z</published>
    <updated>2018-10-24T03:26:04.138Z</updated>
    
    <content type="html"><![CDATA[<p>此文是最近又温习了一下Promise的源码，发现自己又懵逼了，于是决定在我被虐完还清醒的状态下记点什么，免得过段时间再看又是那个状态。。</p><p>关于Promise源码解读比较好的有篇文章不错，可以<a href="https://tech.meituan.com/promise-insight.html" target="_blank" rel="noopener">传送</a>过去看一下</p><p>借鉴他文章里的一个🌰：</p><p>通过用户id获取其手机号</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//获取用户ID</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">getUserId</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span> (<span class="params">resolve</span>) </span>&#123;</span><br><span class="line">        resolve(<span class="number">9876</span>);</span><br><span class="line">    &#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//通过ID获取手机号</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">getUserMobileById</span>(<span class="params">id</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span> (<span class="params">resolve</span>) </span>&#123;</span><br><span class="line">        Y.io(<span class="string">'/usermobile/'</span> + id, &#123;</span><br><span class="line">            on: &#123;</span><br><span class="line">                success: <span class="function"><span class="keyword">function</span> (<span class="params">i, o</span>) </span>&#123;</span><br><span class="line">                    resolve(<span class="built_in">JSON</span>.parse(o).mobile);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">           &#125;);</span><br><span class="line">    &#125;);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>此时想做的就是getUserId获取到ID后传给getUserMobileById去换取手机号，于是调用的方式就是这样的：</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//例1</span></span><br><span class="line">getUserId()</span><br><span class="line">    .then(getUserMobileById)</span><br><span class="line">    .then(<span class="function"><span class="keyword">function</span> (<span class="params">mobile</span>) </span>&#123;</span><br><span class="line">        <span class="comment">// do sth else with mobile</span></span><br><span class="line">    &#125;, <span class="function"><span class="keyword">function</span> (<span class="params">error</span>) </span>&#123;</span><br><span class="line">        <span class="comment">// getUserId或者getUerMobileById时出现的错误</span></span><br><span class="line">        <span class="built_in">console</span>.log(error);</span><br><span class="line">    &#125;);</span><br></pre></td></tr></table></figure><p>当然也可以有另外的写法</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//例2</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">getUserId</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span> (<span class="params">resolve</span>) </span>&#123;</span><br><span class="line">        resolve(getUserMobileById(<span class="number">9876</span>));</span><br><span class="line">    &#125;);</span><br><span class="line">&#125;</span><br><span class="line">getUserId().then(<span class="function"><span class="keyword">function</span>(<span class="params">res</span>)</span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(res);</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure><p>其实两种写法原理都是一样的，只是写的位置不同而已，今天要说的是第一种写法。</p><p>先放几个关键的方法：</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">this</span>.then = <span class="function"><span class="keyword">function</span> (<span class="params">onFulfilled</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span> (<span class="params">resolve</span>) </span>&#123;</span><br><span class="line">        handle(&#123;</span><br><span class="line">            onFulfilled: onFulfilled || <span class="literal">null</span>,</span><br><span class="line">            resolve: resolve</span><br><span class="line">        &#125;);</span><br><span class="line">    &#125;);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">handle</span>(<span class="params">deferred</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (state === <span class="string">'pending'</span>) &#123;</span><br><span class="line">        deferreds.push(deferred);</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">var</span> ret = deferred.onFulfilled(value);</span><br><span class="line">    deferred.resolve(ret);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">resolve</span>(<span class="params">newValue</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (newValue &amp;&amp; (<span class="keyword">typeof</span> newValue === <span class="string">'object'</span> || <span class="keyword">typeof</span> newValue === <span class="string">'function'</span>)) &#123;</span><br><span class="line">        <span class="keyword">var</span> then = newValue.then;</span><br><span class="line">        <span class="keyword">if</span> (<span class="keyword">typeof</span> then === <span class="string">'function'</span>) &#123;</span><br><span class="line">            then.call(newValue, resolve);</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    state = <span class="string">'fulfilled'</span>;</span><br><span class="line">    value = newValue;</span><br><span class="line">    setTimeout(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">        deferreds.forEach(<span class="function"><span class="keyword">function</span> (<span class="params">deferred</span>) </span>&#123;</span><br><span class="line">            handle(deferred);</span><br><span class="line">        &#125;);</span><br><span class="line">    &#125;, <span class="number">0</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>回到例1</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">getUserId()</span><br><span class="line">    .then(getUserMobileById)</span><br><span class="line">    .then(<span class="function"><span class="keyword">function</span> (<span class="params">mobile</span>) </span>&#123;</span><br><span class="line">        <span class="comment">// do sth else with mobile</span></span><br><span class="line">    &#125;, <span class="function"><span class="keyword">function</span> (<span class="params">error</span>) </span>&#123;</span><br><span class="line">        <span class="comment">// getUserId或者getUerMobileById时出现的错误</span></span><br><span class="line">        <span class="built_in">console</span>.log(error);</span><br><span class="line">    &#125;);</span><br></pre></td></tr></table></figure><p>1.首先执行getUserId，其返回的是一个Promise实例（IDPro），执行其内部的逻辑，调用IDPro的resolve方法并传入9876</p><p>2.resolve将IDPro的pending变成fulfilled状态，延迟遍历deferreds数组，同时循环执行handle并将deferreds的每项传入进去</p><p>3.进入handle方法中，此时的IDPro状态为fulfilled，所以他会执行传入的deferred中的onFulfilled和resolve，此时，onFulfilled为getUserMobileById（MOPro），resolve属于第一次调用then方法生成的bridge Promise。执行onFulfilled将value（9876）传入，返回值是一个Promise实例，执行其内部的逻辑，然后将该实例传入resolve中。</p><p>4.进入resolve中后，由于满足上面的条件，所以直接调用了MOPro的then方法，将bridge Promise的resolve传入进去并返回。</p><p>5.当MOPro执行了其内部的resolve时，将MOPro的状态变成了fulfilled，延迟遍历deferreds数组，同时循环执行handle并将deferreds的每项传入进去</p><p>6.进入handle方法中，此时onFulfilled为IDPro的then方法返回的bridge Promise的resolve，调用onFulfilled将value传入，此时bridge Promise会执行其then方法中注入的deferred，其实它的then方法就是例1中的第二个then方法，它不是MOPro的then方法，而是bridge Promise。。。</p><p>回头再去看这张也就觉得合理了</p><p><img src="https://tech.meituan.com/img/promise-series-flow.png" alt=""></p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;p&gt;此文是最近又温习了一下Promise的源码，发现自己又懵逼了，于是决定在我被虐完还清醒的状态下记点什么，免得过段时间再看又是那个状态。。&lt;/p&gt;
&lt;p&gt;关于Promise源码解读比较好的有篇文章不错，可以&lt;a href=&quot;https://tech.meituan.com/p
      
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>js获取css中某个元素的样式</title>
    <link href="http://yoursite.com/2018/05/04/js%E8%8E%B7%E5%8F%96css%E4%B8%AD%E6%9F%90%E4%B8%AA%E5%85%83%E7%B4%A0%E7%9A%84%E6%A0%B7%E5%BC%8F/"/>
    <id>http://yoursite.com/2018/05/04/js获取css中某个元素的样式/</id>
    <published>2018-05-04T08:49:44.000Z</published>
    <updated>2018-10-24T03:26:04.156Z</updated>
    
    <content type="html"><![CDATA[<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE html&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span> <span class="attr">lang</span>=<span class="string">"en"</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">"UTF-8"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">title</span>&gt;</span>Document<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">style</span>&gt;</span><span class="undefined"></span></span><br><span class="line"><span class="css"><span class="selector-id">#divTransform</span> &#123;</span></span><br><span class="line"><span class="undefined">    margin: 30px;</span></span><br><span class="line"><span class="undefined">    width: 200px;</span></span><br><span class="line"><span class="undefined">    height: 100px;</span></span><br><span class="line"><span class="undefined">    background-color: yellow;</span></span><br><span class="line"><span class="css">    <span class="comment">/* Rotate div */</span></span></span><br><span class="line"><span class="undefined">    transform: rotate(9deg);</span></span><br><span class="line"><span class="undefined">    -ms-transform: rotate(9deg);</span></span><br><span class="line"><span class="css">    <span class="comment">/* Internet Explorer */</span></span></span><br><span class="line"><span class="undefined">    -moz-transform: rotate(9deg);</span></span><br><span class="line"><span class="css">    <span class="comment">/* Firefox */</span></span></span><br><span class="line"><span class="undefined">    -webkit-transform: rotate(9deg);</span></span><br><span class="line"><span class="css">    <span class="comment">/* Safari 和 Chrome */</span></span></span><br><span class="line"><span class="undefined">    -o-transform: rotate(9deg);</span></span><br><span class="line"><span class="css">    <span class="comment">/* Opera */</span></span></span><br><span class="line"><span class="undefined">&#125;</span></span><br><span class="line"><span class="undefined"></span><span class="tag">&lt;/<span class="name">style</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">"divTransform"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="undefined"></span></span><br><span class="line"><span class="javascript"><span class="keyword">var</span> el = <span class="built_in">document</span>.getElementById(<span class="string">"divTransform"</span>);</span></span><br><span class="line"><span class="javascript"><span class="keyword">var</span> st = <span class="built_in">window</span>.getComputedStyle(el, <span class="literal">null</span>);</span></span><br><span class="line"><span class="javascript"><span class="keyword">var</span> tr = st.getPropertyValue(<span class="string">"-webkit-transform"</span>) ||</span></span><br><span class="line"><span class="javascript">    st.getPropertyValue(<span class="string">"-moz-transform"</span>) ||</span></span><br><span class="line"><span class="javascript">    st.getPropertyValue(<span class="string">"-ms-transform"</span>) ||</span></span><br><span class="line"><span class="javascript">    st.getPropertyValue(<span class="string">"-o-transform"</span>) ||</span></span><br><span class="line"><span class="javascript">    st.getPropertyValue(<span class="string">"transform"</span>) ||</span></span><br><span class="line"><span class="javascript">    <span class="string">"FAIL"</span>;</span></span><br><span class="line"><span class="undefined"></span></span><br><span class="line"><span class="javascript"><span class="comment">// With rotate(30deg)...</span></span></span><br><span class="line"><span class="javascript"><span class="comment">// matrix(0.866025, 0.5, -0.5, 0.866025, 0px, 0px)</span></span></span><br><span class="line"><span class="javascript"><span class="built_in">console</span>.log(<span class="string">'Matrix: '</span> + tr);</span></span><br><span class="line"><span class="undefined"></span></span><br><span class="line"><span class="javascript"><span class="comment">// rotation matrix - http://en.wikipedia.org/wiki/Rotation_matrix</span></span></span><br><span class="line"><span class="undefined"></span></span><br><span class="line"><span class="javascript"><span class="keyword">var</span> values = tr.split(<span class="string">'('</span>)[<span class="number">1</span>].split(<span class="string">')'</span>)[<span class="number">0</span>].split(<span class="string">','</span>);</span></span><br><span class="line"><span class="javascript"><span class="keyword">var</span> a = values[<span class="number">0</span>];</span></span><br><span class="line"><span class="javascript"><span class="keyword">var</span> b = values[<span class="number">1</span>];</span></span><br><span class="line"><span class="javascript"><span class="keyword">var</span> c = values[<span class="number">2</span>];</span></span><br><span class="line"><span class="javascript"><span class="keyword">var</span> d = values[<span class="number">3</span>];</span></span><br><span class="line"><span class="undefined"></span></span><br><span class="line"><span class="javascript"><span class="keyword">var</span> scale = <span class="built_in">Math</span>.sqrt(a * a + b * b);</span></span><br><span class="line"><span class="undefined"></span></span><br><span class="line"><span class="javascript"><span class="built_in">console</span>.log(<span class="string">'Scale: '</span> + scale);</span></span><br><span class="line"><span class="undefined"></span></span><br><span class="line"><span class="javascript"><span class="comment">// arc sin, convert from radians to degrees, round</span></span></span><br><span class="line"><span class="javascript"><span class="keyword">var</span> sin = b / scale;</span></span><br><span class="line"><span class="javascript"><span class="comment">// next line works for 30deg but not 130deg (returns 50);</span></span></span><br><span class="line"><span class="javascript"><span class="comment">// var angle = Math.round(Math.asin(sin) * (180/Math.PI));</span></span></span><br><span class="line"><span class="javascript"><span class="keyword">var</span> angle = <span class="built_in">Math</span>.round(<span class="built_in">Math</span>.atan2(b, a) * (<span class="number">180</span> / <span class="built_in">Math</span>.PI));</span></span><br><span class="line"><span class="undefined"></span></span><br><span class="line"><span class="javascript"><span class="built_in">console</span>.log(<span class="string">'Rotate: '</span> + angle + <span class="string">'deg'</span>);</span></span><br><span class="line"><span class="undefined"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      
      
        &lt;figure class=&quot;highlight html&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=
      
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>正则的学习笔记</title>
    <link href="http://yoursite.com/2018/03/28/%E6%AD%A3%E5%88%99%E7%9A%84%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
    <id>http://yoursite.com/2018/03/28/正则的学习笔记/</id>
    <published>2018-03-28T02:36:44.000Z</published>
    <updated>2018-10-24T03:26:04.193Z</updated>
    
    <content type="html"><![CDATA[<h5 id="1"><a href="#1" class="headerlink" title="1.\"></a>1.\</h5><p>在非特殊字符之前的反斜杠表示下一个字符是特殊的，不能从字面上解释</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/\/fa/.exec(<span class="string">"/fao"</span>)     <span class="comment">//===&gt; /fa</span></span><br></pre></td></tr></table></figure><p>#####2.^和$</p><p>^是匹配输入的开始</p><p>$是匹配输入的结束</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">/^A/.exec(<span class="string">'an A'</span>)  <span class="comment">//匹配不到</span></span><br><span class="line">/A$/.exec(<span class="string">'an A'</span>)  <span class="comment">//===&gt; A</span></span><br></pre></td></tr></table></figure><p>#####3.*</p><p>匹配前一个表达式0次或多次，等价于 {0,}</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/bo*<span class="regexp">/.exec('A ghost boooooed')  /</span><span class="regexp">/===&gt; booooo</span></span><br></pre></td></tr></table></figure><h5 id="4"><a href="#4" class="headerlink" title="4.+"></a>4.+</h5><p>匹配前面一个表达式1次或者多次，等价于 {1,}</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//这样和*没有区别，结果是一样的</span></span><br><span class="line">/bo+<span class="regexp">/.exec('A ghost boooooed')  /</span><span class="regexp">/===&gt; booooo</span></span><br><span class="line"><span class="regexp">/</span><span class="regexp">/但是这样就会区别他俩的区别</span></span><br><span class="line"><span class="regexp">/</span>bo+<span class="regexp">/.exec('A ghost bed')  /</span><span class="regexp">/===&gt; null</span></span><br><span class="line"><span class="regexp">/</span>bo*<span class="regexp">/.exec('A ghost bed')  /</span><span class="regexp">/===&gt; b</span></span><br></pre></td></tr></table></figure><h5 id="5"><a href="#5" class="headerlink" title="5.?"></a>5.?</h5><ul><li>匹配前面一个表达式0次或者1次，等价于 {0,1}</li></ul><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">/e?le?<span class="regexp">/.exec('angel')  /</span><span class="regexp">/===&gt; el</span></span><br><span class="line"><span class="regexp">/</span>e?le?<span class="regexp">/.exec('angle')  /</span><span class="regexp">/===&gt; le</span></span><br><span class="line"><span class="regexp">/</span>e?le?<span class="regexp">/.exec('solo')   /</span><span class="regexp">/===&gt; l</span></span><br></pre></td></tr></table></figure><ul><li>非贪婪匹配</li></ul><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">/ca+<span class="regexp">/.exec('caaaaaaandy') /</span><span class="regexp">/===&gt; caaaaaaa</span></span><br><span class="line"><span class="regexp">/</span><span class="regexp">/在符合匹配规则的情况下，尽量少匹配</span></span><br><span class="line"><span class="regexp">/</span>ca+?<span class="regexp">/.exec('caaaaaaandy')  /</span><span class="regexp">/===&gt; ca</span></span><br></pre></td></tr></table></figure><h5 id="6"><a href="#6" class="headerlink" title="6.  ."></a>6.  <code>.</code></h5><p>(小数点)匹配除换行符之外的任何<strong><em>单个字符</em></strong></p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//匹配o已经前面的一个字符</span></span><br><span class="line">/.o/.exec(<span class="string">"fao bar f bar"</span>)  <span class="comment">//===&gt; ao</span></span><br><span class="line"><span class="comment">//匹配o前面的单个字符(不包括o)</span></span><br><span class="line">/.(?=o)/.exec(<span class="string">"fao bar f bar"</span>)  <span class="comment">//===&gt; a</span></span><br><span class="line"><span class="comment">//匹配o前面的所有字符(不包括o)</span></span><br><span class="line">/.+(?=o)/.exec(<span class="string">"fao bar f bar"</span>)  <span class="comment">//===&gt; fa</span></span><br></pre></td></tr></table></figure><h5 id="7-X"><a href="#7-X" class="headerlink" title="7.(X)"></a>7.(X)</h5><p>匹配 ‘x’ 并且记住匹配项</p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h5 id=&quot;1&quot;&gt;&lt;a href=&quot;#1&quot; class=&quot;headerlink&quot; title=&quot;1.\&quot;&gt;&lt;/a&gt;1.\&lt;/h5&gt;&lt;p&gt;在非特殊字符之前的反斜杠表示下一个字符是特殊的，不能从字面上解释&lt;/p&gt;
&lt;figure class=&quot;highlight javascri
      
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>移动端适配解决方案-rem布局</title>
    <link href="http://yoursite.com/2018/03/05/%E7%A7%BB%E5%8A%A8%E7%AB%AF%E9%80%82%E9%85%8D%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88-rem%E5%B8%83%E5%B1%80/"/>
    <id>http://yoursite.com/2018/03/05/移动端适配解决方案-rem布局/</id>
    <published>2018-03-05T07:02:13.000Z</published>
    <updated>2018-10-24T03:26:04.196Z</updated>
    
    <content type="html"><![CDATA[<p>本文为转载,<a href="https://www.jianshu.com/p/985d26b40199" target="_blank" rel="noopener">原文链接</a></p><p>这是阿里团队的高清方案布局代码，所谓高清方案就是根据设备屏幕的DPR（设备像素比，又称DPPX，比如dpr=2时，表示1个CSS像素由4个物理像素点组成） 动态设置 html 的font-size, 同时根据设备DPR调整页面的缩放值，进而达到高清效果。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;script&gt;!function(e)&#123;function t(a)&#123;if(i[a])return i[a].exports;var n=i[a]=&#123;exports:&#123;&#125;,id:a,loaded:!1&#125;;return e[a].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports&#125;var i=&#123;&#125;;return t.m=e,t.c=i,t.p=&quot;&quot;,t(0)&#125;([function(e,t)&#123;&quot;use strict&quot;;Object.defineProperty(t,&quot;__esModule&quot;,&#123;value:!0&#125;);var i=window;t[&quot;default&quot;]=i.flex=function(normal,e,t)&#123;var a=e||100,n=t||1,r=i.document,o=navigator.userAgent,d=o.match(/Android[\S\s]+AppleWebkit\/(\d&#123;3&#125;)/i),l=o.match(/U3\/((\d+|\.)&#123;5,&#125;)/i),c=l&amp;&amp;parseInt(l[1].split(&quot;.&quot;).join(&quot;&quot;),10)&gt;=80,p=navigator.appVersion.match(/(iphone|ipad|ipod)/gi),s=i.devicePixelRatio||1;p||d&amp;&amp;d[1]&gt;534||c||(s=1);var u=normal?1:1/s,m=r.querySelector(&apos;meta[name=&quot;viewport&quot;]&apos;);m||(m=r.createElement(&quot;meta&quot;),m.setAttribute(&quot;name&quot;,&quot;viewport&quot;),r.head.appendChild(m)),m.setAttribute(&quot;content&quot;,&quot;width=device-width,user-scalable=no,initial-scale=&quot;+u+&quot;,maximum-scale=&quot;+u+&quot;,minimum-scale=&quot;+u),r.documentElement.style.fontSize=normal?&quot;50px&quot;: a/2*s*n+&quot;px&quot;&#125;,e.exports=t[&quot;default&quot;]&#125;]); flex(false,100, 1);&lt;/script&gt;</span><br></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      
      
        &lt;p&gt;本文为转载,&lt;a href=&quot;https://www.jianshu.com/p/985d26b40199&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;原文链接&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;这是阿里团队的高清方案布局代码，所谓高清方案就是根据设备屏幕的DPR（
      
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>前端发布系统技术方案</title>
    <link href="http://yoursite.com/2018/02/28/%E5%89%8D%E7%AB%AF%E5%8F%91%E5%B8%83%E7%B3%BB%E7%BB%9F%E6%8A%80%E6%9C%AF%E6%96%B9%E6%A1%88/"/>
    <id>http://yoursite.com/2018/02/28/前端发布系统技术方案/</id>
    <published>2018-02-28T02:36:46.000Z</published>
    <updated>2018-10-24T03:26:04.177Z</updated>
    
    <content type="html"><![CDATA[<p>前端发布系统技术方案</p><p>目标</p><ol><li>区分环境发布（开发、日常、预发、线上）。</li><li>增加流程监控，禁止随意发布。</li><li>一. 键快速回滚。</li><li>增加代码检测功能（以后）</li></ol><p>技术方案</p><ol><li>以git仓库为维度发布项目</li><li>必须从master切出新的发布分支</li><li>git master为主干，禁止开发人员操作master，主干用于发布后代码合并，并且发布后打上tag。</li><li>如果需要回滚，选择相应tag回滚。</li></ol><p>详点</p><p>组配置</p><p>一个host对应一个组，每个组下面分仓库发布。</p><p>如：crm.adbaitai.com/crm-&gt;crm.adbaitai.com/crm 我们使用oschina可能在命名上会有瑕疵</p><ul><li>host地址</li><li>ip地址</li><li>服务端webserve路径</li><li>端口地址</li><li>git组地址</li><li>备注说明</li></ul><p>项目配置</p><ul><li>git仓库地址，需要和相应组配置的git组地址对上</li><li>项目名（不能手工，自动从仓库地址分解）</li><li>说明</li><li>开发人员</li><li>测试人员</li></ul><p>项目日常发布</p><ol><li>选择发布的版本</li><li>版本号大于等于之前的版本</li><li>发布的理由</li><li>显示发布列表</li></ol><p>项目预发发布</p><ol><li>必须发布过日常（待选）</li><li>版本号于等于之前发布版本</li><li>发布的理由</li><li>显示发布列表</li></ol><p>项目线上发布</p><ol><li>必须发布过预发</li><li>版本号要大于线上版本</li><li>发布的理由</li><li>显示发布列表</li><li>列表有回滚操作</li></ol><p>技术架构</p><p>nodejs mysql vue html5 css3</p><p>思维导图<br><img src="http://oss.ltcdn.cc/cow/2017/11/27/828w_2041h_1A2971511775613_origin.png" width="300px"></p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;p&gt;前端发布系统技术方案&lt;/p&gt;
&lt;p&gt;目标&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;区分环境发布（开发、日常、预发、线上）。&lt;/li&gt;
&lt;li&gt;增加流程监控，禁止随意发布。&lt;/li&gt;
&lt;li&gt;一. 键快速回滚。&lt;/li&gt;
&lt;li&gt;增加代码检测功能（以后）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;技术方
      
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>重绘和回流（重排）</title>
    <link href="http://yoursite.com/2018/02/24/%E9%87%8D%E7%BB%98%E5%92%8C%E5%9B%9E%E6%B5%81/"/>
    <id>http://yoursite.com/2018/02/24/重绘和回流/</id>
    <published>2018-02-24T02:35:57.000Z</published>
    <updated>2018-10-24T03:26:04.199Z</updated>
    
    <content type="html"><![CDATA[<h2 id="写在前面"><a href="#写在前面" class="headerlink" title="写在前面"></a><code>写在前面</code></h2><p>######本文是看了几篇关于重绘和回流的文章后对几篇文章进行的糅合和摘取</p><p>浏览器从下载文档到显示页面的过程是个复杂的过程，这里包含了重绘和重排。各家浏览器引擎的工作原理略有差<br>别，但也有一定规则。简单讲，通常在文档初次加载时，浏览器引擎会解析HTML文档来构建DOM树，之后根据DOM元素的几何属性构建一棵用于渲染的树。</p><p>渲染树的每个节点都有大小和边距等属性，类似于盒子模型（由于隐藏元素不需要显示，渲染树中并不包含DOM树中隐藏的元素）。当渲染树构建完成后，浏览器<br> 就可以将元素放置到正确的位置了，再根据渲染树节点的样式属性绘制出页面。由于浏览器的流布局，对渲染树的计算通常只需要遍历一次就可以完成。但<br>table及其内部元素除外，它可能需要多次计算才能确定好其在渲染树中节点的属性，通常要花3倍于同等元素的时间。这也是为什么我们要避免使用<br>table做布局的一个原因。</p><p>重绘是一个元素外观的改变所触发的浏览器行为，例如改变vidibility、outline、背景色等属性。浏览器会根据元素的新属性重新绘制，使元素呈现新的外观。重绘不会带来重新布局，并不一定伴随重排。</p><p>重排是更明显的一种改变，可以理解为渲染树需要重新计算。</p><p>其实理解起来很容易。所谓的render树就是识别了几何属性的dom数，好像我们画人体的时候，dom树是先确定都有什么比如四肢，头部，身体，其他器官等；而render树则是确定这个人的高矮胖瘦，头发是否盖眼睛等，如果我们在绘画过程中发现脖子长了那就惨了，脖子下面都要重画。这就是回流了。如果发现只是手指画的有问题也还是要回流但我们只需要重画手指。（当然，我说的是手就是手，没什么特别造型的时候）；当我们的render树完事了，也就是人体大概轮廓我们都画好了，就可以上色了，换个发色这种我们叫重绘。</p><p>下面是常见的触发重排的操作：</p><p><strong>1. DOM元素的几何属性变化</strong></p><p>当DOM元素的几何属性变化时，渲染树中的相关节点就会失效，浏览器会根据DOM元素的变化重建构建渲染树中失效的节点。之后，会根据新的渲染树重新绘<br>制这部分页面。而且，当前元素的重排也许会带来相关元素的重排。例如，容器节点的渲染树改变时，会触发子节点的重新计算，也会触发其后续兄弟节点的重排，<br> 祖先节点需要重新计算子节点的尺寸也会产生重排。最后，每个元素都将发生重绘。可见，重排一定会引起浏览器的重绘，一个元素的重排通常会带来一系列的反<br> 应，甚至触发整个文档的重排和重绘，性能代价是高昂的。</p><p><strong>2.DOM树的结构变化</strong></p><p>当DOM树的 结构变化时，例如节点的增减、移动等，也会触发重排。浏览器引擎布局的过程，类似于树的前序遍历，是一个从上到下从左到右的过程。通常在这个过程中，当前 元素不会再影响其前面已经遍历过的元素。所以，如果在body最前面插入一个元素，会导致整个文档的重新渲染，而在其后插入一个元素，则不会影响到前面的 元素。</p><p><strong>3.获取某些属性</strong></p><p>浏览器引擎可能会针对重排做了优化。比如Opera，它会等到有足够 数量的变化发生，或者等到一定的时间，或者等一个线程结束，再一起处理，这样就只发生一次重排。但除了渲染树的直接变化，当获取一些属性时，浏览器为取得 正确的值也会触发重排。这样就使得浏览器的优化失效了。这些属性包括：offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、 clientTop、clientLeft、clientWidth、clientHeight、getComputedStyle() (currentStyle in IE)。所以，在多次使用这些值时应进行缓存。</p><p>此外，改变元素的一些样式，调整浏览器窗口大小等等也都将触发重排。</p><p>开发中，比较好的实践是尽量减少重排次数和缩小重排的影响范围。例如：</p><ol><li>将多次改变样式属性的操作合并成一次操作。例如，</li></ol><p>JS:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> changeDiv = <span class="built_in">document</span>.getElementById(<span class="string">'changeDiv'</span>); </span><br><span class="line">changeDiv.style.color = <span class="string">'#093'</span>; </span><br><span class="line">changeDiv.style.background = <span class="string">'#eee'</span>; </span><br><span class="line">changeDiv.style.height = <span class="string">'200px'</span>;</span><br></pre></td></tr></table></figure><p>可以合并为：</p><p>CSS:</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-tag">div</span><span class="selector-class">.changeDiv</span> &#123;</span><br><span class="line"><span class="attribute">background</span>: <span class="number">#eee</span>;</span><br><span class="line"><span class="attribute">color</span>: <span class="number">#093</span>;</span><br><span class="line"><span class="attribute">height</span>: <span class="number">200px</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>JS:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">document</span>.getElementById(<span class="string">'changeDiv'</span>).className = <span class="string">'changeDiv'</span>;</span><br></pre></td></tr></table></figure><ol start="2"><li>将需要多次重排的元素，position属性设为absolute或fixed，这样此元素就脱离了文档流，它的变化不会影响到其他元素。例如有动画效果的元素就最好设置为绝对定位。</li><li>在内存中多次操作节点，完成后再添加到文档中去。例如要异步获取表格数据，渲染到页面。可以先取得数据后在内存中构建整个表格的html片段，再一次性添加到文档中去，而不是循环添加每一行。</li><li>由于display属性为none的元素不在渲染树中，对隐藏的元素操作不会引发其他元素的重排。如果要对一个元素进行复杂的操作时，可以先隐藏它，操作完成后再显示。这样只在隐藏和显示时触发2次重排。</li><li>在需要经常取那些引起浏览器重排的属性值时，要缓存到变量。</li></ol><p>在最近几次面试中比较常问的一个问题：在前端如何实现一个表格的排序。如果应聘者的方案中考虑到了如何减少重绘和重排的影响，将是使人满意的方案。</p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h2 id=&quot;写在前面&quot;&gt;&lt;a href=&quot;#写在前面&quot; class=&quot;headerlink&quot; title=&quot;写在前面&quot;&gt;&lt;/a&gt;&lt;code&gt;写在前面&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;######本文是看了几篇关于重绘和回流的文章后对几篇文章进行的糅合和摘取&lt;/p&gt;
&lt;p&gt;浏览器从
      
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>react的日常问题小总结</title>
    <link href="http://yoursite.com/2018/02/08/react%E7%9A%84%E6%97%A5%E5%B8%B8%E9%97%AE%E9%A2%98%E5%B0%8F%E6%80%BB%E7%BB%93/"/>
    <id>http://yoursite.com/2018/02/08/react的日常问题小总结/</id>
    <published>2018-02-08T06:13:36.000Z</published>
    <updated>2018-10-24T03:26:04.161Z</updated>
    
    <content type="html"><![CDATA[<h2 id="写在前面"><a href="#写在前面" class="headerlink" title="写在前面"></a><code>写在前面</code></h2><p>先附上一些关于react的文章，留着以后查漏补缺用：</p><p><a href="https://www.jianshu.com/p/4784216b8194" target="_blank" rel="noopener">react的生命周期</a></p><p><a href="https://segmentfault.com/a/1190000011523084" target="_blank" rel="noopener">对react一些原理性的理解</a></p><ul><li>React合成事件系统</li></ul><p><a href="https://segmentfault.com/a/1190000004527878" target="_blank" rel="noopener">react-router的实现原理</a></p><p><a href="https://segmentfault.com/a/1190000008051628" target="_blank" rel="noopener">React中setState同步更新策略</a></p><h5 id="1-为什么在componentWillUpdate中调用setState会造成循环调用"><a href="#1-为什么在componentWillUpdate中调用setState会造成循环调用" class="headerlink" title="1.为什么在componentWillUpdate中调用setState会造成循环调用"></a>1.为什么在componentWillUpdate中调用setState会造成循环调用</h5><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">如果在shouldComponentUpdate和componentWillUpdate中调用了setState，此时<span class="keyword">this</span>._pendingStateQueue != <span class="literal">null</span>，则performUpdateIfNecessary方法就会调用updateComponent方法进行组件更新。但是updateComponent方法又会调用shouldComponentUpdate和componentWillUpdate，因此造成循环调用，使得浏览器内存占满后崩溃。</span><br></pre></td></tr></table></figure><p>#####2.componentDidMount里调用setState会触发componentWillUpdate，但是拿不到新设置的state</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">setState是一个不保证同步的过程</span><br></pre></td></tr></table></figure><p>一般设置state都会放在componentWillMount中去做，这个时候触发componentWillUpdate的函数中就可以得到改变的state</p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h2 id=&quot;写在前面&quot;&gt;&lt;a href=&quot;#写在前面&quot; class=&quot;headerlink&quot; title=&quot;写在前面&quot;&gt;&lt;/a&gt;&lt;code&gt;写在前面&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;先附上一些关于react的文章，留着以后查漏补缺用：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https:
      
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>webpack至于loader的编写</title>
    <link href="http://yoursite.com/2018/01/31/webpack%E8%87%B3%E4%BA%8Eloader%E7%9A%84%E7%BC%96%E5%86%99/"/>
    <id>http://yoursite.com/2018/01/31/webpack至于loader的编写/</id>
    <published>2018-01-31T07:33:06.000Z</published>
    <updated>2018-10-24T03:26:04.170Z</updated>
    
    <content type="html"><![CDATA[<h2 id="写在前面"><a href="#写在前面" class="headerlink" title="写在前面"></a><code>写在前面</code></h2><p>之前看过一篇不错的文章，很适合入门，<a href="https://segmentfault.com/a/1190000012718374" target="_blank" rel="noopener">传送门</a></p><p>本篇文章是基于我看了一些文章后动手写的一些结合平时业务的demo</p><p><a href="https://github.com/youstde/webpackDemo" target="_blank" rel="noopener">完整代码在master分支上</a></p><p>####业务场景：</p><p>我现在想写一个插件，这个插件在编写完成后打包只生成一个js，别人用这个插件的时候只需要将这个js引入即可，相应的布局和样式会自动渲染到页面上（简单的一个插件实现）</p><p>demo目录结构如下：</p><p><img src="http://ww1.sinaimg.cn/large/005QDhBjly1fnzuwox5frj30gc0em75n.jpg" alt=""></p><p>从根目录开始看起，<code>index.html</code>是整个项目的容器模板（测试用），<code>index.js</code>是入口文件，同时也是插件的核心处理文件，其他就不用多说。然后<code>template</code>下面，是插件的核心模板和样式，<code>loader</code>目录下面放的就是自己写的<code>loader</code>了</p><p>下面是webpack的配置：</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> path = <span class="built_in">require</span>(<span class="string">'path'</span>),</span><br><span class="line">    webpack = <span class="built_in">require</span>(<span class="string">'webpack'</span>),</span><br><span class="line">    ROOT_PATH = path.resolve(__dirname), <span class="comment">//当前项目的跟路径（绝对）</span></span><br><span class="line">    BUILD_DIR = path.resolve(ROOT_PATH, <span class="string">'build'</span>);</span><br><span class="line"><span class="keyword">var</span> HtmlWebpackPlugin = <span class="built_in">require</span>(<span class="string">'html-webpack-plugin'</span>);</span><br><span class="line"></span><br><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">    entry: &#123;</span><br><span class="line">    <span class="string">'index'</span>: path.resolve(ROOT_PATH, <span class="string">'./index.js'</span>)</span><br><span class="line">  &#125;,</span><br><span class="line">  output: &#123;</span><br><span class="line">    path: BUILD_DIR,</span><br><span class="line">    publicPath: <span class="string">'./'</span>,</span><br><span class="line">    filename: <span class="string">'[name]/index.js'</span></span><br><span class="line">  &#125;,</span><br><span class="line">    <span class="built_in">module</span>: &#123;</span><br><span class="line">        rules: [&#123;</span><br><span class="line">            test: <span class="regexp">/\.html$/</span>,</span><br><span class="line">            use: [<span class="string">'html-loader'</span>]</span><br><span class="line">        &#125;,&#123;</span><br><span class="line">            test: <span class="regexp">/\.html$/</span>,</span><br><span class="line">            use: [&#123;</span><br><span class="line">                loader: path.resolve(<span class="string">'loader/test-html-loader.js'</span>)</span><br><span class="line">            &#125;],</span><br><span class="line">            include: [path.resolve(<span class="string">'template/'</span>)]</span><br><span class="line">        &#125;]</span><br><span class="line">    &#125;,</span><br><span class="line">    plugins: [</span><br><span class="line">      <span class="comment">//引入这个插件是为了演示用，编写这个项目的时候不需要生成HTML文件，只需要生成一个JS即可</span></span><br><span class="line">        <span class="keyword">new</span> HtmlWebpackPlugin(&#123;</span><br><span class="line">          title: <span class="string">''</span>,</span><br><span class="line">          template: path.resolve(<span class="string">'index.html'</span>),</span><br><span class="line">          filename: <span class="string">'index.html'</span>,</span><br><span class="line">          <span class="comment">//chunks这个参数告诉插件要引用entry里面的哪几个入口</span></span><br><span class="line">          chunks: [<span class="string">'index'</span>],</span><br><span class="line">          <span class="comment">//要把script插入标签里</span></span><br><span class="line">          inject: <span class="string">'body'</span></span><br><span class="line">        &#125;)</span><br><span class="line">    ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>其中核心的部分是：</p><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">            test: /\.html$/,</span><br><span class="line">            use: [&#123;</span><br><span class="line">                loader: path.resolve('loader/test-html-loader.js')</span><br><span class="line">            &#125;],</span><br><span class="line">            include: [path.resolve('template/')]</span><br><span class="line">        &#125;</span><br></pre></td></tr></table></figure><p>这个是我自己写的<code>loader</code>，处理的是以<code>html</code>结尾同时是在<code>template</code>目录下的文件,然后就是<code>test-html-loader</code>的具体代码：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> loaderUtils = require(<span class="string">'loader-utils'</span>);</span><br><span class="line"><span class="keyword">var</span> fs = require(<span class="string">'fs'</span>);</span><br><span class="line"><span class="keyword">module</span>.<span class="keyword">exports</span> = function (source) &#123;</span><br><span class="line"><span class="keyword">var</span> basePath = <span class="keyword">this</span>.context;</span><br><span class="line"><span class="keyword">var</span> cssPath = /(\_include\()+(<span class="string">'|")+(.+)+('</span>|<span class="string">")+\)/.exec(source)[3];</span></span><br><span class="line"><span class="string">var content = fs.readFileSync(basePath +'/'+ cssPath);</span></span><br><span class="line">var all = source.replace(/(\_include\()+('|")+(.+)+('|")+\)/, '&lt;style&gt;'+content+'&lt;/style&gt;');</span><br><span class="line">  <span class="keyword">return</span> all;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>解释一下，这个loader主要做的就是匹配<code>_include(PATH)</code>,然后拿到文件路径,读取对应文件之后替换掉<code>_include(PATH)</code>,最后返回处理后的文件，为什么要这么做，是因为我的center.html里是这样写的：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span><br><span class="line">_include("center.css")</span><br><span class="line"><span class="tag">&lt;<span class="name">h2</span>&gt;</span>test<span class="tag">&lt;/<span class="name">h2</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">h3</span>&gt;</span>xixi<span class="tag">&lt;/<span class="name">h3</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">button</span>&gt;</span>click<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure><p>目的就是将css打到html中，然后index.js再去以模板的形式引入：</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> tpl = <span class="built_in">require</span>(<span class="string">'./template/center.html'</span>);</span><br><span class="line"><span class="keyword">var</span> parentEl = <span class="built_in">document</span>.createElement(<span class="string">'div'</span>);</span><br><span class="line">parentEl.innerHTML = tpl;</span><br><span class="line">parentEl.querySelector(<span class="string">'button'</span>).onclick = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line"><span class="built_in">console</span>.log(<span class="number">111</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">document</span>.body.appendChild(parentEl);</span><br></pre></td></tr></table></figure><p>这样，当我打包完成以后，打开index.html就可以看到</p><p><img src="http://ww1.sinaimg.cn/large/005QDhBjly1fnzvmsu4cnj314o0kcjsc.jpg" alt=""></p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h2 id=&quot;写在前面&quot;&gt;&lt;a href=&quot;#写在前面&quot; class=&quot;headerlink&quot; title=&quot;写在前面&quot;&gt;&lt;/a&gt;&lt;code&gt;写在前面&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;之前看过一篇不错的文章，很适合入门，&lt;a href=&quot;https://segmentfault.c
      
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>前端本地调试跨域问题解决</title>
    <link href="http://yoursite.com/2018/01/05/%E5%89%8D%E7%AB%AF%E6%9C%AC%E5%9C%B0%E8%B0%83%E8%AF%95%E8%B7%A8%E5%9F%9F%E9%97%AE%E9%A2%98%E8%A7%A3%E5%86%B3/"/>
    <id>http://yoursite.com/2018/01/05/前端本地调试跨域问题解决/</id>
    <published>2018-01-05T11:33:24.000Z</published>
    <updated>2018-10-24T03:26:04.179Z</updated>
    
    <content type="html"><![CDATA[<h2 id="写在前面"><a href="#写在前面" class="headerlink" title="写在前面"></a><code>写在前面</code></h2><p><a href="http://blog.csdn.net/cjd6568358/article/details/51871039" target="_blank" rel="noopener">传送门</a></p><p>项目全局配置，这个是接口请求和登录请求的host</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports=&#123;</span><br><span class="line">    apiHost: <span class="string">"//ssppre.adbaitai.com"</span>,<span class="comment">//接口apihost</span></span><br><span class="line">    loginApiHost: <span class="string">"//ssppre.adbaitai.com"</span><span class="comment">//登录和apiHost区分出来主要是本地代理无法处理登录问题</span></span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>而这个项目的预发host是<code>ssppre.adbaitai.com</code></p><p>我本地通过Nginx配合hosts绑定，做了一个反向代理，将<code>h6.ssppre.adbaitai.com</code>,代理到<code>http://localhost:8084</code></p><p>这样做的目的是想在本地能够调用预发的登录接口，如果不做这层代理的话，直接<code>http://localhost:8084</code>打开项目是种不上登录的cookie的，因为跨域</p><p>做到这一步应用是成功登录了，但是后续的一些接口请求是报错的，因为我本地是h6.ssppre.adbaitai.com,而apiHost是//ssppre.adbaitai.com。</p><p><img src="http://ww1.sinaimg.cn/large/005QDhBjgy1fn5yzwu1wpj327y15ah3o.jpg" alt=""></p><p>同样还是跨域问题，现在要做的是对接口的调用进行代理</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports=&#123;</span><br><span class="line">    apiHost: <span class="string">"//h6.ssppre.adbaitai.com"</span>,<span class="comment">//接口apihost</span></span><br><span class="line">    loginApiHost: <span class="string">"//ssppre.adbaitai.com"</span><span class="comment">//登录和apiHost区分出来主要是本地代理无法处理登录问题</span></span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>如上，将apiHost改成本地的，然后再将Nginx改一下</p><p><img src="http://ww1.sinaimg.cn/large/005QDhBjgy1fn5z2euvypj30vk0f0mz1.jpg" alt=""></p><p>将带有api 的请求都进行拦截，然后走ssppre.adbaitai.com</p><p>这样就解决了本地调试跨域问题</p><p><code>但是</code>，我这几天自己在搭一个博客系统的时候发现这个方法行不通了</p><p>纳尼😱，试了很多次都是404(因为之前的方法可以是后端已经做了cors的处理，所以直接拦截api就可以实现代理)</p><p>很多人觉得不应该是报跨域的错吗，然而并没有，是404</p><p>为什么会出现404，很显然，这是代理成功了，也请求到了我的接口，而且我接口日志中也有请求日志，既然请求到了为什么会是404，原因就是，你请求我，但是我不想给你数据</p><p>解决这个问题的方法有两种（我喜欢用的两种）：</p><p>1.我后台是koa2搭的，所以我引入了一个插件—<code>koa2-cors</code></p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> Koa = <span class="built_in">require</span>(<span class="string">'koa'</span>);</span><br><span class="line"><span class="keyword">const</span> fs = <span class="built_in">require</span>(<span class="string">'fs'</span>);</span><br><span class="line"><span class="keyword">const</span> config = <span class="built_in">require</span>(<span class="string">'./config/default.js'</span>);</span><br><span class="line"><span class="comment">// const cors = require('koa2-cors');</span></span><br><span class="line"><span class="keyword">const</span> middlewares = <span class="built_in">require</span>(<span class="string">'./middlewares/middlewares.js'</span>);</span><br><span class="line"><span class="keyword">const</span> app = <span class="keyword">new</span> Koa();</span><br><span class="line"><span class="comment">// 具体参数我们在后面进行解释</span></span><br><span class="line">app.use(cors(&#123;</span><br><span class="line">    origin: <span class="function"><span class="keyword">function</span> (<span class="params">ctx</span>) </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (ctx.url === <span class="string">'/test'</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="string">"*"</span>; <span class="comment">// 允许来自所有域名请求</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">'http://youstde.blog.com'</span>; <span class="comment">// 这样就能只允许localhost:8080 这个域名的请求了</span></span><br><span class="line">    &#125;,</span><br><span class="line">    exposeHeaders: [<span class="string">'WWW-Authenticate'</span>, <span class="string">'Server-Authorization'</span>],</span><br><span class="line">    maxAge: <span class="number">5</span>,</span><br><span class="line">    credentials: <span class="literal">true</span>,</span><br><span class="line">    allowMethods: [<span class="string">'GET'</span>, <span class="string">'POST'</span>, <span class="string">'DELETE'</span>],</span><br><span class="line">    allowHeaders: [<span class="string">'Content-Type'</span>, <span class="string">'Authorization'</span>, <span class="string">'Accept'</span>],</span><br><span class="line">&#125;));</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> main = <span class="keyword">async</span> ctx =&gt; &#123;</span><br><span class="line"><span class="comment">// ctx.cookies.set(</span></span><br><span class="line"> <span class="comment">//        'cid',</span></span><br><span class="line"> <span class="comment">//        'helloworld',</span></span><br><span class="line"> <span class="comment">//        &#123;</span></span><br><span class="line"> <span class="comment">//            domain: '127.0.0.1',</span></span><br><span class="line"> <span class="comment">//            path: '/',</span></span><br><span class="line"> <span class="comment">//            maxAge: 10 * 60 * 1000,</span></span><br><span class="line"> <span class="comment">//            expires: new Date('2017-02-15'),  // cookie失效时间</span></span><br><span class="line"> <span class="comment">//            httpOnly: false,  // 是否只用于http请求中获取</span></span><br><span class="line"> <span class="comment">//            overwrite: false  // 是否允许重写</span></span><br><span class="line"> <span class="comment">//        &#125;</span></span><br><span class="line"> <span class="comment">//    );</span></span><br><span class="line"> <span class="comment">//单页面应用的话，这个方法只会执行一次</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// app.use(require('./routers/article.js').routes());</span></span><br><span class="line">app.use(<span class="built_in">require</span>(<span class="string">'./routers/sign.js'</span>).routes());</span><br><span class="line">app.use(middlewares);</span><br><span class="line">app.listen(config.port,()=&gt;&#123;</span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">`app is listenning on <span class="subst">$&#123;config.port&#125;</span>`</span>);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><p>配置一下corse,这样之前的404就变成了200了</p><p><img src="http://ww1.sinaimg.cn/large/005QDhBjgy1fni8yj1ezfj30xu0ei0wa.jpg" alt=""></p><p>2.Nginx的反向代理</p><p>不是之前的那种做法，只是做api的拦截，然后重定向到指定地址</p><p>是给接口地址新开一个Nginx配置</p><p>至此，接口也从飘红的404变成了绿色的200了,很开心</p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">server</span>  &#123;</span><br><span class="line">      <span class="attribute">listen</span> <span class="number">80</span>;</span><br><span class="line">      <span class="attribute">server_name</span> youstde.blog.com;</span><br><span class="line"></span><br><span class="line">      <span class="attribute">location</span> / &#123;</span><br><span class="line">          <span class="attribute">proxy_set_header</span> X-Real-IP <span class="variable">$remote_addr</span>;</span><br><span class="line">          <span class="attribute">proxy_set_header</span> X-Forwarded-For <span class="variable">$proxy_add_x_forwarded_for</span>;</span><br><span class="line">          <span class="attribute">proxy_set_header</span> Host <span class="variable">$http_host</span>;</span><br><span class="line">          <span class="attribute">proxy_set_header</span> X-Nginx-Proxy <span class="literal">true</span>;</span><br><span class="line">          <span class="attribute">proxy_set_header</span> Connection <span class="string">""</span>;</span><br><span class="line">          <span class="attribute">proxy_pass</span> http://localhost:8080;</span><br><span class="line"></span><br><span class="line">       &#125;</span><br><span class="line">  &#125;</span><br><span class="line"> <span class="section">server</span>  &#123;</span><br><span class="line">      <span class="attribute">listen</span> <span class="number">80</span>;</span><br><span class="line">      <span class="attribute">server_name</span> api.youstde.blog.com;</span><br><span class="line"></span><br><span class="line">      <span class="attribute">location</span> / &#123;</span><br><span class="line">          <span class="attribute">add_header</span> <span class="string">'Access-Control-Allow-Origin'</span> <span class="string">'http://youstde.blog.com'</span>;</span><br><span class="line">          <span class="attribute">add_header</span> <span class="string">'Access-Control-Allow-Credentials'</span> <span class="string">'true'</span>;</span><br><span class="line">          <span class="attribute">add_header</span> <span class="string">'Access-Control-Allow-Methods'</span> <span class="string">'GET,POST,OPTIONS'</span>;</span><br><span class="line">          <span class="attribute">proxy_set_header</span> X-Real-IP <span class="variable">$remote_addr</span>;</span><br><span class="line">          <span class="attribute">proxy_set_header</span> X-Forwarded-For <span class="variable">$proxy_add_x_forwarded_for</span>;</span><br><span class="line">          <span class="attribute">proxy_set_header</span> Host <span class="variable">$http_host</span>;</span><br><span class="line">          <span class="attribute">proxy_set_header</span> X-Nginx-Proxy <span class="literal">true</span>;</span><br><span class="line">          <span class="attribute">proxy_set_header</span> Connection <span class="string">""</span>;</span><br><span class="line">          <span class="attribute">proxy_pass</span> http://localhost:7001;</span><br><span class="line"></span><br><span class="line">       &#125;</span><br><span class="line"></span><br><span class="line">  &#125;</span><br></pre></td></tr></table></figure><h2 id="补充两点："><a href="#补充两点：" class="headerlink" title="补充两点："></a><code>补充两点：</code></h2><p>1.路径重写</p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">location</span><span class="regexp"> ^~/cross_origin/</span> &#123;</span><br><span class="line">  <span class="comment">#重写路径</span></span><br><span class="line">  <span class="attribute">rewrite</span><span class="regexp"> ^/cross_origin/(.*)$</span> /<span class="variable">$1</span> <span class="literal">break</span>;</span><br><span class="line">  <span class="attribute">proxy_pass</span> http://127.0.0.1:7001/;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>location配置的意思是对包含 “cross_origin” 请求拦截，并对请求路径进行重写，一开始请求路径是<br>“/cross_origin/get_json?type=20170126” ，重写后便成了<br>“/get_json?type=20170126”，$1代表（.<em>）中的内容，而（.</em>）则代表 cross_origin<br>后面的全部字符，也就是我们会把 cross_origin 部分去掉，但是保留 cross_origin 之后的所有字符</p><p>2.反向代理的时候的POST请求</p><p>我用的是axios去做请求处理，但是发送post请求的时候出现了这个情况</p><p><img src="http://ww1.sinaimg.cn/large/005QDhBjgy1fnib3wy8a3j31iq0n4q9k.jpg" alt=""></p><p>很显然是发送了一个预请求，因为不是一个简单的请求</p><p>首先我们得了解什么是简单请求和非简单请求</p><p><a href="https://segmentfault.com/a/1190000000709909" target="_blank" rel="noopener">文章看这里</a></p><p>而且关于axios中如何去设置</p><p><a href="https://github.com/axios/axios#using-applicationx-www-form-urlencoded-format" target="_blank" rel="noopener">看这里</a></p><p><img src="http://ww1.sinaimg.cn/large/005QDhBjgy1fnibczvrhmj31g60tcq9f.jpg" alt=""></p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h2 id=&quot;写在前面&quot;&gt;&lt;a href=&quot;#写在前面&quot; class=&quot;headerlink&quot; title=&quot;写在前面&quot;&gt;&lt;/a&gt;&lt;code&gt;写在前面&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;http://blog.csdn.net/cjd6568358/article/
      
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>上拉加载更多的实现</title>
    <link href="http://yoursite.com/2017/12/28/%E4%B8%8A%E6%8B%89%E5%8A%A0%E8%BD%BD%E6%9B%B4%E5%A4%9A%E7%9A%84%E5%AE%9E%E7%8E%B0/"/>
    <id>http://yoursite.com/2017/12/28/上拉加载更多的实现/</id>
    <published>2017-12-28T06:31:55.000Z</published>
    <updated>2018-10-24T03:26:04.175Z</updated>
    
    <content type="html"><![CDATA[<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//获取滚动条当前的位置</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">getScrollTop</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> scrollTop = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">if</span> (<span class="built_in">document</span>.documentElement &amp;&amp; <span class="built_in">document</span>.documentElement.scrollTop) &#123;</span><br><span class="line">        scrollTop = <span class="built_in">document</span>.documentElement.scrollTop;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">if</span> (<span class="built_in">document</span>.body) &#123;</span><br><span class="line">        scrollTop = <span class="built_in">document</span>.body.scrollTop;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> scrollTop;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//获取当前可视范围的高度</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">getClientHeight</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> clientHeight = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">if</span> (<span class="built_in">document</span>.body.clientHeight &amp;&amp; <span class="built_in">document</span>.documentElement.clientHeight) &#123;</span><br><span class="line">        clientHeight = <span class="built_in">Math</span>.min(<span class="built_in">document</span>.body.clientHeight, <span class="built_in">document</span>.documentElement.clientHeight);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span> &#123;</span><br><span class="line">        clientHeight = <span class="built_in">Math</span>.max(<span class="built_in">document</span>.body.clientHeight, <span class="built_in">document</span>.documentElement.clientHeight);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> clientHeight;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//获取文档完整的高度</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">getScrollHeight</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">Math</span>.max(<span class="built_in">document</span>.body.scrollHeight, <span class="built_in">document</span>.documentElement.scrollHeight);</span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">window</span>.onscroll = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (getScrollTop() + getClientHeight() == getScrollHeight()) &#123;</span><br><span class="line">        <span class="comment">//ajax从这里开始</span></span><br><span class="line">        $.ajax(&#123;</span><br><span class="line">            type: <span class="string">'GET'</span>,</span><br><span class="line">            url: pageHost + <span class="string">'/api/public/spider/article/paging'</span>,</span><br><span class="line">            dataType: <span class="string">'jsonp'</span>,</span><br><span class="line">            success: <span class="function"><span class="keyword">function</span> (<span class="params">data</span>) </span>&#123;</span><br><span class="line">               </span><br><span class="line">            &#125;,</span><br><span class="line">            error: <span class="function"><span class="keyword">function</span> (<span class="params">xhr, type</span>) </span>&#123;</span><br><span class="line">                <span class="built_in">console</span>.log(<span class="string">'Ajax error!'</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      
      
        &lt;figure class=&quot;highlight javascript&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span 
      
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>使用webpack的require.context实现路由“去中心化”管理(转载)</title>
    <link href="http://yoursite.com/2017/12/01/require-context/"/>
    <id>http://yoursite.com/2017/12/01/require-context/</id>
    <published>2017-12-01T09:05:42.000Z</published>
    <updated>2018-10-24T03:26:04.162Z</updated>
    
    <content type="html"><![CDATA[<h2 id="一个项目中路由的变化过程"><a href="#一个项目中路由的变化过程" class="headerlink" title="一个项目中路由的变化过程"></a><code>一个项目中路由的变化过程</code></h2><p>当你在开发一个大型单页面应用的时候，项目之初一般做法是所有的路由规则都维护在一个<code>route.js</code>的文件里。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// rootRoute.js</span></span><br><span class="line"><span class="keyword">const</span> rootRoute = &#123;</span><br><span class="line">    childRoutes: [</span><br><span class="line">        &#123;</span><br><span class="line">            path: <span class="string">'/'</span>,</span><br><span class="line">            component: AppLayout,</span><br><span class="line">            childRoutes: [</span><br><span class="line">                &#123;</span><br><span class="line">                    path: <span class="string">'shop'</span>, <span class="comment">// 购买详情页</span></span><br><span class="line">                    component: Shop</span><br><span class="line">                &#125;,</span><br><span class="line">                &#123;</span><br><span class="line">                    path: <span class="string">'order'</span>, <span class="comment">// 订单页</span></span><br><span class="line">                    component: Order</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="comment">// ...</span></span><br><span class="line">                <span class="comment">// 少量其他路由</span></span><br><span class="line">                <span class="comment">// ...</span></span><br><span class="line">            ]</span><br><span class="line">        &#125;</span><br><span class="line">    ]</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p><strong>随着业务代码的增长路由很快会变成：</strong></p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// rootRoute.js</span></span><br><span class="line"><span class="keyword">const</span> rootRoute = &#123;</span><br><span class="line">    childRoutes: [</span><br><span class="line">        &#123;</span><br><span class="line">            path: <span class="string">'/'</span>,</span><br><span class="line">            component: AppLayout,</span><br><span class="line">            childRoutes: [</span><br><span class="line">                &#123;</span><br><span class="line">                    path: <span class="string">'shop'</span>, <span class="comment">// 购买详情页</span></span><br><span class="line">                    component: ShopLayout,</span><br><span class="line">                    childRoutes: [</span><br><span class="line">                        &#123;</span><br><span class="line">                            path: <span class="string">'foodDetail'</span>,</span><br><span class="line">                            component: FoodDetail</span><br><span class="line">                        &#125;,</span><br><span class="line">                        &#123;</span><br><span class="line">                            path: <span class="string">'shoesDetail'</span>,</span><br><span class="line">                            component: ShoesDetail</span><br><span class="line">                        &#125;</span><br><span class="line">                        <span class="comment">// 其他</span></span><br><span class="line">                    ]</span><br><span class="line">                &#125;,</span><br><span class="line">                &#123;</span><br><span class="line">                    path: <span class="string">'order'</span>, <span class="comment">// 订单页</span></span><br><span class="line">                    component: Order,</span><br><span class="line">                    childRoutes: [</span><br><span class="line">                        &#123;</span><br><span class="line">                            path: <span class="string">'remark'</span>, <span class="comment">//订单备注</span></span><br><span class="line">                            component: Remark</span><br><span class="line">                        &#125;,</span><br><span class="line">                        &#123;</span><br><span class="line">                            path: <span class="string">'invoice'</span>, <span class="comment">//发票抬头</span></span><br><span class="line">                            component: Invoice</span><br><span class="line">                        &#125;,</span><br><span class="line">                        &#123;</span><br><span class="line">                            path: <span class="string">'payment'</span>, <span class="comment">//付款页面</span></span><br><span class="line">                            component: Payment</span><br><span class="line">                        &#125;,</span><br><span class="line">                        &#123;</span><br><span class="line">                            path: <span class="string">'userValidation'</span>, <span class="comment">//用户验证</span></span><br><span class="line">                            component: UserValidation</span><br><span class="line">                        &#125;,</span><br><span class="line">                        &#123;</span><br><span class="line">                            path: <span class="string">'chooseAddress'</span>, <span class="comment">//选择地址</span></span><br><span class="line">                            component: ChooseAddress,</span><br><span class="line">                            childRoutes: [</span><br><span class="line">                                &#123;</span><br><span class="line">                                    path: <span class="string">'addAddress'</span>, <span class="comment">//添加地址</span></span><br><span class="line">                                    component: AddAddress,</span><br><span class="line">                                    childRoutes: [</span><br><span class="line">                                        &#123;</span><br><span class="line">                                            path: <span class="string">'searchAddress'</span>, <span class="comment">//搜索地址</span></span><br><span class="line">                                            component: SearchAddress</span><br><span class="line">                                        &#125;</span><br><span class="line">                                    ]</span><br><span class="line">                                &#125;</span><br><span class="line">                            ]</span><br><span class="line">                        &#125;</span><br><span class="line">                    ]</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="comment">// ...</span></span><br><span class="line">                <span class="comment">// 大量新增路由</span></span><br><span class="line">                <span class="comment">// ...</span></span><br><span class="line">            ]</span><br><span class="line">        &#125;</span><br><span class="line">    ]</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p><strong>当路由变的越来越大，大到已经难以维护时。我们按照react-router提供的思路，对路由按业务模块进行拆分。</strong></p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// rootRoute.js</span></span><br><span class="line"><span class="keyword">const</span> rootRoute = &#123;</span><br><span class="line">    childRoutes: [</span><br><span class="line">        &#123;</span><br><span class="line">            path: <span class="string">'/'</span>,</span><br><span class="line">            component: AppLayout,</span><br><span class="line">            childRoutes: [</span><br><span class="line">                <span class="built_in">require</span>(<span class="string">'./modules/shop/route'</span>), <span class="comment">//购买详情页</span></span><br><span class="line">                <span class="built_in">require</span>(<span class="string">'./modules/order/route'</span>), <span class="comment">// 订单页</span></span><br><span class="line">                <span class="built_in">require</span>(<span class="string">'./modules/login/route'</span>), <span class="comment">// 登录注册页</span></span><br><span class="line">                <span class="built_in">require</span>(<span class="string">'./modules/service/route'</span>), <span class="comment">// 服务中心</span></span><br><span class="line">                <span class="comment">// ...</span></span><br><span class="line">                <span class="comment">// 其他大量新增路由</span></span><br><span class="line">                <span class="comment">// ...</span></span><br><span class="line">            ]</span><br><span class="line">        &#125;</span><br><span class="line">    ]</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>按该方式拆分后，每个业务模块维护自身的路由配置。新增业务模块路由，只需要在总的rootRoute中引入该业务模块的路由即可（<strong>也就是加一行代码</strong>）。这个方案看来是已经接近完美了。<strong>但如果想达到连一行代码都不用加？实现彻彻底底的去中心化管理</strong></p><h2 id="require-context是什么？"><a href="#require-context是什么？" class="headerlink" title="require.context是什么？"></a><code>require.context是什么？</code></h2><p>想要彻彻底底的实现去中心化管理我们需要使用到require.context</p><blockquote><p>webpack官方文档的介绍<a href="https://webpack.js.org/guides/dependency-management/#require-context" target="_blank" rel="noopener">require.context</a></p></blockquote><p>简单说就是：有了require.context，我们可以通过正则匹配引入相应的文件模块。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">require.context(directory, useSubdirectories, regExp)</span><br></pre></td></tr></table></figure><p>require.context有三个参数：</p><ul><li>directory：说明需要检索的目录</li><li>useSubdirectories：是否检索子目录</li><li>regExp: 匹配文件的正则表达式</li></ul><p>使用require.context改造后的rootRoute.js文件</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> rootRoute = &#123;</span><br><span class="line">    childRoutes: [</span><br><span class="line">        &#123;</span><br><span class="line">            path: <span class="string">'/'</span>,</span><br><span class="line">            component: AppLayout,</span><br><span class="line">            childRoutes: (<span class="function"><span class="params">r</span> =&gt;</span> &#123;</span><br><span class="line">                <span class="keyword">return</span> r.keys().map(<span class="function"><span class="params">key</span> =&gt;</span> r(key));</span><br><span class="line">            &#125;)(<span class="built_in">require</span>.context(<span class="string">'./'</span>, <span class="literal">true</span>, /^\.\/modules\/((?!\/)[\s\S])+\/route\.js$/))</span><br><span class="line">        &#125;</span><br><span class="line">    ]</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>优化后，新增一个业务模块，只要业务模块route文件遵循统一的目录结构。业务模块route就能被自动关联到rootRoute里。</p><p><a href="https://github.com/wuchangming/blog/tree/master/code/require-context-usage/route-demo" target="_blank" rel="noopener">查看示例代码</a></p><h3 id="其他应用场景"><a href="#其他应用场景" class="headerlink" title="其他应用场景"></a>其他应用场景</h3><p>这个思路可应用于其他想要实现”去中心化”管理的功能模块。</p><ul><li>模块化管理reducer</li></ul>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h2 id=&quot;一个项目中路由的变化过程&quot;&gt;&lt;a href=&quot;#一个项目中路由的变化过程&quot; class=&quot;headerlink&quot; title=&quot;一个项目中路由的变化过程&quot;&gt;&lt;/a&gt;&lt;code&gt;一个项目中路由的变化过程&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;当你在开发一个大型单页面应用的时候
      
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>vue系列之componet的全局注册和use</title>
    <link href="http://yoursite.com/2017/12/01/vue%E7%B3%BB%E5%88%97%E4%B9%8Bcomponet%E7%9A%84%E5%85%A8%E5%B1%80%E6%B3%A8%E5%86%8C%E5%92%8Cuse/"/>
    <id>http://yoursite.com/2017/12/01/vue系列之componet的全局注册和use/</id>
    <published>2017-12-01T06:25:51.000Z</published>
    <updated>2018-10-24T03:26:04.169Z</updated>
    
    <content type="html"><![CDATA[<h2 id="写在前面"><a href="#写在前面" class="headerlink" title="写在前面"></a><code>写在前面</code></h2><p>我现在写了一个组件svgIcon，想注册为一个全局组件，我只说我平时用的一种：<code>Vue.component(&#39;svg-icon&#39;, SvgIcon)</code>，这样我们就可以在任何组件里直接使用就可以了，而不需要再在每个需要用到该组件的地方引入了。</p><h2 id="vue-use"><a href="#vue-use" class="headerlink" title="vue.use()"></a><code>vue.use()</code></h2><p>平时我们需要用到别人的插件，首先是<code>install</code>，然后在主JS中（main.js）中引入，然后使用<code>vue.use(插件)</code>挂载一下就可以使用了。</p><p>webpack首先会加载main.js，所以我们在main的js里面引入。我以element ui来做对比说明</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">import Vue from &apos;vue&apos;</span><br><span class="line">import App from &apos;./App.vue&apos;</span><br><span class="line"> </span><br><span class="line">// 引入element-ui组件</span><br><span class="line">import ElementUi from &apos;element-ui&apos;</span><br><span class="line">import &apos;element-ui/lib/theme-default/index.css&apos;</span><br><span class="line"> </span><br><span class="line">// 引入自定义组件。index.js是组件的默认入口</span><br><span class="line">import Loading from &apos;../components/loading&apos;</span><br><span class="line">Vue.use(Loading);</span><br><span class="line"> </span><br><span class="line">Vue.use(ElementUi);</span><br><span class="line">new Vue(&#123;</span><br><span class="line"> el: &apos;#app&apos;,</span><br><span class="line"> render: h =&gt; h(App)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure><p>然后在Loading.vue里面定义自己的组件模板</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">&lt;!-- 这里和普通组件的书写一样 --&gt;</span><br><span class="line">&lt;template&gt;</span><br><span class="line">  &lt;div class=&quot;loading&quot;&gt;</span><br><span class="line">    loading...</span><br><span class="line">  &lt;/div&gt;</span><br><span class="line">&lt;/template&gt;</span><br></pre></td></tr></table></figure><p>在index.js文件里面添加install方法</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> MyLoading <span class="keyword">from</span> <span class="string">'./Loading.vue'</span></span><br><span class="line"><span class="comment">// 这里是重点</span></span><br><span class="line"><span class="keyword">const</span> Loading = &#123;</span><br><span class="line">  install: <span class="function"><span class="keyword">function</span>(<span class="params">Vue</span>)</span>&#123;</span><br><span class="line">    Vue.component(<span class="string">'Loading'</span>,MyLoading)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"> </span><br><span class="line"><span class="comment">// 导出组件</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> Loading</span><br></pre></td></tr></table></figure><p>接下来就是在App.Vue里面使用组件了，这个组件已经在main.js定义加载了</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">&lt;template&gt;</span><br><span class="line"> &lt;div id=&quot;app&quot;&gt;</span><br><span class="line"> &lt;!-- 使用element ui的组件 --&gt;</span><br><span class="line"> &lt;el-button&gt;默认按钮&lt;/el-button&gt;</span><br><span class="line"> </span><br><span class="line"> &lt;!-- 使用自定义组件 --&gt;</span><br><span class="line"> &lt;Loading&gt;&lt;/Loading&gt;</span><br><span class="line"> &lt;/div&gt;</span><br><span class="line">&lt;/template&gt;</span><br></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h2 id=&quot;写在前面&quot;&gt;&lt;a href=&quot;#写在前面&quot; class=&quot;headerlink&quot; title=&quot;写在前面&quot;&gt;&lt;/a&gt;&lt;code&gt;写在前面&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;我现在写了一个组件svgIcon，想注册为一个全局组件，我只说我平时用的一种：&lt;code&gt;Vue.
      
    
    </summary>
    
    
  </entry>
  
</feed>
