<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Welcome to My Blog</title>
  
  
  <link href="/atom.xml" rel="self"/>
  
  <link href="https://ascodelife.github.io/"/>
  <updated>2020-07-22T09:19:58.986Z</updated>
  <id>https://ascodelife.github.io/</id>
  
  <author>
    <name>John Doe</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>学习笔记——布局系列（一）</title>
    <link href="https://ascodelife.github.io/2020/07/16/layout1/"/>
    <id>https://ascodelife.github.io/2020/07/16/layout1/</id>
    <published>2020-07-16T09:28:42.924Z</published>
    <updated>2020-07-22T09:19:58.986Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>本系列文章主要针对了常用的几种css布局进行需求分析与要点详解，后续将不断对布局实现方案进行补充。本文主要介绍了水平居中、垂直居中和水平+垂直居中布局方案。</p><a id="more"></a><h2 id="1-水平居中"><a href="#1-水平居中" class="headerlink" title="1.水平居中"></a>1.水平居中</h2><p>首先分析最简单的水平居中，基本布局如下，两个div的嵌套。需要实现的是子div相对父div水平居中。</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">class</span>=<span class="string">"parent"</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">"child"</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>&gt;</span></span><br></pre></td></tr></table></figure><h3 id="1-1-方案一"><a href="#1-1-方案一" class="headerlink" title="1.1 方案一"></a>1.1 方案一</h3><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><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="selector-class">.parent</span>&#123;</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">100px</span>;</span><br><span class="line">   <span class="attribute">height</span>:<span class="number">100px</span>;</span><br><span class="line">    <span class="attribute">text-align</span>:center;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-class">.child</span>&#123;</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">50px</span>;</span><br><span class="line">    <span class="attribute">height</span>:<span class="number">50px</span>;</span><br><span class="line">    <span class="attribute">display</span>:inline-block;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>这个方案十分简单，MDN中的描述是，<code>text-align</code>控制<strong>行内内容</strong>如何相对它的块父元素对齐。</p><p>而将子div渲染成一个<code>inline-block</code>盒子可以保证它在父元素中的布局受<code>text-align</code>且能直接修改他的宽高属性。</p><p>优点：兼容性高，实现简单。</p><p>缺点：所有行内元素都会受<code>text-align</code>的影响而居中；且它是一个可继承的属性，若不想影响到更深层级的元素，需要在子元素中重新设置<code>text-align</code>属性。</p><h3 id="1-2-方案二"><a href="#1-2-方案二" class="headerlink" title="1.2 方案二"></a>1.2 方案二</h3><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><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="selector-class">.parent</span>&#123;</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">100px</span>;</span><br><span class="line">   <span class="attribute">height</span>:<span class="number">100px</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-class">.child</span>&#123;</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">50px</span>;</span><br><span class="line">    <span class="attribute">height</span>:<span class="number">50px</span>;</span><br><span class="line">    <span class="attribute">margin</span>:<span class="number">0</span> auto;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>这个方案也很简单，当左右外边距为<code>auto</code>时，会自动分配父元素剩余宽度均分到左右边距中。注意：此时子元素不能是行内元素，否则<code>margin</code>属性是不会生效的。</p><p>优点：兼容性高，实现简单。</p><p>缺点：没有很明显的缺点，如果要说，那就是如果子元素脱离了文档流，那么<code>margin</code>属性会失效。</p><h3 id="1-3-方案三（不推荐）"><a href="#1-3-方案三（不推荐）" class="headerlink" title="1.3 方案三（不推荐）"></a>1.3 方案三（不推荐）</h3><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><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></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.parent</span>&#123;</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">100px</span>;</span><br><span class="line">   <span class="attribute">height</span>:<span class="number">100px</span>;</span><br><span class="line">    <span class="attribute">position</span>:relative;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-class">.child</span>&#123;</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">50px</span>;</span><br><span class="line">    <span class="attribute">height</span>:<span class="number">50px</span>;</span><br><span class="line">    <span class="attribute">position</span>:absolute;</span><br><span class="line">    <span class="attribute">left</span>:<span class="number">50%</span>;</span><br><span class="line">    <span class="attribute">transform</span>:<span class="built_in">translateX</span>(-<span class="number">50%</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><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><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="selector-class">.parent</span>&#123;</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">100px</span>;</span><br><span class="line">   <span class="attribute">height</span>:<span class="number">100px</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-class">.child</span>&#123;</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">50px</span>;</span><br><span class="line">    <span class="attribute">height</span>:<span class="number">50px</span>;</span><br><span class="line">    <span class="attribute">position</span>:relative;</span><br><span class="line">    <span class="attribute">left</span>:<span class="number">50%</span>;</span><br><span class="line">    <span class="attribute">transform</span>:<span class="built_in">translateX</span>(-<span class="number">50%</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>这个方案较前面两个更为复杂，给人一种杀鸡焉用宰牛刀的感觉。强烈不推荐使用。</p><p>优点：没有明显的优点。</p><p>缺点：较复杂，使用相对布局和绝对布局反而会留下更大的隐患；<code>transform</code>属性兼容性不强。</p><h3 id="1-4-方案四（flex-grid）"><a href="#1-4-方案四（flex-grid）" class="headerlink" title="1.4 方案四（flex/grid）"></a>1.4 方案四（flex/grid）</h3><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><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="selector-class">.parent</span>&#123;</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">100px</span>;</span><br><span class="line">   <span class="attribute">height</span>:<span class="number">100px</span>;</span><br><span class="line">    <span class="attribute">display</span>:flex;</span><br><span class="line">    <span class="comment">/*display:grid;*/</span></span><br><span class="line">    <span class="attribute">justify-content</span>:center;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-class">.child</span>&#123;</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">50px</span>;</span><br><span class="line">    <span class="attribute">height</span>:<span class="number">50px</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>父元素使用<code>flex</code>（<code>grid</code>）布局并设置主轴上（网格行轴）元素的排列方式为居中来实现水平居中，会带来一个问题就是主轴（网格行轴）上所有子元素都会居中。</p><p>优点：实现简单。</p><p>缺点：兼容性不强。</p><h2 id="2-垂直居中"><a href="#2-垂直居中" class="headerlink" title="2.垂直居中"></a>2.垂直居中</h2><p>下面分析稍微复杂一些的垂直居中，基本布局同水平居中。需要实现的是子div相对父div垂直居中。</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">class</span>=<span class="string">"parent"</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">"child"</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>&gt;</span></span><br></pre></td></tr></table></figure><h3 id="2-1-方案一"><a href="#2-1-方案一" class="headerlink" title="2.1 方案一"></a>2.1 方案一</h3><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><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="selector-class">.parent</span>&#123;</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">100px</span>;</span><br><span class="line">   <span class="attribute">height</span>:<span class="number">100px</span>;</span><br><span class="line">    <span class="attribute">display</span>:table-cell;</span><br><span class="line">    <span class="attribute">vertical-align</span>:middle;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-class">.child</span>&#123;</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">50px</span>;</span><br><span class="line">    <span class="attribute">height</span>:<span class="number">50px</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>根据MDN的描述，<code>table-cell</code>让一个元素表现为像<code>&lt;td&gt;</code>元素一样，也就是一个单元格。然后我们使用<code>vertical-align</code>属性来指定单元格内元素的垂直对齐方式。（这里涨姿势了，原来<code>vertical-align</code>不仅能用来指定行内元素（inline）也能用来指定表格单元格（table-cell）元素的垂直对齐方式。）</p><p>优点：兼容性比较好。</p><p>缺点：为了实现垂直居中效果而把父元素变成一个单元格，从语义上来看很不友好；<code>vertical-align</code>属性也是具有继承性，同上<code>text-align</code>。</p><h3 id="2-2-方案二"><a href="#2-2-方案二" class="headerlink" title="2.2 方案二"></a>2.2 方案二</h3><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><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></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.parent</span>&#123;</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">100px</span>;</span><br><span class="line">   <span class="attribute">height</span>:<span class="number">100px</span>;</span><br><span class="line">    <span class="attribute">position</span>:relative;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-class">.child</span>&#123;</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">50px</span>;</span><br><span class="line">    <span class="attribute">height</span>:<span class="number">50px</span>;</span><br><span class="line">    <span class="attribute">position</span>:absolute;</span><br><span class="line">    <span class="attribute">top</span>:<span class="number">50%</span>;</span><br><span class="line">    <span class="attribute">transform</span>:<span class="built_in">translateY</span>(-<span class="number">50%</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><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><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="selector-class">.parent</span>&#123;</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">100px</span>;</span><br><span class="line">   <span class="attribute">height</span>:<span class="number">100px</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-class">.child</span>&#123;</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">50px</span>;</span><br><span class="line">    <span class="attribute">height</span>:<span class="number">50px</span>;</span><br><span class="line">    <span class="attribute">position</span>:relative;</span><br><span class="line">    <span class="attribute">top</span>:<span class="number">50%</span>;</span><br><span class="line">    <span class="attribute">transform</span>:<span class="built_in">translateY</span>(-<span class="number">50%</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>类似水平居中的方案二，也是比较常见的一种实现方式。</p><p>优点：没有明显的优点。</p><p>缺点：<code>transform</code>兼容性不强。需要使用相对布局和绝对布局实现。</p><h3 id="2-3-方案三-（较推荐）"><a href="#2-3-方案三-（较推荐）" class="headerlink" title="2.3 方案三 （较推荐）"></a>2.3 方案三 （较推荐）</h3><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><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></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.parent</span>&#123;</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">100px</span>;</span><br><span class="line">   <span class="attribute">height</span>:<span class="number">100px</span>;</span><br><span class="line">    <span class="attribute">position</span>:relative;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-class">.child</span>&#123;</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">50px</span>;</span><br><span class="line">    <span class="attribute">height</span>:<span class="number">50px</span>;</span><br><span class="line">    <span class="attribute">position</span>:absolute;</span><br><span class="line">    <span class="attribute">top</span>:<span class="number">0</span>;</span><br><span class="line">    <span class="attribute">bottom</span>:<span class="number">0</span>;</span><br><span class="line">    <span class="attribute">margin</span>:auto <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>具体解析我打算放到水平+垂直居中的方案三中去说，这里先吊个胃口。比起方案二，方案三没有了```transform``属性，兼容性更好。</p><p>优点：兼容性好。</p><p>缺点：需要使用相对布局和绝对布局实现。</p><h3 id="2-4-方案四（flex-grid）"><a href="#2-4-方案四（flex-grid）" class="headerlink" title="2.4 方案四（flex/grid）"></a>2.4 方案四（flex/grid）</h3><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><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="selector-class">.parent</span>&#123;</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">100px</span>;</span><br><span class="line">   <span class="attribute">height</span>:<span class="number">100px</span>;</span><br><span class="line">    <span class="attribute">display</span>:flex;</span><br><span class="line">    <span class="comment">/*display:grid;*/</span></span><br><span class="line">    <span class="attribute">align-items</span>:center;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-class">.child</span>&#123;</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">50px</span>;</span><br><span class="line">    <span class="attribute">height</span>:<span class="number">50px</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>父元素使用<code>flex</code>（<code>grid</code>）布局并设置项目在其包含块中在交叉轴（块轴）上的对齐方式为居中，会带来一个问题就是交叉轴（块轴）上所有项目都会居中。</p><p>优点：实现简单。</p><p>缺点：兼容性不强。</p><h2 id="3-水平-垂直居中"><a href="#3-水平-垂直居中" class="headerlink" title="3.水平+垂直居中"></a>3.水平+垂直居中</h2><p>理论上，是不是把上面的水平居中和垂直居中全部排列组合一遍就可以得到NxM种方案？当然不是，这里也不浪费时间去做组合，直接给出一些可行的方案。同样，基本布局如下。需要实现的是子div相对父div水平+垂直居中。</p><h3 id="3-1-方案一"><a href="#3-1-方案一" class="headerlink" title="3.1 方案一"></a>3.1 方案一</h3><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><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="selector-class">.parent</span>&#123;</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">100px</span>;</span><br><span class="line">   <span class="attribute">height</span>:<span class="number">100px</span>;</span><br><span class="line">    <span class="attribute">display</span>:table-cell;</span><br><span class="line">    <span class="attribute">vertical-align</span>:middle;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-class">.child</span>&#123;</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">50px</span>;</span><br><span class="line">    <span class="attribute">height</span>:<span class="number">50px</span>;</span><br><span class="line">    <span class="attribute">margin</span>:<span class="number">0</span> auto;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>该方案为水平居中方案一和垂直居中方案一的组合，也同样继承了它们的缺点和优点。同样的子元素不能是行内元素。</p><p>优点：兼容性好。</p><p>缺点：语义。</p><h3 id="3-2-方案二"><a href="#3-2-方案二" class="headerlink" title="3.2 方案二"></a>3.2 方案二</h3><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><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></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.parent</span>&#123;</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">100px</span>;</span><br><span class="line">   <span class="attribute">height</span>:<span class="number">100px</span>;</span><br><span class="line">    <span class="attribute">position</span>:relative;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-class">.child</span>&#123;</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">50px</span>;</span><br><span class="line">    <span class="attribute">height</span>:<span class="number">50px</span>;</span><br><span class="line">    <span class="attribute">position</span>:absolute;</span><br><span class="line">    <span class="attribute">top</span>:<span class="number">50%</span>;</span><br><span class="line">    <span class="attribute">left</span>:<span class="number">50%</span>;</span><br><span class="line">    <span class="attribute">transform</span>:<span class="built_in">translate</span>(-<span class="number">50%</span>,-<span class="number">50%</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><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><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></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.parent</span>&#123;</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">100px</span>;</span><br><span class="line">   <span class="attribute">height</span>:<span class="number">100px</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-class">.child</span>&#123;</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">50px</span>;</span><br><span class="line">    <span class="attribute">height</span>:<span class="number">50px</span>;</span><br><span class="line">    <span class="attribute">position</span>:relative;</span><br><span class="line">    <span class="attribute">top</span>:<span class="number">50%</span>;</span><br><span class="line">    <span class="attribute">left</span>:<span class="number">50%</span>;</span><br><span class="line">    <span class="attribute">transform</span>:<span class="built_in">translate</span>(-<span class="number">50%</span>,-<span class="number">50%</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>该方案为水平居中方案二和垂直居中方案二的组合。</p><p>优点：能用就行。</p><p>缺点：<code>transform</code>兼容性不强。需要使用相对布局和绝对布局实现。</p><h3 id="3-3-方案三（推荐）"><a href="#3-3-方案三（推荐）" class="headerlink" title="3.3 方案三（推荐）"></a>3.3 方案三（推荐）</h3><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><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="selector-class">.parent</span>&#123;</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">100px</span>;</span><br><span class="line">   <span class="attribute">height</span>:<span class="number">100px</span>;</span><br><span class="line">    <span class="attribute">position</span>:relative;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-class">.child</span>&#123;</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">50px</span>;</span><br><span class="line">    <span class="attribute">height</span>:<span class="number">50px</span>;</span><br><span class="line">    <span class="attribute">position</span>:absolute;</span><br><span class="line">    <span class="attribute">top</span>:<span class="number">0</span>;</span><br><span class="line">    <span class="attribute">bottom</span>:<span class="number">0</span>;</span><br><span class="line">    <span class="attribute">left</span>:<span class="number">0</span>;</span><br><span class="line">    <span class="attribute">right</span>:<span class="number">0</span>;</span><br><span class="line">    <span class="attribute">margin</span>:auto;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>这个方法并不是我原创的，而是在《CSS世界》中强烈推荐的一种方法。其核心就在于掌握<strong>格式化宽高</strong>的计算公式。</p><blockquote><p>父元素的宽 = 子元素left + 子元素right + 子元素左右margin  + 子元素左右border + 子元素左右padding + 子元素宽</p><p>父元素高 = 子元素top + 子元素bottom + 子元素上下margin  + 子元素上下border + 子元素上下padding + 子元素高</p></blockquote><p>因此，当子元素top/right/bottom/left、border、padding、宽高都确定时，<code>margin:auto</code>会将剩余父元素空间均分，达到居中的效果。</p><p>优点：兼容性好。</p><p>缺点：依然需要使用相对布局和绝对布局实现。</p><h3 id="3-4-方案四（flex-grid）"><a href="#3-4-方案四（flex-grid）" class="headerlink" title="3.4 方案四（flex/grid）"></a>3.4 方案四（flex/grid）</h3><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><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></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.parent</span>&#123;</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">100px</span>;</span><br><span class="line">   <span class="attribute">height</span>:<span class="number">100px</span>;</span><br><span class="line">    <span class="attribute">display</span>:flex;</span><br><span class="line">    <span class="comment">/*display:grid;*/</span></span><br><span class="line">    <span class="attribute">justify-content</span>:center;</span><br><span class="line">    <span class="attribute">align-items</span>:center;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-class">.child</span>&#123;</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">50px</span>;</span><br><span class="line">    <span class="attribute">height</span>:<span class="number">50px</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>这个方法综合了1.4和2.4，，会带来一个问题就是所有项目都会水平且垂直居中。</p><p>优点：实现简单。</p><p>缺点：兼容性不强。</p><h2 id="后记"><a href="#后记" class="headerlink" title="后记"></a>后记</h2><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;/h2&gt;&lt;p&gt;本系列文章主要针对了常用的几种css布局进行需求分析与要点详解，后续将不断对布局实现方案进行补充。本文主要介绍了水平居中、垂直居中和水平+垂直居中布局方案。&lt;/p&gt;
    
    </summary>
    
    
      <category term="front-end" scheme="https://ascodelife.github.io/categories/front-end/"/>
    
    
      <category term="学习笔记" scheme="https://ascodelife.github.io/tags/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
    
      <category term="css" scheme="https://ascodelife.github.io/tags/css/"/>
    
      <category term="布局" scheme="https://ascodelife.github.io/tags/%E5%B8%83%E5%B1%80/"/>
    
  </entry>
  
  <entry>
    <title>学习笔记——防抖与节流实例</title>
    <link href="https://ascodelife.github.io/2020/07/15/debounceAndThrottle/"/>
    <id>https://ascodelife.github.io/2020/07/15/debounceAndThrottle/</id>
    <published>2020-07-15T09:34:55.667Z</published>
    <updated>2020-12-09T11:58:43.147Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>前前后后看了很多关于防抖和节流的文章，一直没有编程总结。防抖和节流其实比较类似，都是闭包的简单应用。前者关键在于用户频繁进行多次操作时，只响应一次；后者关键在于控制操作的频率。下次将列举出关键函数代码与实际运用例子。</p><a id="more"></a><h2 id="防抖"><a href="#防抖" class="headerlink" title="防抖"></a>防抖</h2><h3 id="防抖关键函数"><a href="#防抖关键函数" class="headerlink" title="防抖关键函数"></a>防抖关键函数</h3><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">debounce</span>(<span class="params">f, wait</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">let</span> timmer = <span class="literal">null</span>;</span><br><span class="line">    <span class="keyword">return</span> <span class="function">(<span class="params">...args</span>) =&gt;</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (timmer) clearInterval(timmer);</span><br><span class="line">        timmer = setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">            f(...args);</span><br><span class="line">        &#125;, wait);</span><br><span class="line">    &#125;;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>关键的两个点在于使用闭包保存<code>timmer</code>，以及ES6的剩余参数来传入回调函数的若干个参数。</p><h3 id="函数调用示例"><a href="#函数调用示例" class="headerlink" title="函数调用示例"></a>函数调用示例</h3><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">const</span> myDebounce = debounce(myFn,<span class="number">1000</span>);</span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">let</span> i=<span class="number">0</span>;i&lt;<span class="number">1000</span>;i++)&#123;</span><br><span class="line">    myDebounce(arg1,arg2,arg3);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>这样，即使调用1000次，也只会响应最后一次的请求。</p><h3 id="实战说明"><a href="#实战说明" class="headerlink" title="实战说明"></a>实战说明</h3><p>该例子的应用场景主要为用户频繁点击提交按钮，可能会产生多次异步请求或同步运算，这样无论对用户还是对服务器都是不友好的。因此，我们使用防抖技术，当用户频繁点击提交时，我们只响应最后一次操作。</p><p>请在下面的输入框中随机输入文本，然后疯狂点击提交按钮，只有当你停止点击2s后，你的请求才会被提交，你会看到提交成功的提示说明。</p><iframe src="/demo/frontend/debounceAndThrottle/debounce.html" width=100% height=320px></iframe><h2 id="节流"><a href="#节流" class="headerlink" title="节流"></a>节流</h2><h3 id="节流关键函数"><a href="#节流关键函数" class="headerlink" title="节流关键函数"></a>节流关键函数</h3><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="function"><span class="keyword">function</span> <span class="title">throttle</span>(<span class="params">f, wait</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">let</span> timmer = <span class="literal">null</span>;</span><br><span class="line">    <span class="keyword">return</span> <span class="function">(<span class="params">...args</span>) =&gt;</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (timmer) <span class="keyword">return</span>;</span><br><span class="line">        timmer = setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">            f(...args);</span><br><span class="line">            timmer = <span class="literal">null</span>;</span><br><span class="line">        &#125;, wait);</span><br><span class="line">    &#125;;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>关键技术点和节流类似，只是当<code>timmer</code>实例已经存在时的处理方式不同。实际上仅变动了两行代码。</p><h3 id="函数调用示例-1"><a href="#函数调用示例-1" class="headerlink" title="函数调用示例"></a>函数调用示例</h3><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="keyword">const</span> myThrottle = throttle(myFn,<span class="number">1000</span>);</span><br><span class="line">setTimeIntervar(<span class="function"><span class="params">()</span>=&gt;</span>&#123;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">let</span> i=<span class="number">0</span>;i&lt;<span class="number">4</span>;i++)&#123;</span><br><span class="line">    myThrottle(arg1,arg2,arg3);</span><br><span class="line">&#125;</span><br><span class="line">&#125;,<span class="number">500</span>);</span><br></pre></td></tr></table></figure><p>当间隔1s调用4次<code>myThrottle</code>函数时，“理论上”会执行两次回调函数。（理论上指的是事件循环无法保证一定在0.5s间隔内就执行一次定时任务也无法保证每次定时任务一定会被执行。）</p><h3 id="实战说明-1"><a href="#实战说明-1" class="headerlink" title="实战说明"></a>实战说明</h3><p>当滚动进度条时，我们不需要每次滚动事件触发就进行响应，而是间隔一定时间后响应一次，这样可以在保证用户正常体验的前提下减少性能损耗。</p><p>即使疯狂对<code>box</code>上下滚动，可以发现它只会间隔2s响应一次。当你停止滚动时，它有可能会再响应一次。</p><iframe src="/demo/frontend/debounceAndThrottle/throttle.html" width=100% height=500px></iframe><h2 id="后记"><a href="#后记" class="headerlink" title="后记"></a>后记</h2><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;/h2&gt;&lt;p&gt;前前后后看了很多关于防抖和节流的文章，一直没有编程总结。防抖和节流其实比较类似，都是闭包的简单应用。前者关键在于用户频繁进行多次操作时，只响应一次；后者关键在于控制操作的频率。下次将列举出关键函数代码与实际运用例子。&lt;/p&gt;
    
    </summary>
    
    
      <category term="front-end" scheme="https://ascodelife.github.io/categories/front-end/"/>
    
    
      <category term="html&amp;css" scheme="https://ascodelife.github.io/tags/html-css/"/>
    
      <category term="css3" scheme="https://ascodelife.github.io/tags/css3/"/>
    
      <category term="学习笔记" scheme="https://ascodelife.github.io/tags/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
    
      <category term="optimization" scheme="https://ascodelife.github.io/tags/optimization/"/>
    
  </entry>
  
  <entry>
    <title>学习笔记——从预编译出发看闭包</title>
    <link href="https://ascodelife.github.io/2020/04/24/closure/"/>
    <id>https://ascodelife.github.io/2020/04/24/closure/</id>
    <published>2020-04-24T02:53:45.000Z</published>
    <updated>2020-04-30T16:11:52.905Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>陆陆续续看过一些对js闭包(closure)，发现对闭包理解一直差点意思。直到学习了js预编译，才恍然大悟，原来从预编译出发看闭包，才能看得更加透彻!</p><a id="more"></a><h2 id="预备知识"><a href="#预备知识" class="headerlink" title="预备知识"></a>预备知识</h2><p>首先，我们得先对预编译进行一些简要地介绍。</p><h3 id="执行上下文"><a href="#执行上下文" class="headerlink" title="执行上下文"></a>执行上下文</h3><p>执行上下文可理解为当前的执行环境，与该运行环境相对应。js引擎每进入一个环境就会创建相应的执行上下文，创建执行上下文的过程中，主要做了以下三件事件，如图：<br><img src="/demo/frontend/closure/execution-context.png" alt="avatar"></p><h3 id="预编译"><a href="#预编译" class="headerlink" title="预编译"></a>预编译</h3><p>大家都知道，javascript是解释性语言，主要特点为解释一行执行一行。<br>而在js的执行分为3个阶段</p><ol><li><strong>语法分析</strong>：script标签加载即开始语法分析，分析整个标签内的语法错误。无错误即进入预编译阶段。</li><li><strong>预编译</strong>： 每进入一个新环境，就进行一次预编译，同时创建一个执行上下文并放入执行栈中。此时，当前环境会进行一定的函数声明提升和变量声明提升，注意：函数声明提升优先于变量声明提升。环境中没有新的函数声明则进入解释执行阶段。</li><li><strong>解释执行</strong>：将当前执行上下文中的VO-&gt;AO， 此后，js引擎在当前环境从上到下、从左到右执行代码，不断改变AO中的变量等内容。当前上下文执行完毕则出栈，执行下一个上下文。  </li></ol><p><strong><em>要点：js进入全局环境时，主线程创建全局执行上下文，全局执行上下文中的变量对象<code>VO(globalContext) === global</code>,或称为GO;在进入函数环境时，会创建执行上下文，并放入执行栈，而在函数执行时执行上下文中的VO-&gt;AO</em></strong></p><p><strong>预编译四部曲：</strong>  </p><ol><li>创建AO(Activation object)对象</li><li>找形参和变量声明，将变量声明的名（即变量和形参名）作为AO属性名，值为undefined</li><li>将实参和形参统一</li><li>在函数体里面找函数声明，值赋予函数体（<strong><em>注意此处的函数声明要区别于函数表达式）</em></strong><h3 id="预编译例子分析"><a href="#预编译例子分析" class="headerlink" title="预编译例子分析"></a>预编译例子分析</h3><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></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">fn</span>(<span class="params">a</span>)</span>&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(a);</span><br><span class="line">        <span class="keyword">var</span> a = <span class="number">123</span>;</span><br><span class="line">        <span class="built_in">console</span>.log(a);</span><br><span class="line">        <span class="function"><span class="keyword">function</span> <span class="title">a</span>(<span class="params"></span>) </span>&#123;&#125;</span><br><span class="line">        <span class="built_in">console</span>.log(a);</span><br><span class="line">        <span class="keyword">var</span> b = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;&#125;;</span><br><span class="line">        <span class="built_in">console</span>.log(b);</span><br><span class="line">        <span class="function"><span class="keyword">function</span> <span class="title">d</span>(<span class="params"></span>) </span>&#123;&#125;</span><br><span class="line">&#125;</span><br><span class="line">fn(<span class="number">1</span>);</span><br></pre></td></tr></table></figure></li><li>创建AO(Activation object)对象<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">AO = &#123;&#125;</span><br></pre></td></tr></table></figure></li><li>找形参和变量声明，将变量声明的名（即变量和形参名）作为AO属性名，值为undefined<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">AO = &#123;</span><br><span class="line">    a:<span class="literal">undefined</span>,<span class="comment">//形参</span></span><br><span class="line">    b:<span class="literal">undefined</span>,<span class="comment">//变量声明</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li><li>将实参和形参统一<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">AO = &#123;</span><br><span class="line">    a:<span class="number">1</span>,<span class="comment">//将实参值赋给形参</span></span><br><span class="line">    b:<span class="literal">undefined</span>,<span class="comment">//变量声明</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li><li>在函数体里面找函数声明，值赋予函数体<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">AO = &#123;</span><br><span class="line">    a:<span class="function"><span class="keyword">function</span> <span class="title">a</span>(<span class="params"></span>)</span>&#123;&#125;,</span><br><span class="line">    b:<span class="literal">undefined</span>,<span class="comment">//变量声明</span></span><br><span class="line">    d:<span class="function"><span class="keyword">function</span> <span class="title">d</span>(<span class="params"></span>)</span>&#123;&#125;,</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><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</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">fn</span>(<span class="params">a</span>)</span>&#123;</span><br><span class="line">        <span class="function"><span class="keyword">function</span> <span class="title">a</span>(<span class="params"></span>) </span>&#123;&#125;</span><br><span class="line">        <span class="function"><span class="keyword">function</span> <span class="title">d</span>(<span class="params"></span>) </span>&#123;&#125;</span><br><span class="line">        <span class="comment">//var a;函数声明优先于变量声明</span></span><br><span class="line">        <span class="built_in">console</span>.log(a);</span><br><span class="line">        a = <span class="number">123</span>;</span><br><span class="line">        <span class="built_in">console</span>.log(a);</span><br><span class="line">        <span class="built_in">console</span>.log(a);</span><br><span class="line">        <span class="keyword">var</span> b = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;&#125;;<span class="comment">//注意函数表达式不提升</span></span><br><span class="line">        <span class="built_in">console</span>.log(b);</span><br><span class="line">&#125;</span><br><span class="line">fn(<span class="number">1</span>);</span><br></pre></td></tr></table></figure>由上述代码，我们可以很简单地分析出打印结果为：<br>ƒ a() {}<br>123<br>123<br>ƒ () {}  </li></ol><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></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">test</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(b);<span class="comment">//undefined;</span></span><br><span class="line">    <span class="keyword">if</span> (a) &#123;</span><br><span class="line">        <span class="keyword">var</span> b = <span class="number">100</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="built_in">console</span>.log(b);<span class="comment">//undefined</span></span><br><span class="line">    c = <span class="number">234</span>;</span><br><span class="line">    <span class="built_in">console</span>.log(c); <span class="comment">//234;</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> a;</span><br><span class="line">test();</span><br><span class="line">a = <span class="number">10</span>;</span><br><span class="line"><span class="built_in">console</span>.log(c);  <span class="comment">//234;</span></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></pre></td><td class="code"><pre><span class="line">VO(globalContext) = &#123;</span><br><span class="line">    a:<span class="literal">undefined</span>,</span><br><span class="line">    c:<span class="literal">undefined</span>,<span class="comment">//非严格模式</span></span><br><span class="line">    test:<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;...&#125;,<span class="comment">//这里略写了函数体</span></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></pre></td><td class="code"><pre><span class="line">GO = &#123;</span><br><span class="line">    a:<span class="literal">undefined</span>,</span><br><span class="line">    c:<span class="literal">undefined</span>,<span class="comment">//非严格模式</span></span><br><span class="line">    test:<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;...&#125;,<span class="comment">//这里略写了函数体</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>通俗来说GO比起AO只是少了实参和形参统一的步骤。<br>当进入函数<code>test</code>环境时，js预编译创建执行上下文并入执行栈，在函数执行时VO-&gt;AO。初始AO如下所示。</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></pre></td><td class="code"><pre><span class="line">AO(test) = &#123;</span><br><span class="line">    b:<span class="literal">undefined</span>,</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="闭包实例分析"><a href="#闭包实例分析" class="headerlink" title="闭包实例分析"></a>闭包实例分析</h2><p>有了上面的预备知识，我们将举几个经典的闭包例子，从预编译出发来进行分析。</p><h3 id="例子一"><a href="#例子一" class="headerlink" title="例子一"></a>例子一</h3><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> foo = (<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> v = <span class="number">0</span></span><br><span class="line">    <span class="keyword">return</span> <span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> v++</span><br><span class="line">    &#125;</span><br><span class="line">&#125;())</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; <span class="number">10</span>; i++) &#123;</span><br><span class="line">    foo()</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(foo())</span><br></pre></td></tr></table></figure><ol><li>创建全局执行上下文，此时GO对象为<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">GO = &#123;    </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li><li>执行完第一条赋值语句后，此时GO对象为<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">GO = &#123;</span><br><span class="line">    foo:<span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> v++</span><br><span class="line">    &#125;    </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li></ol><h2 id="后记"><a href="#后记" class="headerlink" title="后记"></a>后记</h2>]]></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;/h2&gt;&lt;p&gt;陆陆续续看过一些对js闭包(closure)，发现对闭包理解一直差点意思。直到学习了js预编译，才恍然大悟，原来从预编译出发看闭包，才能看得更加透彻!&lt;/p&gt;
    
    </summary>
    
    
      <category term="front-end" scheme="https://ascodelife.github.io/categories/front-end/"/>
    
    
      <category term="学习笔记" scheme="https://ascodelife.github.io/tags/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
    
      <category term="javascript" scheme="https://ascodelife.github.io/tags/javascript/"/>
    
  </entry>
  
  <entry>
    <title>学习笔记——执行上下文与this的指向</title>
    <link href="https://ascodelife.github.io/2020/04/22/this/"/>
    <id>https://ascodelife.github.io/2020/04/22/this/</id>
    <published>2020-04-22T14:08:04.000Z</published>
    <updated>2020-04-24T02:46:42.999Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>如果面试官让你用一句话总结this的指向，你会怎么总结。广泛流传的一句话是:</p><blockquote><p>谁调用它，<code>this</code>就指向谁。</p></blockquote><p>严格来说，这句话的描述不够规范也不完全准确。对<code>this</code>指向的分析离不开执行上下文。因此，本文我们将结合执行上下文对<code>this</code>的各种使用场景进行分析。</p><a id="more"></a><h2 id="全局环境下的this"><a href="#全局环境下的this" class="headerlink" title="全局环境下的this"></a>全局环境下的this</h2><h3 id="例题一"><a href="#例题一" class="headerlink" title="例题一"></a>例题一</h3><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">f1</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="keyword">this</span>)</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">f2</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line"><span class="meta">    'use strict'</span></span><br><span class="line">    <span class="built_in">console</span>.log(<span class="keyword">this</span>)</span><br><span class="line">&#125;</span><br><span class="line">f1() <span class="comment">// window</span></span><br><span class="line">f2() <span class="comment">// undefined</span></span><br></pre></td></tr></table></figure><p>函数<code>f1</code>和<code>f2</code>都在全局环境下被调用或者说没有直接调用者，在非严格模式下<code>this</code>指向了调用它<code>window</code>对象，但在严格模式下<code>this</code>指向<code>undefined</code>。  </p><h3 id="例题二"><a href="#例题二" class="headerlink" title="例题二"></a>例题二</h3><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="keyword">const</span> foo = &#123;</span><br><span class="line">    bar: <span class="number">10</span>,</span><br><span class="line">    fn: <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="keyword">this</span>)</span><br><span class="line">       <span class="built_in">console</span>.log(<span class="keyword">this</span>.bar)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> fn1 = foo.fn</span><br><span class="line">fn1()</span><br></pre></td></tr></table></figure><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></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">## 上下文对象调用中的 this</span><br><span class="line">### 例题三</span><br><span class="line">&#96;&#96;&#96;javascript</span><br><span class="line">const foo &#x3D; &#123;</span><br><span class="line">    bar: 10,</span><br><span class="line">    fn: function() &#123;</span><br><span class="line">       console.log(this)</span><br><span class="line">       console.log(this.bar)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line">foo.fn()</span><br></pre></td></tr></table></figure><p>在此题中，我们先在全局环境下调用<code>foo.fn()</code>，而函数<code>fn</code>在<code>foo</code>对象中被调用。此时，<code>this</code>指向的是<strong>最后调用它的对象</strong><code>foo</code>，<code>this.bar</code>就相当于<code>foo.bar</code>。</p><h3 id="例题四"><a href="#例题四" class="headerlink" title="例题四"></a>例题四</h3><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">const</span> person = &#123;</span><br><span class="line">    name: <span class="string">'Lucas'</span>,</span><br><span class="line">    brother: &#123;</span><br><span class="line">        name: <span class="string">'Mike'</span>,</span><br><span class="line">        fn: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">this</span>.name</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="built_in">console</span>.log(person.brother.fn())</span><br></pre></td></tr></table></figure><p>由例题三的分析，此题的结果也很明了，最后调用函数<code>fn</code>的对象为<code>brother</code>，因此<code>this.name</code>就相当于<code>brother.name</code>  </p><h3 id="例题五"><a href="#例题五" class="headerlink" title="例题五"></a>例题五</h3><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> o1 = &#123;</span><br><span class="line">    text: <span class="string">'o1'</span>,</span><br><span class="line">    fn: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">this</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">const</span> o2 = &#123;</span><br><span class="line">    text: <span class="string">'o2'</span>,</span><br><span class="line">    fn: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> o1.fn()</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">const</span> o3 = &#123;</span><br><span class="line">    text: <span class="string">'o3'</span>,</span><br><span class="line">    fn: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">        <span class="keyword">var</span> fn = o1.fn</span><br><span class="line">        <span class="keyword">return</span> fn()</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(o1.fn())</span><br><span class="line"><span class="built_in">console</span>.log(o2.fn())</span><br><span class="line"><span class="built_in">console</span>.log(o3.fn())</span><br></pre></td></tr></table></figure><p>调用<code>o1.fn()</code>时，<code>this</code>指向<code>o1</code>对象，这个没什么好说的。<br>调用<code>o2.fn()</code>时，<code>this</code>也指向最后调用它的<code>o1</code>。<br>调用<code>o3.fn()</code>时，函数<code>fn</code>先被赋值为函数<code>o1.fn</code>，然后再调用赋值后的函数<code>fn</code>。此时情况就还原为了例子一。</p><h2 id="bind-call-apply-改变-this-指向"><a href="#bind-call-apply-改变-this-指向" class="headerlink" title="bind/call/apply 改变 this 指向"></a>bind/call/apply 改变 this 指向</h2><p>先举个简单例子</p><h3 id="例题六"><a href="#例题六" class="headerlink" title="例题六"></a>例题六</h3><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">const</span> foo = &#123;</span><br><span class="line">    name: <span class="string">'lucas'</span>,</span><br><span class="line">    logName: <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="keyword">this</span>.name)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">const</span> bar = &#123;</span><br><span class="line">    name: <span class="string">'mike'</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">console</span>.log(foo.logName.call(bar))</span><br></pre></td></tr></table></figure><p>利用<code>call</code>改变<code>this</code>指向，使<code>this</code>指向<code>bar</code>对象，最后打印<code>bar.name</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><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">## 构造函数和 this</span><br><span class="line">如下例题所示</span><br><span class="line">### 例题七</span><br><span class="line">&#96;&#96;&#96;javascript</span><br><span class="line">function Foo() &#123;</span><br><span class="line">    this.bar &#x3D; &quot;Lucas&quot;</span><br><span class="line">&#125;</span><br><span class="line">const instance &#x3D; new Foo()</span><br><span class="line">console.log(instance.bar)</span><br></pre></td></tr></table></figure><p>显然，对于oop比较熟悉的人立马就知道这里打印的就是<code>this.bar</code>的值。<br>当<code>new</code>操作符调用构造函数时，会对<code>this</code>指向造成什么影响呢？我们简单说一下<code>new</code>操作符的工作就是：  </p><ol><li>创建一个新对象。</li><li>将构造函数的<code>this</code>指向这个新对象。</li><li>为这个对象添加属性、方法等。</li><li>最终返回新对象。</li></ol><h2 id="箭头函数与this"><a href="#箭头函数与this" class="headerlink" title="箭头函数与this"></a>箭头函数与this</h2><p>这个也是我们在使用箭头函数时要注意的问题。</p><h3 id="例题八"><a href="#例题八" class="headerlink" title="例题八"></a>例题八</h3><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"><span class="keyword">const</span> foo = &#123;  </span><br><span class="line">    fn: <span class="function"><span class="keyword">function</span> (<span class="params"></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">            <span class="built_in">console</span>.log(<span class="keyword">this</span>)</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="built_in">console</span>.log(foo.fn())</span><br></pre></td></tr></table></figure><p>这里由于产生了闭包，<code>this</code>指向了<code>window</code>，与我们原先的想法有差异。为了能让<code>this</code>指向调用<code>fn</code>函数的<code>foo</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> foo = &#123;  </span><br><span class="line">    fn: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;  </span><br><span class="line">        setTimeout(<span class="function"><span class="params">()</span> =&gt;</span> &#123;  </span><br><span class="line">            <span class="built_in">console</span>.log(<span class="keyword">this</span>)</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="built_in">console</span>.log(foo.fn())</span><br></pre></td></tr></table></figure><p>此时，<code>this</code>指向最近的函数即<code>fn</code>的<code>this</code>指向。</p><h2 id="this的优先级"><a href="#this的优先级" class="headerlink" title="this的优先级"></a>this的优先级</h2><p>对<code>this</code>的绑定我们通常分为两类  </p><ol><li>显式绑定，如<code>call</code>、<code>apply</code>、<code>bind</code>、<code>new</code>对<code>this</code>的绑定。</li><li>隐式绑定，如根据调用关系确定的<code>this</code>指向。  </li></ol><p>那么显示绑定和隐式绑定谁的优先级更高呢？</p><h3 id="例题九"><a href="#例题九" class="headerlink" title="例题九"></a>例题九</h3><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="function"><span class="keyword">function</span> <span class="title">foo</span> (<span class="params">a</span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="keyword">this</span>.a)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> obj1 = &#123;</span><br><span class="line">    a: <span class="number">1</span>,</span><br><span class="line">    foo: foo</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> obj2 = &#123;</span><br><span class="line">    a: <span class="number">2</span>,</span><br><span class="line">    foo: foo</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">obj1.foo.call(obj2)</span><br><span class="line">obj2.foo.call(obj1)</span><br></pre></td></tr></table></figure><p>上例比较了对象调用与call的优先级，根据打印的结果为2，1可以得知：<code>call</code>和<code>apply</code>的显式绑定的优先级要高于隐式绑定。</p><h3 id="例题十"><a href="#例题十" class="headerlink" title="例题十"></a>例题十</h3><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">foo</span> (<span class="params">a</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">this</span>.a = a</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> obj1 = &#123;&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> bar = foo.bind(obj1)</span><br><span class="line">bar(<span class="number">2</span>)</span><br><span class="line"><span class="built_in">console</span>.log(obj1.a)</span><br></pre></td></tr></table></figure><p>上例使用<code>bind</code>将<code>bar</code>函数中<code>this</code>绑定为<code>obj1</code>对象，因此执行<code>bar(2)</code>后，<code>obj1.a</code>的值为2。<br>此时，若将<code>bar</code>函数当做构造函数，<code>new</code>一个对象时，<code>this</code>将绑定到新创建的对象上。</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"><span class="keyword">var</span> baz = <span class="keyword">new</span> bar(<span class="number">3</span>)</span><br><span class="line"><span class="built_in">console</span>.log(baz.a)</span><br></pre></td></tr></table></figure><p>如上例，结果将输出3。<br>由此可以得到结论，同样是显示绑定<code>new</code>的优先级比<code>bind</code>高。</p><h3 id="例题十一"><a href="#例题十一" class="headerlink" title="例题十一"></a>例题十一</h3><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="function"><span class="keyword">function</span> <span class="title">foo</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="function"><span class="params">a</span> =&gt;</span> &#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="keyword">this</span>.a)</span><br><span class="line">    &#125;;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> obj1 = &#123;</span><br><span class="line">    a: <span class="number">2</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> obj2 = &#123;</span><br><span class="line">    a: <span class="number">3</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> bar = foo.call(obj1)</span><br><span class="line"><span class="built_in">console</span>.log(bar.call(obj2))</span><br></pre></td></tr></table></figure><p>首先用<code>call</code>将<code>this</code>绑定到<code>obj1</code>，此时<code>bar</code>（引用箭头函数）的<code>this</code>也会绑定到<code>obj1</code>，箭头函数的绑定无法被修改。因此，最后将打印2。</p><h2 id="后记"><a href="#后记" class="headerlink" title="后记"></a>后记</h2><p>通过上面的例子，我们可以得知：</p><blockquote><p><code>this</code>的指向，是在调用函数时根据执行上下文所动态确定的。  </p></blockquote><p>当然，要完全解决<code>this</code>指向问题，光靠上面几个例子是不够的，还需要自己多写多看多做总结，才能把知识点融会贯通。</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;/h2&gt;&lt;p&gt;如果面试官让你用一句话总结this的指向，你会怎么总结。广泛流传的一句话是:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;谁调用它，&lt;code&gt;this&lt;/code&gt;就指向谁。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;严格来说，这句话的描述不够规范也不完全准确。对&lt;code&gt;this&lt;/code&gt;指向的分析离不开执行上下文。因此，本文我们将结合执行上下文对&lt;code&gt;this&lt;/code&gt;的各种使用场景进行分析。&lt;/p&gt;
    
    </summary>
    
    
      <category term="front-end" scheme="https://ascodelife.github.io/categories/front-end/"/>
    
    
      <category term="学习笔记" scheme="https://ascodelife.github.io/tags/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
    
      <category term="javascript" scheme="https://ascodelife.github.io/tags/javascript/"/>
    
  </entry>
  
  <entry>
    <title>学习笔记——摆钟的改进</title>
    <link href="https://ascodelife.github.io/2020/04/17/improve-animation-grandfather-clock/"/>
    <id>https://ascodelife.github.io/2020/04/17/improve-animation-grandfather-clock/</id>
    <published>2020-04-17T10:34:01.000Z</published>
    <updated>2020-04-20T05:56:10.753Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>在<a href="/2020/04/14/animation-grandfather-clock/#关键点2：时钟刻度">上一篇文章4.1.2节</a>中介绍了时钟刻度的实现方式，对其中时钟数字的摆放位置我们总结出了一套公式进行计算，本篇对数字的摆放给出了更简洁的实现方式。</p><a id="more"></a><h2 id="改进思路"><a href="#改进思路" class="headerlink" title="改进思路"></a>改进思路</h2><p>利用伪元素before，我们可以将数字附加到刻度之前，因为数字会跟着刻度旋转，所以为了保证数字正常显示，我们需要再针对数字进行一次旋转。即总共进行两次旋转，一次整体旋转，一次数字旋转。<br>同时，为了让刻度和数字完全对齐，我们需要在设置伪元素的样式上使用一些技巧。</p><h2 id="代码与细节展示"><a href="#代码与细节展示" class="headerlink" title="代码与细节展示"></a>代码与细节展示</h2><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><span class="line">67</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="meta-keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</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">style</span>&gt;</span></span><br><span class="line"><span class="css">        <span class="selector-id">#clock</span> &#123;</span></span><br><span class="line">            width: 300px;</span><br><span class="line">            height: 300px;</span><br><span class="line">            border-radius: 50%;</span><br><span class="line">            border: 1px solid;</span><br><span class="line">            font-size: 20px;</span><br><span class="line">            position: relative;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line"><span class="css">        <span class="selector-class">.scale</span>&gt;<span class="selector-tag">div</span> &#123;</span></span><br><span class="line">            position: absolute;</span><br><span class="line">            height: 5px;</span><br><span class="line">            width: 2px;</span><br><span class="line">            left: 50%;</span><br><span class="line">            background-color: black;</span><br><span class="line"><span class="css">            <span class="comment">/* 中心Y偏移=时钟高度/2 */</span></span></span><br><span class="line">            transform-origin: 0 150px;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line"><span class="css">        <span class="selector-class">.scale</span>&gt;<span class="selector-tag">div</span><span class="selector-pseudo">:nth-child(5n+1)</span> &#123;</span></span><br><span class="line">            height: 10px;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line"><span class="css">        <span class="selector-class">.scale</span>&gt;<span class="selector-tag">div</span><span class="selector-pseudo">:nth-child(5n+1)</span><span class="selector-pseudo">::before</span> &#123;</span></span><br><span class="line"><span class="css">            <span class="comment">/* 设置为块级元素，使其宽度可更改 */</span></span></span><br><span class="line">            display: block;</span><br><span class="line"><span class="css">            <span class="comment">/* 文本居中显示 */</span></span></span><br><span class="line">            text-align: center;</span><br><span class="line"><span class="css">            <span class="comment">/* 设置一个足够大的宽度，至少大于字体宽度 */</span></span></span><br><span class="line">            width: 20px;</span><br><span class="line"><span class="css">            <span class="comment">/* 让元素向左偏移宽度的一半，使得字体与刻度线对齐 */</span></span></span><br><span class="line">            margin-left: -10px;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line"><span class="css">        <span class="selector-class">.scale</span>&gt;<span class="selector-tag">div</span><span class="selector-pseudo">:nth-child(1)</span><span class="selector-pseudo">::before</span> &#123;</span></span><br><span class="line">            content: '12';</span><br><span class="line">            transform: rotate(0deg);</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line"><span class="css">        <span class="selector-class">.scale</span>&gt;<span class="selector-tag">div</span><span class="selector-pseudo">:nth-child(6)</span><span class="selector-pseudo">::before</span> &#123;</span></span><br><span class="line">            content: '1';</span><br><span class="line">            transform: rotate(-30deg);</span><br><span class="line">        &#125;</span><br><span class="line">    <span class="tag">&lt;/<span class="name">style</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">title</span>&gt;</span>clock<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><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">"clock"</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">"scale"</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">'scale0'</span> <span class="attr">style</span>=<span class="string">"transform: rotate(0deg);"</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">'scale1'</span> <span class="attr">style</span>=<span class="string">"transform: rotate(6deg);"</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">'scale2'</span> <span class="attr">style</span>=<span class="string">"transform: rotate(12deg);"</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">'scale3'</span> <span class="attr">style</span>=<span class="string">"transform: rotate(18deg);"</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">'scale4'</span> <span class="attr">style</span>=<span class="string">"transform: rotate(24deg);"</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">'scale5'</span> <span class="attr">style</span>=<span class="string">"transform: rotate(30deg);"</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>&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><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure><h2 id="眼见为实"><a href="#眼见为实" class="headerlink" title="眼见为实"></a>眼见为实</h2><iframe src="/demo/frontend/improve-animation-grandfather-clock/clock-scale.html" width=100% height=320px></iframe><h2 id="后记"><a href="#后记" class="headerlink" title="后记"></a>后记</h2><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;/h2&gt;&lt;p&gt;在&lt;a href=&quot;/2020/04/14/animation-grandfather-clock/#关键点2：时钟刻度&quot;&gt;上一篇文章4.1.2节&lt;/a&gt;中介绍了时钟刻度的实现方式，对其中时钟数字的摆放位置我们总结出了一套公式进行计算，本篇对数字的摆放给出了更简洁的实现方式。&lt;/p&gt;
    
    </summary>
    
    
      <category term="front-end" scheme="https://ascodelife.github.io/categories/front-end/"/>
    
    
      <category term="html&amp;css" scheme="https://ascodelife.github.io/tags/html-css/"/>
    
      <category term="css3" scheme="https://ascodelife.github.io/tags/css3/"/>
    
      <category term="学习笔记" scheme="https://ascodelife.github.io/tags/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
    
      <category term="animation" scheme="https://ascodelife.github.io/tags/animation/"/>
    
  </entry>
  
  <entry>
    <title>学习笔记——纯css3动画实现可显示时间的摆钟</title>
    <link href="https://ascodelife.github.io/2020/04/14/animation-grandfather-clock/"/>
    <id>https://ascodelife.github.io/2020/04/14/animation-grandfather-clock/</id>
    <published>2020-04-14T10:24:34.000Z</published>
    <updated>2020-04-20T05:37:03.178Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>上一篇我们简单实验了一下一些预定义的transition-timing-function关键字，实际上这些关键字同样也适用于animation-timing-function.这一篇我们就趁热打铁，配合animation来制作一个可显示时间的摆钟。</p><a id="more"></a><h2 id="需求分析"><a href="#需求分析" class="headerlink" title="需求分析"></a>需求分析</h2><ol><li>在我们实现代码前，首先得知道摆钟长啥样，其次再分析它的各个零部件是如何运动的。下面直接用图片展示吧。<br><img src="/demo/frontend/animation-grandfather-clock/grandfather-clock.gif" alt="avatar"></li><li>从运动规律上看，我们可以把它拆解成两部分，一部分是普通的时钟，指针按不同的频率做圆周运动；一部分是下面的单摆，做着平面单摆运动。因此，在我们实现的时候可以把它分成两部分实现，最后进行组合。</li></ol><h2 id="单摆的具体分析与代码实现"><a href="#单摆的具体分析与代码实现" class="headerlink" title="单摆的具体分析与代码实现"></a>单摆的具体分析与代码实现</h2><p>下面我们将对单摆进行具体分析与代码实现。</p><h3 id="单摆的结构"><a href="#单摆的结构" class="headerlink" title="单摆的结构"></a>单摆的结构</h3><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">border-radius</span><span class="selector-pseudo">:50</span>%</span><br></pre></td></tr></table></figure><h3 id="单摆的运动规律"><a href="#单摆的运动规律" class="headerlink" title="单摆的运动规律"></a>单摆的运动规律</h3><p>单摆在最高点速度最0，在最低点速度最大，那么可以使用如下方式模拟它的运动轨迹</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">animation-timing-function</span><span class="selector-pseudo">:ease-in-out</span></span><br></pre></td></tr></table></figure><p>单摆是一个理论上无限次地周期性运动，那么则有</p><figure class="highlight css"><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"><span class="selector-tag">animation-iteration-count</span><span class="selector-pseudo">:infinite</span>;</span><br><span class="line"><span class="selector-tag">animation-direction</span><span class="selector-pseudo">:alternate</span>;</span><br></pre></td></tr></table></figure><p>假设单摆最高摆到45度，分解它半个周期的关键帧有</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><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"><span class="keyword">@keyframes</span> swing&#123;</span><br><span class="line">    <span class="selector-tag">from</span>&#123;</span><br><span class="line">        <span class="attribute">transform</span>:<span class="built_in">rotate</span>(<span class="number">45deg</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="selector-tag">to</span>&#123;</span><br><span class="line">        <span class="attribute">transform</span>:<span class="built_in">rotate</span>(-<span class="number">45deg</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>已知单摆的一个周期为1s，那么综合上述代码可以得到缩写</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">animation</span><span class="selector-pseudo">:swing</span>,<span class="selector-class">.5s</span>,<span class="selector-tag">ease-in-out</span>,<span class="selector-tag">infinite</span>,<span class="selector-tag">alternate</span></span><br></pre></td></tr></table></figure><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">transform-origin</span><span class="selector-pseudo">:center</span> <span class="selector-tag">top</span></span><br></pre></td></tr></table></figure><h3 id="代码实现"><a href="#代码实现" class="headerlink" title="代码实现"></a>代码实现</h3><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></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="meta-keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</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">style</span>&gt;</span></span><br><span class="line">        div &#123;</span><br><span class="line">            margin: 0 auto;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line"><span class="css">        <span class="keyword">@keyframes</span> swing &#123;</span></span><br><span class="line">            from &#123;</span><br><span class="line">                transform: rotate(45deg);</span><br><span class="line">            &#125;</span><br><span class="line">            to &#123;</span><br><span class="line">                transform: rotate(-45deg);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line"><span class="css">        <span class="selector-id">#simple-pendulum</span> &#123;</span></span><br><span class="line"><span class="css">            <span class="selector-tag">animation</span>: <span class="selector-tag">swing</span> <span class="selector-class">.5s</span> <span class="selector-tag">ease-in-out</span> <span class="selector-tag">infinite</span> <span class="selector-tag">alternate</span>;</span></span><br><span class="line">            width: 30px;</span><br><span class="line">            transform-origin: center top;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line"><span class="css">        <span class="selector-id">#ball</span> &#123;</span></span><br><span class="line">            height: 30px;</span><br><span class="line">            width: 30px;</span><br><span class="line">            background: red;</span><br><span class="line">            border-radius: 100%;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line"><span class="css">        <span class="selector-id">#line</span> &#123;</span></span><br><span class="line">            height: 100px;</span><br><span class="line">            width: 10px;</span><br><span class="line">            background: yellow;</span><br><span class="line">        &#125;</span><br><span class="line">    <span class="tag">&lt;/<span class="name">style</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">title</span>&gt;</span>simple-pendulum<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><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">"simple-pendulum"</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">"line"</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">id</span>=<span class="string">"ball"</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>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</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><h3 id="眼见为实"><a href="#眼见为实" class="headerlink" title="眼见为实"></a>眼见为实</h3><iframe src="/demo/frontend/animation-grandfather-clock/simple-pendulum.html" width=100% height=150px></iframe><h2 id="时钟的具体分析与代码实现"><a href="#时钟的具体分析与代码实现" class="headerlink" title="时钟的具体分析与代码实现"></a>时钟的具体分析与代码实现</h2><p>下面我们将对时钟进行具体分析与代码实现。</p><h3 id="时钟的结构"><a href="#时钟的结构" class="headerlink" title="时钟的结构"></a>时钟的结构</h3><ol><li>时钟是一个圆形容器。</li><li>容器里面有时针、分针、秒针，长度为时针&lt;分针&lt;秒针。</li><li>时钟里还有刻度和数字，每间隔6°一个小刻度，每间隔30°一个大刻度。  </li></ol><h4 id="关键点1：时钟与指针"><a href="#关键点1：时钟与指针" class="headerlink" title="关键点1：时钟与指针"></a>关键点1：时钟与指针</h4><p>指针在时钟中水平垂直居中并向上偏移指针高度的50%。<br>水平垂直居中是一个老生常谈的问题，下面直接给出一个相对比较好且兼容性强的解决方案，实现原理是依据绝对定位的格式化宽高计算公式<br>计算公式粗略可表示为容器大小=top/right/bottom/left+margin+border+padding+width/height<br>当然有机会的话之后再写一篇文章慢慢分析水平垂直居中。</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><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="selector-class">.father</span>&#123;</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">200px</span>;</span><br><span class="line">    <span class="attribute">height</span>:<span class="number">200px</span>;</span><br><span class="line">    <span class="attribute">position</span>:relative;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-class">.son</span>&#123;</span><br><span class="line">    <span class="attribute">width</span>:<span class="number">10px</span>;</span><br><span class="line">    <span class="attribute">height</span>:<span class="number">100px</span>;</span><br><span class="line">    <span class="attribute">position</span>:absolute;</span><br><span class="line">    <span class="attribute">top</span>:<span class="number">0</span>;</span><br><span class="line">    <span class="attribute">right</span>:<span class="number">0</span>;</span><br><span class="line">    <span class="attribute">bottom</span>:<span class="number">0</span>;</span><br><span class="line">    <span class="attribute">left</span>:<span class="number">0</span>;</span><br><span class="line">    <span class="attribute">margin</span>:auto;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>最后向上偏移指针高度的50%和指针旋转点</p><figure class="highlight css"><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"><span class="selector-tag">transform</span><span class="selector-pseudo">:translateY(-50</span>%);</span><br><span class="line"><span class="selector-tag">transform-origin</span><span class="selector-pseudo">:center</span> <span class="selector-tag">bottom</span>;</span><br></pre></td></tr></table></figure><h4 id="关键点2：时钟刻度"><a href="#关键点2：时钟刻度" class="headerlink" title="关键点2：时钟刻度"></a>关键点2：时钟刻度</h4><p>虽然这里用js配合jquery实现起来比较简洁，但是作为学习研究，我们要使用一切可能的方法去实现需求。<br>首先时钟是个圆形，我们要先把所有刻度移动到圆的顶部并居中，之后分别绕时钟中心点旋转不同的角度，当然复制粘贴的过程会有点繁琐。<br>对于数字，因为数字不能跟着像刻度一样旋转（旋转了以后数字朝向就变了），所以我们直接用绝对定位，并通过极坐标转直角坐标系的公式，算出偏移值。<br>下面将给出一个标有刻度为1的时钟的实现代码。<br><em>具体数值的计算公式已给出,此处细节处理比较多,能实现较完美的对齐效果。</em></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><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><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="meta-keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</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">style</span>&gt;</span></span><br><span class="line"><span class="css">        <span class="selector-id">#clock</span> &#123;</span></span><br><span class="line">            width: 300px;</span><br><span class="line">            height: 300px;</span><br><span class="line">            border-radius: 50%;</span><br><span class="line">            border: 1px solid;</span><br><span class="line">            font-size: 20px;</span><br><span class="line">            position: relative;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line"><span class="css">        <span class="selector-class">.scale</span>&gt;<span class="selector-tag">div</span> &#123;</span></span><br><span class="line">            position: absolute;</span><br><span class="line">            height: 5px;</span><br><span class="line">            width: 2px;</span><br><span class="line">            left: 50%;</span><br><span class="line">            background-color: black;</span><br><span class="line"><span class="css">            <span class="comment">/* 中心Y偏移=时钟高度/2 */</span></span></span><br><span class="line">            transform-origin: 0 150px;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line"><span class="css">        <span class="selector-class">.scale</span>&gt;<span class="selector-tag">div</span><span class="selector-pseudo">:nth-child(5n+1)</span> &#123;</span></span><br><span class="line">            height: 10px;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line"><span class="css">        <span class="selector-class">.number</span>&gt;<span class="selector-tag">div</span> &#123;</span></span><br><span class="line">            position: absolute;</span><br><span class="line">            line-height: 20px;</span><br><span class="line">            width: 20px;</span><br><span class="line">            text-align: center;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line"><span class="css">        <span class="selector-class">.number1</span> &#123;</span></span><br><span class="line"><span class="css">            <span class="comment">/* left=时钟半径+(时钟半径-刻度高度)*cos(-60°)-盒子宽度/2  */</span></span></span><br><span class="line">            left: 205px;</span><br><span class="line"><span class="css">            <span class="comment">/* top=时钟半径+(时钟半径-刻度高度)*sin(-60°)-行高/2 */</span></span></span><br><span class="line"><span class="css">            <span class="selector-tag">top</span>: 27<span class="selector-class">.41px</span>;</span></span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line"><span class="css">        <span class="selector-class">.number12</span> &#123;</span></span><br><span class="line"><span class="css">            <span class="comment">/* left=时钟半径+(时钟半径-刻度高度)*cos(270°)-盒子宽度/2  */</span></span></span><br><span class="line">            left: 140px;</span><br><span class="line"><span class="css">            <span class="comment">/* top=时钟半径+(时钟半径-刻度高度)*sin(270°)-行高/2  */</span></span></span><br><span class="line">            top: 10px;</span><br><span class="line">        &#125;</span><br><span class="line">    <span class="tag">&lt;/<span class="name">style</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">title</span>&gt;</span>clock<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><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">"clock"</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">"scale"</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">'scale0'</span> <span class="attr">style</span>=<span class="string">"transform: rotate(0deg);"</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">'scale1'</span> <span class="attr">style</span>=<span class="string">"transform: rotate(6deg);"</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">'scale2'</span> <span class="attr">style</span>=<span class="string">"transform: rotate(12deg);"</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">'scale3'</span> <span class="attr">style</span>=<span class="string">"transform: rotate(18deg);"</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">'scale4'</span> <span class="attr">style</span>=<span class="string">"transform: rotate(24deg);"</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">'scale5'</span> <span class="attr">style</span>=<span class="string">"transform: rotate(30deg);"</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>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"number"</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">"number1"</span>&gt;</span>1<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">"number12"</span>&gt;</span>12<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>&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><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure><p>眼见为实</p><iframe src="/demo/frontend/animation-grandfather-clock/clock-scale.html" width=100% height=320px></iframe><h3 id="时钟的运动规律"><a href="#时钟的运动规律" class="headerlink" title="时钟的运动规律"></a>时钟的运动规律</h3><p>时钟有三个指针，每个指针的运动频率不同。其中，时针和分针是匀速地连续地周期运动，秒针是匀速地一秒一帧地周期运动。<br>分针的动画粗略可以表示为</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><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">@keyframes</span> rotation&#123;</span><br><span class="line">    <span class="selector-tag">from</span>&#123;</span><br><span class="line">        <span class="attribute">transform</span>:<span class="built_in">rotate</span>(<span class="number">0deg</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="selector-tag">to</span>&#123;</span><br><span class="line">        <span class="attribute">transform</span>:<span class="built_in">rotate</span>(<span class="number">360deg</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;    </span><br><span class="line"><span class="selector-tag">animation</span><span class="selector-pseudo">:rotation</span> 3600<span class="selector-tag">s</span> <span class="selector-tag">liner</span> <span class="selector-tag">infinite</span></span><br></pre></td></tr></table></figure><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><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">@keyframes</span> rotation&#123;</span><br><span class="line">    <span class="selector-tag">from</span>&#123;</span><br><span class="line">        <span class="attribute">transform</span>:<span class="built_in">rotate</span>(<span class="number">0deg</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="selector-tag">to</span>&#123;</span><br><span class="line">        <span class="attribute">transform</span>:<span class="built_in">rotate</span>(<span class="number">360deg</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;    </span><br><span class="line"><span class="selector-tag">animation</span><span class="selector-pseudo">:rotation</span> 60<span class="selector-tag">s</span> <span class="selector-tag">steps</span>(60,<span class="selector-tag">end</span>) <span class="selector-tag">infinite</span></span><br></pre></td></tr></table></figure><h3 id="眼见为实-1"><a href="#眼见为实-1" class="headerlink" title="眼见为实"></a>眼见为实</h3><p>因为代码比较长，冗余的地方比较多，感兴趣的请自行F12</p><iframe src="/demo/frontend/animation-grandfather-clock/clock.html" width=100% height=320px></iframe><h2 id="最终实现效果"><a href="#最终实现效果" class="headerlink" title="最终实现效果"></a>最终实现效果</h2><p>直接上图不解释(待美化)，感兴趣的请自行F12</p><iframe src="/demo/frontend/animation-grandfather-clock/final.html" width=100% height=580px></iframe><h2 id="后记"><a href="#后记" class="headerlink" title="后记"></a>后记</h2><p>作为刚学习动画的菜鸟，css3动画有太多有趣的地方以及实现的细节与技巧。比起js动画，css3动画在实现比较简单的动画时有着较大优势，且不容易出现丢帧的情况，值得深入学习与研究。</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;/h2&gt;&lt;p&gt;上一篇我们简单实验了一下一些预定义的transition-timing-function关键字，实际上这些关键字同样也适用于animation-timing-function.这一篇我们就趁热打铁，配合animation来制作一个可显示时间的摆钟。&lt;/p&gt;
    
    </summary>
    
    
      <category term="front-end" scheme="https://ascodelife.github.io/categories/front-end/"/>
    
    
      <category term="html&amp;css" scheme="https://ascodelife.github.io/tags/html-css/"/>
    
      <category term="css3" scheme="https://ascodelife.github.io/tags/css3/"/>
    
      <category term="学习笔记" scheme="https://ascodelife.github.io/tags/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
    
      <category term="animation" scheme="https://ascodelife.github.io/tags/animation/"/>
    
  </entry>
  
  <entry>
    <title>学习笔记——transition-timing-function</title>
    <link href="https://ascodelife.github.io/2020/04/13/transition-timing-function/"/>
    <id>https://ascodelife.github.io/2020/04/13/transition-timing-function/</id>
    <published>2020-04-13T11:32:54.000Z</published>
    <updated>2020-04-14T10:22:46.185Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>transition CSS 属性是 transition-property，transition-duration，transition-timing-function 和 transition-delay 的一个简写属性。<br>其中transition-timing-function潜力最大也最为复杂，值得进行研究。</p><a id="more"></a><h2 id="常用预定义关键字"><a href="#常用预定义关键字" class="headerlink" title="常用预定义关键字"></a>常用预定义关键字</h2><p>我们所知道的常用的easing函数有：linear，ease，ease-in，ease-out，ease-in-out，以及step函数：step-start，step-end，steps(n,start)，steps(n,end)。<br>当然，为了得到更多的自定义easing函数，我们可以去研究贝塞尔(cubic-bezier)曲线，网上也能找到一些有趣的贝塞尔函数值。这里不多做解释，仅对预定义关键字进行演示。</p><h2 id="实现代码"><a href="#实现代码" class="headerlink" title="实现代码"></a>实现代码</h2><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><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="meta-keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</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>demo1<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">style</span>&gt;</span></span><br><span class="line"><span class="css">        <span class="selector-class">.runner</span>,</span></span><br><span class="line"><span class="css">        <span class="selector-class">.track</span> &#123;</span></span><br><span class="line">            height: 80px;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line"><span class="css">        <span class="selector-class">.track</span> &#123;</span></span><br><span class="line">            width: 500px;</span><br><span class="line">            margin: 10px 0px;</span><br><span class="line">            background: yellow;</span><br><span class="line">            text-align: center;</span><br><span class="line">            line-height: 80px;</span><br><span class="line">            font-size: 20px;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line"><span class="css">        <span class="selector-class">.runner</span>,</span></span><br><span class="line"><span class="css">        <span class="selector-class">.track</span><span class="selector-pseudo">:hover</span>&gt;<span class="selector-class">.runner</span> &#123;</span></span><br><span class="line">            transition: transform 1s;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line"><span class="css">        <span class="selector-class">.runner</span> &#123;</span></span><br><span class="line">            width: 100px;</span><br><span class="line">            border: solid;</span><br><span class="line">            line-height: 80px;</span><br><span class="line">            position: absolute;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line"><span class="css">        <span class="selector-class">.track</span><span class="selector-pseudo">:hover</span>&gt;<span class="selector-class">.runner</span> &#123;</span></span><br><span class="line">            transform: translate(400px);</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line"><span class="css">        <span class="selector-class">.track</span>&gt;<span class="selector-class">.linear</span>,</span></span><br><span class="line"><span class="css">        <span class="selector-class">.track</span><span class="selector-pseudo">:hover</span>&gt;<span class="selector-class">.linear</span> &#123;</span></span><br><span class="line">            transition-timing-function: linear</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line"><span class="css">        <span class="selector-class">.track</span>&gt;<span class="selector-class">.ease-in</span>,</span></span><br><span class="line"><span class="css">        <span class="selector-class">.track</span><span class="selector-pseudo">:hover</span>&gt;<span class="selector-class">.ease-in</span> &#123;</span></span><br><span class="line">            transition-timing-function: ease-in</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line"><span class="css">        <span class="selector-class">.track</span>&gt;<span class="selector-class">.ease-out</span>,</span></span><br><span class="line"><span class="css">        <span class="selector-class">.track</span><span class="selector-pseudo">:hover</span>&gt;<span class="selector-class">.ease-out</span> &#123;</span></span><br><span class="line">            transition-timing-function: ease-out</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line"><span class="css">        <span class="selector-class">.track</span>&gt;<span class="selector-class">.ease-in-out</span>,</span></span><br><span class="line"><span class="css">        <span class="selector-class">.track</span><span class="selector-pseudo">:hover</span>&gt;<span class="selector-class">.ease-in-out</span> &#123;</span></span><br><span class="line">            transition-timing-function: ease-in-out;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line"><span class="css">        <span class="selector-class">.track</span>&gt;<span class="selector-class">.steps-start</span>,</span></span><br><span class="line"><span class="css">        <span class="selector-class">.track</span><span class="selector-pseudo">:hover</span>&gt;<span class="selector-class">.steps-start</span> &#123;</span></span><br><span class="line">            transition-timing-function: steps(5, start);</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line"><span class="css">        <span class="selector-class">.track</span>&gt;<span class="selector-class">.steps-end</span>,</span></span><br><span class="line"><span class="css">        <span class="selector-class">.track</span><span class="selector-pseudo">:hover</span>&gt;<span class="selector-class">.steps-end</span> &#123;</span></span><br><span class="line">            transition-timing-function: steps(5, end);</span><br><span class="line">        &#125;</span><br><span class="line">    <span class="tag">&lt;/<span class="name">style</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><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">class</span>=<span class="string">"track-container"</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">"track"</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">"runner linear"</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            linear赛道，匀速</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">div</span> <span class="attr">class</span>=<span class="string">"track"</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">"runner ease"</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            ease赛道：默认值，起步快，减速</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">div</span> <span class="attr">class</span>=<span class="string">"track"</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">"runner ease-in"</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            ease-in赛道：加速</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">div</span> <span class="attr">class</span>=<span class="string">"track"</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">"runner ease-out"</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            ease-out赛道：减速</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">div</span> <span class="attr">class</span>=<span class="string">"track"</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">"runner ease-in-out"</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            ease-in-out赛道：先加速后减速</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">div</span> <span class="attr">class</span>=<span class="string">"track"</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">"runner steps-start"</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            steps(5,start)赛道：20% 40% 60% 80% 100%</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">div</span> <span class="attr">class</span>=<span class="string">"track"</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">"runner steps-end"</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            steps(5,end)赛道：0 20% 40% 60% 80%</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">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><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure><h2 id="眼见为实"><a href="#眼见为实" class="headerlink" title="眼见为实"></a>眼见为实</h2><p>把鼠标悬停到赛道上，看每个runner奔跑吧。<br>   <iframe src="/demo/frontend/transition-timing-function/demo1.html" width=100% height=800px></iframe></p><h2 id="小tips"><a href="#小tips" class="headerlink" title="小tips"></a>小tips</h2><p>此处布局也使用了无依赖绝对定位技巧，不了解的可以看上一篇哦！</p><h2 id="后记"><a href="#后记" class="headerlink" title="后记"></a>后记</h2><p>通过transition-timing-function我们可以得到很多运动轨迹，如何把这些有着不同特点的运动轨迹应用于实际，需要我们不停地实践与积累。</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;/h2&gt;&lt;p&gt;transition CSS 属性是 transition-property，transition-duration，transition-timing-function 和 transition-delay 的一个简写属性。&lt;br&gt;其中transition-timing-function潜力最大也最为复杂，值得进行研究。&lt;/p&gt;
    
    </summary>
    
    
      <category term="front-end" scheme="https://ascodelife.github.io/categories/front-end/"/>
    
    
      <category term="html&amp;css" scheme="https://ascodelife.github.io/tags/html-css/"/>
    
      <category term="css3" scheme="https://ascodelife.github.io/tags/css3/"/>
    
      <category term="学习笔记" scheme="https://ascodelife.github.io/tags/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
    
      <category term="transition" scheme="https://ascodelife.github.io/tags/transition/"/>
    
  </entry>
  
  <entry>
    <title>前端窍门——无依赖absolute绝对定位</title>
    <link href="https://ascodelife.github.io/2020/04/12/absolute-positioning-without-dependence/"/>
    <id>https://ascodelife.github.io/2020/04/12/absolute-positioning-without-dependence/</id>
    <published>2020-04-12T15:59:44.000Z</published>
    <updated>2020-04-14T10:28:13.935Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>聊起absolute定位，我们首先想到的就是找其包含块(containing block)或直接给父元素一个relative定位,然后根据包含块通过设置top,right,bottom,left属性值进行偏移。看起来，这是很常见的做法，但盲目的如此”套公式“，只能说你对absolute的理解不到家。</p><a id="more"></a><h2 id="何所谓“依赖”"><a href="#何所谓“依赖”" class="headerlink" title="何所谓“依赖”"></a>何所谓“依赖”</h2><p>所谓“依赖”，指的是绝对定位元素需要找到包含块，然后”依赖“包含块进行偏移或格式化元素的宽高。  </p><p>为了达到我们的目的——让子元素紧紧地“依赖”父元素，我们会“丧心病狂”的硬塞给父元素一个relative定位，甚至配合z-index属性设置层级。</p><p>好吧，先不谈父元素愿意不愿意，既然谈到了“依赖”，就不得不联想到耦合，耦合度越高的代码在应对变化时就越脆弱。</p><h2 id="传统的“有依赖”绝对定位"><a href="#传统的“有依赖”绝对定位" class="headerlink" title="传统的“有依赖”绝对定位"></a>传统的“有依赖”绝对定位</h2><p>既然要聊聊无依赖绝对定位，那么就应该先看看传统的”有依赖”绝对定位在一些经典应用场景是怎么做的，然后我们再谈怎么改进。</p><h3 id="表单提示信息"><a href="#表单提示信息" class="headerlink" title="表单提示信息"></a>表单提示信息</h3><ol><li><p>场景重现：填写表单时，当某个输入框获取焦点时，在输入框右侧显示一些提示信息。</p></li><li><p>场景分析：</p><ol><li>提示信息为不定长，若父元素宽度表现为定长，那么有可能内容会溢出；若父元素宽度表现为包裹性，那么宽度就会改变。</li><li>提示信息的显示和隐藏不能影响原布局，那么使其脱离文档流是最常见的选择。</li></ol></li><li><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><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></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="meta-keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</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>demo1<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">style</span>&gt;</span></span><br><span class="line"><span class="css">        <span class="selector-class">.regist-box</span> &#123;</span></span><br><span class="line">            width: 300px;</span><br><span class="line"><span class="css">            <span class="comment">/* 容器定宽 */</span></span></span><br><span class="line">            margin: 0 auto;</span><br><span class="line"><span class="css">            <span class="comment">/* 为了便于观察给一个边框 */</span></span></span><br><span class="line">            border: 1px solid;</span><br><span class="line"><span class="css">            <span class="comment">/* 使其变成子元素的包含块 */</span></span></span><br><span class="line">            position: relative;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line">        input &#123;</span><br><span class="line">            width: 200px;</span><br><span class="line">        &#125;</span><br><span class="line"><span class="css">        <span class="comment">/* 提示信息 */</span></span></span><br><span class="line">        </span><br><span class="line"><span class="css">        <span class="selector-class">.regist-remark</span> &#123;</span></span><br><span class="line">            color: red;</span><br><span class="line">            display: none;</span><br><span class="line"><span class="css">            <span class="comment">/* 绝对定位 */</span></span></span><br><span class="line">            position: absolute;</span><br><span class="line"><span class="css">            <span class="comment">/* 根据包含块进行定位 */</span></span></span><br><span class="line">            top: 0;</span><br><span class="line">            left: 250px;</span><br><span class="line">            white-space: nowrap;</span><br><span class="line">        &#125;</span><br><span class="line"><span class="css">        <span class="comment">/* 输入框获得焦点显示提示信息 */</span></span></span><br><span class="line">        </span><br><span class="line"><span class="css">        <span class="selector-tag">input</span><span class="selector-pseudo">:focus</span>~<span class="selector-class">.regist-remark</span> &#123;</span></span><br><span class="line">            display: inline;</span><br><span class="line">        &#125;</span><br><span class="line">    <span class="tag">&lt;/<span class="name">style</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><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">class</span>=<span class="string">'regist-box'</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">"regist-group"</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">label</span> <span class="attr">class</span>=<span class="string">"regist-label"</span>&gt;</span>邮箱<span class="tag">&lt;/<span class="name">label</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">"email"</span> <span class="attr">class</span>=<span class="string">"regist-input"</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">span</span> <span class="attr">class</span>=<span class="string">"regist-remark"</span>&gt;</span>请输入邮箱！<span class="tag">&lt;/<span class="name">span</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">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><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure></li><li><p>眼见为实：</p><iframe src="/demo/frontend/absolute-positioning-without-dependence/demo1.html" width=100%></iframe></li><li><p>代码分析：<br>让我们来分析一下，这样的代码是如何的脆弱。改动输入框width/padding/margin或改动label的文字长度，都需要修改提示信息的偏移值。那么他的复用性就大大降低了，特别是应对动态生成元素时，需要借助js进行偏移计算。</p></li></ol><h2 id="无依赖的改造"><a href="#无依赖的改造" class="headerlink" title="无依赖的改造"></a>无依赖的改造</h2><ol><li><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><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></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="meta">&lt;!DOCTYPE <span class="meta-keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</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>demo2<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">style</span>&gt;</span></span><br><span class="line"><span class="css">        <span class="selector-class">.regist-box</span> &#123;</span></span><br><span class="line">            width: 300px;</span><br><span class="line"><span class="css">            <span class="comment">/* 容器定宽 */</span></span></span><br><span class="line">            margin: 0 auto;</span><br><span class="line"><span class="css">            <span class="comment">/* 为了便于观察给一个边框 */</span></span></span><br><span class="line">            border: 1px solid;</span><br><span class="line"><span class="css">            <span class="comment">/* 使其变成子元素的包含块 */</span></span></span><br><span class="line"><span class="css">            <span class="comment">/* position: relative; */</span></span></span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line">        input &#123;</span><br><span class="line">            width: 200px;</span><br><span class="line">        &#125;</span><br><span class="line"><span class="css">        <span class="comment">/* 提示信息 */</span></span></span><br><span class="line">        </span><br><span class="line"><span class="css">        <span class="selector-class">.regist-remark</span> &#123;</span></span><br><span class="line">            color: red;</span><br><span class="line">            display: none;</span><br><span class="line"><span class="css">            <span class="comment">/* 绝对定位 */</span></span></span><br><span class="line">            position: absolute;</span><br><span class="line"><span class="css">            <span class="comment">/* 根据包含块进行定位 */</span></span></span><br><span class="line">            /*top: 0;</span><br><span class="line">            left: 250px;</span><br><span class="line">            white-space: nowrap;*/</span><br><span class="line"><span class="css">            <span class="comment">/* 利用margin进行偏移 */</span></span></span><br><span class="line">            margin-left: 10px;</span><br><span class="line">        &#125;</span><br><span class="line"><span class="css">        <span class="comment">/* 输入框获得焦点显示提示信息 */</span></span></span><br><span class="line">        </span><br><span class="line"><span class="css">        <span class="selector-tag">input</span><span class="selector-pseudo">:focus</span>~<span class="selector-class">.regist-remark</span> &#123;</span></span><br><span class="line">            display: inline;</span><br><span class="line">        &#125;</span><br><span class="line">    <span class="tag">&lt;/<span class="name">style</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><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">class</span>=<span class="string">'regist-box'</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">"regist-group"</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">label</span> <span class="attr">class</span>=<span class="string">"regist-label"</span>&gt;</span>邮箱<span class="tag">&lt;/<span class="name">label</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">"email"</span> <span class="attr">class</span>=<span class="string">"regist-input"</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">span</span> <span class="attr">class</span>=<span class="string">"regist-remark"</span>&gt;</span>请输入邮箱！<span class="tag">&lt;/<span class="name">span</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">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><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure></li><li><p>眼见为实 <iframe src="/demo/frontend/absolute-positioning-without-dependence/demo2.html" width=100%></iframe></p></li><li><p>代码分析：<br>毫不犹豫的去掉硬塞给父元素的相对定位，同时也去掉了left/right，使用margin进行元素偏移。<br>代码中使用margin-left:10px从视觉上看就是相对于输入框向右偏移了10px，虽然实际上其脱离了文档流，但是margin的表现却如它还在文档流中一样。<br>如此一来，没有了“依赖”，其弹性大大提高。无论你label有多少文字、input有多宽，我都永远乖乖跟在你身后，不离不弃。  </p></li><li><p>小tip:<br>想让提示信息放到输入框前面只需要改动它们在文档中的排列顺序哦！这个可以自行尝试。</p><h2 id="其他应用"><a href="#其他应用" class="headerlink" title="其他应用"></a>其他应用</h2><p>下面将给出它的其他简单有趣应用。</p><h3 id="悬停展示下拉列表"><a href="#悬停展示下拉列表" class="headerlink" title="悬停展示下拉列表"></a>悬停展示下拉列表</h3></li><li><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><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></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="meta-keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</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>demo3<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">style</span>&gt;</span></span><br><span class="line"><span class="css">        <span class="selector-class">.item</span> &#123;</span></span><br><span class="line">            display: inline-block</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line"><span class="css">        <span class="selector-class">.item</span>,</span></span><br><span class="line"><span class="css">        <span class="selector-class">.combo_box</span> &#123;</span></span><br><span class="line">            padding: 10px;</span><br><span class="line">            border: 1px solid;</span><br><span class="line">            width: 100px;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line"><span class="css">        <span class="selector-class">.combo_box</span> &#123;</span></span><br><span class="line">            position: absolute;</span><br><span class="line"><span class="css">            <span class="comment">/* margin-left = -1 * (padding-left + border-left)  */</span></span></span><br><span class="line">            margin-left: -11px;</span><br><span class="line"><span class="css">            <span class="comment">/* margin-top =  padding-bottom + border-bottom  */</span></span></span><br><span class="line">            margin-top: 11px;</span><br><span class="line">            border-top: none;</span><br><span class="line">            display: none;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line"><span class="css">        <span class="selector-class">.item</span><span class="selector-pseudo">:hover</span>&gt;<span class="selector-class">.combo_box</span> &#123;</span></span><br><span class="line">            display: block;</span><br><span class="line">        &#125;</span><br><span class="line">    <span class="tag">&lt;/<span class="name">style</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><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">class</span>=<span class="string">'box'</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">"item"</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">a</span>&gt;</span>linka11111<span class="tag">&lt;/<span class="name">a</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">"combo_box"</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">"subItem"</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;<span class="name">a</span>&gt;</span>linka111<span class="tag">&lt;/<span class="name">a</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><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">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">"item"</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">a</span>&gt;</span>linkb<span class="tag">&lt;/<span class="name">a</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">"combo_box"</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">"subItem"</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;<span class="name">a</span>&gt;</span>linkb1<span class="tag">&lt;/<span class="name">a</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">div</span> <span class="attr">class</span>=<span class="string">"subItem"</span>&gt;</span></span><br><span class="line"></span><br><span class="line">                    <span class="tag">&lt;<span class="name">a</span>&gt;</span>linkb2<span class="tag">&lt;/<span class="name">a</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">div</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">div</span> <span class="attr">class</span>=<span class="string">"item"</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">a</span>&gt;</span>linkc<span class="tag">&lt;/<span class="name">a</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">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><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure></li><li><p>眼见为实：</p><iframe src="/demo/frontend/absolute-positioning-without-dependence/demo3.html" width=100%></iframe></li><li><p>代码分析：<br>如此布局，可以满足一些简单的下拉框需求，仅当item的padding/border改变时需要对margin进行修改，而修改item内文字长度、大小都不会影响布局。</p></li></ol><h2 id="后记"><a href="#后记" class="headerlink" title="后记"></a>后记</h2><p>无依赖absolute绝对定位的舞台很大，我们可以思考曾经使用absolute实现的功能是否都能利用它来替换，使代码更简洁更健壮。</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;/h2&gt;&lt;p&gt;聊起absolute定位，我们首先想到的就是找其包含块(containing block)或直接给父元素一个relative定位,然后根据包含块通过设置top,right,bottom,left属性值进行偏移。看起来，这是很常见的做法，但盲目的如此”套公式“，只能说你对absolute的理解不到家。&lt;/p&gt;
    
    </summary>
    
    
      <category term="front-end" scheme="https://ascodelife.github.io/categories/front-end/"/>
    
    
      <category term="html&amp;css" scheme="https://ascodelife.github.io/tags/html-css/"/>
    
      <category term="absolute" scheme="https://ascodelife.github.io/tags/absolute/"/>
    
      <category term="前端窍门" scheme="https://ascodelife.github.io/tags/%E5%89%8D%E7%AB%AF%E7%AA%8D%E9%97%A8/"/>
    
  </entry>
  
</feed>
