<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>YouGuess</title>
  
  <subtitle>youguess13@qq.com</subtitle>
  <link href="/atom.xml" rel="self"/>
  
  <link href="https://yguess.github.io/"/>
  <updated>2018-03-13T05:45:54.804Z</updated>
  <id>https://yguess.github.io/</id>
  
  <author>
    <name>YouGuess</name>
    
  </author>
  
  <generator uri="http://hexo.io/">Hexo</generator>
  
  <entry>
    <title></title>
    <link href="https://yguess.github.io/2018/03/10/%E6%A0%87%E7%AD%BE%E9%A1%B5%E9%80%9A%E4%BF%A1/"/>
    <id>https://yguess.github.io/2018/03/10/标签页通信/</id>
    <published>2018-03-10T06:08:29.417Z</published>
    <updated>2018-03-13T05:45:54.804Z</updated>
    
    <content type="html"><![CDATA[<p>title: js中的页面间通信<br>date: 2016-8-10<br>tag: javascript</p><hr><h1 id="js中的页面间通信"><a href="#js中的页面间通信" class="headerlink" title="js中的页面间通信"></a>js中的页面间通信</h1><p>本来准备找实习了，由于暑假回家学车，学完后回不去学校，(⊙﹏⊙)。<br>一些找前端实习的小伙伴都被问到了页面间通讯的问题，所以做了一点了解。<br>页面间通信涉及到跨域与不跨域，不跨域的通信比较简单,而跨域通信的方法也有,不过每一种也都有限制。</p><h3 id="不跨域的通信"><a href="#不跨域的通信" class="headerlink" title="不跨域的通信"></a>不跨域的通信</h3><h4 id="1-1-iframe嵌套"><a href="#1-1-iframe嵌套" class="headerlink" title="1.1 iframe嵌套"></a>1.1 iframe嵌套</h4><p>有些页面会通过iframe标签嵌套页面，嵌套页面即作为子页面。父与子页面之间的通信很简单。  </p><pre><code>&lt;!-- 父页面 postMessage.html --&gt;&lt;html&gt;    &lt;head&gt;&lt;/head&gt;    &lt;body&gt;        &lt;input id=&quot;msg&quot; type=&quot;text&quot; placeholder=&quot;再次输入信息&quot;/&gt;        &lt;input type=&quot;button&quot; value=&quot;发送消息&quot; onclick=&quot;sendMsg()&quot;/&gt;        &lt;!-- 子页面 getMessage.html --&gt;        &lt;iframe src=&quot;getMessage.html&quot;&gt;&lt;/iframe&gt;    &lt;/body&gt;&lt;/html&gt;&lt;!-- 子页面 getMessage.html--&gt;&lt;html&gt;    &lt;head&gt;&lt;/head&gt;    &lt;body&gt;        &lt;h3&gt;这里是getMessage.html&lt;/h3&gt;        &lt;div id=&quot;show-msg&quot;&gt;&lt;/div&gt;    &lt;/body&gt;&lt;/html&gt;</code></pre><p>代码:  </p><pre><code>&lt;script&gt;    function sentMsg(){        var msg = document.querySelector(&apos;#msg&apos;);        var data = msg.value;        window.frames[0].document.querySelector(&apos;#show-msg&apos;).innerHTML = data;    }&lt;/script&gt;  </code></pre><p>在父页面中的input中输入内容,点击发送,在子页面中就会显示对应内容。<br>当然,如果父页面中存在多个iframe,只需通过window.frame找到对应的ifrmae,如上传递内容就可以了。  </p><h4 id="1-2-跨标签页通信-window-open"><a href="#1-2-跨标签页通信-window-open" class="headerlink" title="1.2 跨标签页通信 window.open"></a>1.2 跨标签页通信 window.open</h4><p>有时候,当在一个页面中点击链接，打开了一个新的页面，两个页面在相同的域下，可以实现标签页之间的通讯.</p><pre><code>&lt;!-- 父页面 postMessage.html --&gt;&lt;html&gt;    &lt;head&gt;&lt;/head&gt;    &lt;body&gt;        &lt;input type=&quot;button&quot; value=&quot;发送消息&quot; onclick=&quot;sendMsg()&quot;/&gt;        &lt;a href=&quot;getMessage.html&quot; target=&quot;_blank&quot; onclick=&quot;toPage(event)&quot;&gt;点击&lt;/a&gt;    &lt;/body&gt;&lt;/html&gt;</code></pre><p>代码:</p><pre><code>&lt;!-- 父页面 postMessage.html --&gt;&lt;script&gt;    var newPage;    function toPage(evt){        evt.preventDefault(); //阻止默认事件        var url = evt.target.getAttribute(&apos;href&apos;);        newPage = window.open(url,&apos;newPage&apos;);    }    function sentMsg(){        newPage.document.querySelector(&apos;#msg&apos;).innerHTML = &apos;这是postMessage发来的信息&apos;;    }&lt;/script&gt;&lt;!-- 子页面 getMessage.html --&gt;&lt;script&gt;    window.addEventListener(&apos;load&apos;,function(evt){        opener.document.querySelector(&apos;#show-msg&apos;).innerHTML = &apos;load好子页面了&apos;;    },false);&lt;/script&gt;  </code></pre><p>当在postMessage.html页面里点击链接,通过window.open方法打开一个新的页面,如父子页面满足”同源策略”则该方法会返回创建窗口的window对象的引用。getMessage.html添加侦听load事件,通过window.opener获取创建该窗口的window对象的引用,通过该引用可以控制该页面里元素。  </p><p>关于window.open()和window.opener()参见MDN的<a href="https://developer.mozilla.org/zh-CN/docs/Web/API/Window/open" target="_blank" rel="external">window.open</a>和<a href="https://developer.mozilla.org/zh-CN/docs/Web/API/Window/opener" target="_blank" rel="external">window.opener</a>。</p><h3 id="跨域通信"><a href="#跨域通信" class="headerlink" title="跨域通信"></a>跨域通信</h3><p>有时候我们希望能够在不同的域名之间传递数据,但由于浏览器的<a href="http://baike.baidu.com/link?url=1fU9fksoPuJ4PKsH0MwjZXjzkrWTAPjH3pxWCxg3ujz8d5Rrvy1dEXCsxslmSMfUw6bMpHbdBmxRLk47SMPesq" target="_blank" rel="external">“同源策略”</a>,不同域之间的通信只能通过一些技巧来实现。以下是对是否是同源情况的判断:</p><p><table></table></p><p><thead></thead></p><p><tr><br>  <th align="center">编号</th><br>  <th align="center">URL</th><br>  <th align="center">说明</th><br>  <th align="center">是否允许通信</th><br></tr><br></p><p><tbody><tr><br>  <td align="center">1</td><br>  <td align="center"><a href="http://www.a.com/a.js" target="_blank" rel="external">http://www.a.com/a.js</a><br><a href="http://www.a.com/b.js" target="_blank" rel="external">http://www.a.com/b.js</a></td><br>  <td align="center">同一域名下</td><br>  <td align="center">允许</td><br></tr></tbody></p><p><tr><br>  <td align="center">2</td><br>  <td align="center"><a href="http://www.a.com/a/a.js" target="_blank" rel="external">http://www.a.com/a/a.js</a><br><a href="http://www.a.com/b/b.js" target="_blank" rel="external">http://www.a.com/b/b.js</a></td><br>  <td align="center">同一域名下不同文件夹</td><br>  <td align="center">允许</td><br></tr></p><p><tr><br>  <td align="center">3</td><br>  <td align="center"><a href="http://www.a.com:8000/a.js" target="_blank" rel="external">http://www.a.com:8000/a.js</a><br><a href="http://www.a.com/b.js" target="_blank" rel="external">http://www.a.com/b.js</a></td><br>  <td align="center">同一域名，不同端口</td><br>  <td align="center">不允许</td><br></tr></p><p><tr><br>  <td align="center">4</td><br>  <td align="center"><a href="http://www.a.com/a.js" target="_blank" rel="external">http://www.a.com/a.js</a><br><a href="https://www.a.com/b.js" target="_blank" rel="external">https://www.a.com/b.js</a></td><br>  <td align="center">同一域名，不同协议</td><br>  <td align="center">不允许</td><br></tr></p><p><tr><br>  <td align="center">5</td><br>  <td align="center"><a href="http://www.a.com/a.js" target="_blank" rel="external">http://www.a.com/a.js</a><br><a href="http://127.0.0.1/b.js" target="_blank" rel="external">http://127.0.0.1/b.js</a></td><br>  <td align="center">域名和域名对应ip</td><br>  <td align="center">不允许</td><br></tr></p><p><tr><br>  <td align="center">6</td><br>  <td align="center"><a href="http://www.a.com/a.js" target="_blank" rel="external">http://www.a.com/a.js</a><br><a href="http://will.a.com/b.js" target="_blank" rel="external">http://will.a.com/b.js</a></td><br>  <td align="center">主域相同，子域不同</td><br>  <td align="center">不允许</td><br></tr></p><p><tr><br>  <td align="center">7</td><br>  <td align="center"><a href="http://www.a.com/a.js" target="_blank" rel="external">http://www.a.com/a.js</a><br><a href="http://a.com/b.js" target="_blank" rel="external">http://a.com/b.js</a></td><br>  <td align="center">同一域名，不同二级域名（同上）</td><br>  <td align="center">不允许（cookie这种情况下也不允许访问）</td><br></tr></p><p><tr><br>  <td align="center">8</td><br>  <td align="center"><a href="http://www.a.com/a.js" target="_blank" rel="external">http://www.a.com/a.js</a><br><a href="http://www.b.com/b.js" target="_blank" rel="external">http://www.b.com/b.js</a></td><br>  <td align="center">不同域名</td><br>  <td align="center">不允许</td><br></tr><br><br>一般跨域传递数据有3种方法,jsonp、document.domain、window.name来实现。不过，这三种方法都有各自的限制。  </p><p>####2.1 jsonp实现<br>jsonp全称是”json padding”，<a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/JSON" target="_blank" rel="external">json</a>想必已经很清楚了,如果忘了就点击自己重新复习吧。JSONP是一种使用JSON数据的方式，返回的不是JSON对象，是包含JSON对象的javaScript脚本。<br>由于常规使用XMLHttpRequest请求只允许同域下的资源,但是script标签加载js文件却可以跨域加载，比如img标签也可以。通过使用script标签来进行跨域请求，并在响应中返回要执行的script代码，其中可以直接使用JSON传递 javascript对象。即在跨域的服务端生成JSON数据，然后包装成script脚本回传，就不用突破同源策略的限制，解决了跨域访问的问题。  </p><pre><code>&lt;script&gt;    function callback(data){        //处理数据    }    var jsonP = document.createElement(&apos;script&apos;);    jsonP.src = &apos;http://demo.com/server.php?req=callback&apos;;//域名随意起的    document.body.appendChild(jsonP);&lt;/script&gt;</code></pre><p>服务器端的响应代码:  </p><pre><code>&lt;?php     $req = $_GET[&apos;req&apos;];    $data = array(        &apos;data&apos;=&gt;&apos;这是请求的数据&apos;    );    echo $req.&quot;(json_encode($data))&quot;;?&gt;</code></pre><p>这其实就是JSONP的简单实现。客户端创建一个回调函数，然后在远程服务上调用这个函数并且将JSON 数据形式作为参数传递，完成回调。即将服务器的json数据填充(padding)作为回调函数的参数。<br>jsonp方式跨域也有缺陷,首先只能是通过GET方式请求数据,若操作成功,就顺利执行。出现失败则不会有提示,例如不能从服务器捕捉到 404 错误，也不能取消或重新开始请求。当然超时后就不用管他了。同时也需要服务器相应的配合,处理请求才行。</p><p>####2.2 document.domain<br>每一个页面都有document.domain属性,调用这个属性,返回当前文档的域名。也可以对该属性进行赋值，不过值必须是包含基础域名的值(必须属于同一个基础域名!而且所用的协议，端口都要一致)。<br>例如：</p><pre><code>//http://willing.a.com/a.html与http://will.a.com/b.html//a.html&lt;html&gt;    &lt;head&gt;        &lt;script&gt;            docuemnt.domain = &apos;a.com&apos;;        &lt;/script&gt;    &lt;/head&gt;    &lt;body&gt;    &lt;frame src=&quot;http://will.a.com/b.html&quot;&gt;&lt;/iframe&gt;    &lt;/body&gt;&lt;/html&gt;//b.html&lt;html&gt;    &lt;head&gt;        &lt;script&gt;            docuemnt.domain = &apos;a.com&apos;;        &lt;/script&gt;    &lt;/head&gt;    &lt;body&gt;&lt;/body&gt;&lt;/html&gt;</code></pre><p>两个页面处于同一个基础域名下不同子域名下,他们之间js跨域(子域)相互调用，需要在head标签中显式设置同一基础域名,否则会失败。<br>通过这种方式，可以实现跨子域的数据传递，而无法实现跨基础域名的数据传递。<br>另外,Html5的localStorage也可以通过设置document.domain实现跨子域的数据传递。  </p><p>####2.3 window.name<br>每个标签在打开的时候都会存在window.name属性,若没有设置一般为空。window.open函数调用时传递的第二参数即为指定创建窗口的name值。<br>浏览器中当一个标签页打开到关闭之间,window.name的值不变,即使在期间访问了不同域名的网站,name值都是空或手动设置的值。在浏览器控制台输入代码:</p><pre><code>window.name = &apos;YouGuess&apos;;location.href = &apos;http://www.qq.com&apos;;  </code></pre><p>在一个页面中通过iframe嵌入的跨域页面,也可以实现跨域传值,不过该值的大小有所限制(大约2M)。  </p><pre><code>&lt;!-- 父页面 postMessage.html --&gt;&lt;html&gt;    &lt;head&gt;&lt;/head&gt;    &lt;body&gt;        &lt;div id=&quot;show-msg&quot;&gt;&lt;/div&gt;        &lt;input type=&quot;button&quot; value=&quot;获取子页面name&quot; onclick=&quot;getChildName()&quot;/&gt;        &lt;!-- 子页面 getMessage.html --&gt;        &lt;iframe src=&quot;www.baidu.com&quot;&gt;&lt;/iframe&gt;    &lt;/body&gt;&lt;/html&gt;&lt;!-- 子页面 getMessage.html--&gt;&lt;html&gt;    &lt;head&gt;&lt;/head&gt;    &lt;body&gt;    &lt;/body&gt;&lt;/html&gt;  </code></pre><p>代码：</p><pre><code>&lt;script&gt;    &lt;!-- 父页面 postMessage.html --&gt;    function getChildName(){        var show = document.querySelector(&apos;#show-msg&apos;);        var childName = window.frames[0].contentWidth.name;        show.innerHTML = childName;    }    &lt;!-- 子页面 getMessage.html--&gt;    window.addEventListener(&apos;load&apos;,function(){        window.name = &apos;YouGuess&apos;;    })&lt;/script&gt;  </code></pre><p>当在iframe中的页面设置好name的值,点击父页面的按键,即可显示子页面的name属性。</p><p>###3. HTML5的postMessage<br>HTML5提供了<a href="https://developer.mozilla.org/zh-CN/docs/Web/API/Window/postMessage" target="_blank" rel="external">postMessage</a>方法，该方法既可以跨域通信也可以用来不跨域的通信，不过在IE中目前只支持IE8+，其他浏览器基本全面支持。</p><blockquote><p>otherWindow.postMessage(data,origin)<br>       -targetSrc指目标窗口或iframe<br>       -data指要传递的数据，html5规范可以使js的任意基本类型和可复制对象(ie8、9除外)<br>       -origin指明目标窗口的源(协议+主机+端口号[+URL]，URL会被忽略，所以可以不写)定和当前窗口同源的话设置为”/“,若”*”则代表任何页面。</p></blockquote>]]></content>
    
    <summary type="html">
    
      
      
        &lt;p&gt;title: js中的页面间通信&lt;br&gt;date: 2016-8-10&lt;br&gt;tag: javascript&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id=&quot;js中的页面间通信&quot;&gt;&lt;a href=&quot;#js中的页面间通信&quot; class=&quot;headerlink&quot; title=&quot;js中的页面间
      
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>Vue组件的data的函数</title>
    <link href="https://yguess.github.io/2018/03/10/Vue%E7%BB%84%E4%BB%B6%E7%9A%84Data/"/>
    <id>https://yguess.github.io/2018/03/10/Vue组件的Data/</id>
    <published>2018-03-09T16:00:00.000Z</published>
    <updated>2018-03-13T05:50:44.765Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Vue组件的data的函数"><a href="#Vue组件的data的函数" class="headerlink" title="Vue组件的data的函数"></a>Vue组件的data的函数</h2><p>在使用vue开发时，data通常都是一个Object。而在创建Vue组件时，官文文档要求data必须是一个函数，并推荐以下形式： </p><pre>    data(){        return {}    }</pre><p>开始不是很明白，官方给了<a href="https://cn.vuejs.org/v2/guide/components.html#data-%E5%BF%85%E9%A1%BB%E6%98%AF%E5%87%BD%E6%95%B0" target="_blank" rel="external">例子</a>。说实话因为自己反应比较慢，开始没怎么理解意思。后面看了别人的分析才明白。</p><p>其实官方例子的意思是：Vue组件中，如果data是一个对象，多个组件在使用时，就相当于引用了同一个data对象，这样的话组件之间数据就会共享，并会相互影响。而当我们通过函数返回一个对象，这样组件之间数据是有各自作用域，而不会相互影响。而尤大这样做，也是因为js语言自己的问题。</p><h3 id="js的继承"><a href="#js的继承" class="headerlink" title="js的继承"></a>js的继承</h3><p>Vue组件的使用，是需要通过Vue组件实例的Component进行注册。在注册后，自定义组件对象会被构造成Vue组件。而在相同的Vue中注册的组件，他们被相同的构造器构造，继承的特性也一样。js的继承是原型继承，不同的实例继承相同的对象，那不同实例之间继承的属性就会共享，一个修改另一个也被修改。</p><p><pre><br>let Component = function(){}<br>Component.prototype.data = {}</pre></p><p>let cp1 = new Component(),<br>    cp2 = new Component()</p><p>cp1.data === cp2.data  // true<br><br>此时,cp1和cp2内部的data就是共用的。<br>而当使用函数时,原型上的data是函数，并将各自的实际data对象赋予实例对象。</p><p><pre><br>let Component = function(obj){<br>    // 对需要构造的组件对象进行处理<br>    this.data = obj.data()<br>}<br>Component.prototype.data = function(){<br>    return {}<br>}</pre></p><p>let cp1 = new Component({ data: function(){ return {} } }),<br>    cp2 = new Component({ data: function(){ return {} } })</p><p>cp1.data === cp2.data  // false<br><br>这样不同的实例data引用不同，不会共享。<br><a href="https://cn.vuejs.org/v2/api/#data" target="_blank" rel="external">Vue的data原文</a></p><blockquote><p>当一个组件被定义，data 必须声明为返回一个初始数据对象的函数，因为组件可能被用来创建多个实例。如果 data 仍然是一个纯粹的对象，则所有的实例将共享引用同一个数据对象！通过提供 data 函数，每次创建一个新实例后，我们能够调用 data 函数，从而返回初始数据的一个全新副本数据对象。</p></blockquote>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h2 id=&quot;Vue组件的data的函数&quot;&gt;&lt;a href=&quot;#Vue组件的data的函数&quot; class=&quot;headerlink&quot; title=&quot;Vue组件的data的函数&quot;&gt;&lt;/a&gt;Vue组件的data的函数&lt;/h2&gt;&lt;p&gt;在使用vue开发时，data通常都是一个Object
      
    
    </summary>
    
    
      <category term="Vue.js" scheme="https://yguess.github.io/tags/Vue-js/"/>
    
  </entry>
  
  <entry>
    <title>转盘的简单实现</title>
    <link href="https://yguess.github.io/2018/02/25/%E8%BD%AC%E7%9B%98%E7%9A%84%E7%AE%80%E5%8D%95%E5%AE%9E%E7%8E%B0/"/>
    <id>https://yguess.github.io/2018/02/25/转盘的简单实现/</id>
    <published>2018-02-24T16:00:00.000Z</published>
    <updated>2018-03-13T05:58:24.062Z</updated>
    
    <content type="html"><![CDATA[<h3 id="转盘的简单实现"><a href="#转盘的简单实现" class="headerlink" title="转盘的简单实现"></a>转盘的简单实现</h3><p>通过代码实现抽奖的转盘，使用html、css、js实现(并未使用canvas)。参考例子：<a href="https://juejin.im/post/5a2dd40bf265da43176a1482" target="_blank" rel="external">JS写的一个抽奖小Demo从普通写法到设计模式再向ES6的进阶路程</a>。</p><h4 id="实现"><a href="#实现" class="headerlink" title="实现"></a>实现</h4><h5 id="样式实现"><a href="#样式实现" class="headerlink" title="样式实现"></a>样式实现</h5><p>ul是转盘部分，将转盘划分成12份。pointer则是点击转动部分。主要的html结构如下：</p><blockquote><pre><code>&lt;ul class=&quot;turntable&quot;&gt;    &lt;li&gt;&lt;span&gt;1&lt;/span&gt;&lt;/li&gt;    &lt;li style=&quot;transform: rotateZ(30deg);&quot;&gt;&lt;span&gt;2&lt;/span&gt;&lt;/li&gt;    &lt;li style=&quot;transform: rotateZ(60deg);&quot;&gt;&lt;span&gt;3&lt;/span&gt;&lt;/li&gt;    &lt;li style=&quot;transform: rotateZ(90deg);&quot;&gt;&lt;span&gt;4&lt;/span&gt;&lt;/li&gt;    &lt;li style=&quot;transform: rotateZ(120deg);&quot;&gt;&lt;span&gt;5&lt;/span&gt;&lt;/li&gt;    &lt;li style=&quot;transform: rotateZ(150deg);&quot;&gt;&lt;span&gt;6&lt;/span&gt;&lt;/li&gt;    &lt;li style=&quot;transform: rotateZ(180deg);&quot;&gt;&lt;span&gt;7&lt;/span&gt;&lt;/li&gt;    &lt;li style=&quot;transform: rotateZ(210deg);&quot;&gt;&lt;span&gt;8&lt;/span&gt;&lt;/li&gt;    &lt;li style=&quot;transform: rotateZ(240deg);&quot;&gt;&lt;span&gt;9&lt;/span&gt;&lt;/li&gt;    &lt;li style=&quot;transform: rotateZ(270deg);&quot;&gt;&lt;span&gt;10&lt;/span&gt;&lt;/li&gt;    &lt;li style=&quot;transform: rotateZ(300deg);&quot;&gt;&lt;span&gt;11&lt;/span&gt;&lt;/li&gt;    &lt;li style=&quot;transform: rotateZ(330deg);&quot;&gt;&lt;span&gt;12&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class=&quot;pointer&quot; &gt;    &lt;p onclick=&quot;startRotate()&quot;&gt;开始抽奖&lt;/p&gt;&lt;/div&gt;    </code></pre><p>实现的效果如图： <figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="/images/zhuanpan1.png" alt="" title="">                </div>                <div class="image-caption"></div>            </figure><br>ul相对定位后，li设为绝对定位。li样式使用border做成三角形，父元素设置overflow: hidden。然后再对每个li进行rotate变换就可以实现如图的形状。再将开始按钮放置到中间盖住中心部分，就实现如图的整体效果。</p></blockquote><h5 id="转盘转动实现"><a href="#转盘转动实现" class="headerlink" title="转盘转动实现"></a>转盘转动实现</h5><p>其实在点击的时候，就已经确定好指针要指向的部分。转盘分为12份，则随机一个1-12的数，每一部分在圆中所占据的角度是30°。例如：第一部分(1)占据了345-15°，则12占据了16-45°…以此类推。<br>因为要制作一个转动的过程，所以需要再随机一个数，这个数就代表要转的圈数，圈数乘上360，加上选中的数所在的度数，即   </p><blockquote><p>转盘转动的总度数 =  圈数 * 360° + 度数   </p></blockquote><p>但由于每一部分占据的是一个范围，所以指针最后所在的区间范围(以12为例)：    </p><blockquote><p>max度数 = 圈数 <em> 360° + 45°<br>min度数 = 圈数 </em> 360° + 16°     </p></blockquote><p>这里肯可能有疑问：12在圆中为什么是16-45°，而不是316-345°。原因是：转盘是按顺时针方向进行转动的，所以当转盘转动时，1过后指针指向的是12、11、10、9…。所以在计算对应位置时，是按1、12、11…的顺序进行的。同时由于1占据345-15°这样一个范围，为了方便计算，我们将其范围设为-16-15°。同时，为了避免指针在转动结束时指向两个部分的交界处，显示不明显，所以我们在左右各设置一个缓冲区，让指针最后不会停留在缓冲区。如图：<br><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="/images/zhuanpan2.png" alt="" title="">                </div>                <div class="image-caption"></div>            </figure>指针最后只会落在红线之间。    </p><p>为了转盘在开始转动和结束时带有速度递增与递减的效果，需要设置一个加速度、减速度，还要计算出在减速过程中所需要转过的度数，得到开始减速的度数</p><blockquote><p>min度数 - 减速过程中转过的度数 = 开始减速的度数</p></blockquote><p>数据预处理的逻辑如下：<br>&gt;<br>    function prepareData(number){<br>            // 默认12格<br>            number ? ‘’ : number = 12;<br>            let everyDeg = 360 / number,<br>                bufferDeg = 8, // 左右各缓冲4deg<br>                numbersDeg = [];<br>            // 每格所占的度数<br>            let initCount = (everyDeg-bufferDeg)/2;</p><pre><code>    numbersDeg[1] = [-initCount , initCount];    for(let i=number ; i &gt;= 2 ; i--){        numbersDeg[i+&apos;&apos;] = [initCount+bufferDeg+1 , initCount+everyDeg];        initCount += everyDeg;    }    let randomValue = Math.floor(Math.random()*number)+1, // 随机被选中的数        rotateCount = Math.floor(Math.random()*3)+6, // 旋转6-8圈        maxStep = Math.floor(Math.random()*3)+6, // 最大转速为6-8(deg)        stepPlus = 0.05, // 转动的加速度        stepLess = 0.02, // 转动的减速度        step = 0, // 初始变化的角度        initDeg = 0; // 初始转过角度    let totalDeg = rotateCount * 360,        maxDeg = totalDeg + numbersDeg[randomValue][1],        minDeg = totalDeg + numbersDeg[randomValue][0],        // 每次变化的角度在衰减过程中是等差数列，则在衰减过程中会转过的度数之和        // 公式 ((startStep + maxStep) * n) / 2        restDeg = (maxStep * (maxStep / stepLess)) /2;    return {        result: randomValue,        maxDeg: maxDeg,        minDeg: minDeg,        maxStep: maxStep,        step: 0,        initDeg: 0,        stepPlus: stepPlus,         stepLess: stepLess,         restDeg: restDeg,        rotateState: &apos;stop&apos; // 当前转盘状态[&apos;plus&apos;,&apos;less&apos;,&apos;stop&apos;]     };}    </code></pre><p>开始抽奖，通过js代码改变转盘的rotate度数，就可以实现转盘的转动。不过还要考虑加速、减速、停止。</p><blockquote><pre><code>function rotate(){    turntable.style.transform = &quot;rotateZ(&quot;+data.initDeg+&quot;deg)&quot;;    // 计算下一次转盘的度数    data.initDeg += data.step;</code></pre></blockquote><pre><code>    // 加速    if(data.step &lt; data.maxStep &amp;&amp; data.rotateState == &apos;plus&apos;){        data.step += data.stepPlus;    }    // 减速    else if(data.initDeg &gt;= data.minDeg - data.restDeg){        data.step -= data.stepLess;        data.rotateState = &apos;less&apos;;    }    if(data.initDeg &gt;= data.minDeg &amp;&amp; data.initDeg &lt;= data.maxDeg &amp;&amp; data.step &lt; 0){        alert(data.result);        resetTurntable();        console.log(`step: ${data.step}, deg: ${data.initDeg}`);    }else{        window.requestAnimationFrame(rotate);    }}</code></pre><p>以上便是一个转盘实现的大致逻辑与代码。最后转动的效果如图：</p><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="/images/zhuanpan3.gif" alt="" title="">                </div>                <div class="image-caption"></div>            </figure>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h3 id=&quot;转盘的简单实现&quot;&gt;&lt;a href=&quot;#转盘的简单实现&quot; class=&quot;headerlink&quot; title=&quot;转盘的简单实现&quot;&gt;&lt;/a&gt;转盘的简单实现&lt;/h3&gt;&lt;p&gt;通过代码实现抽奖的转盘，使用html、css、js实现(并未使用canvas)。参考例子：&lt;a hr
      
    
    </summary>
    
    
      <category term="javascript" scheme="https://yguess.github.io/tags/javascript/"/>
    
  </entry>
  
  <entry>
    <title>es6函数参数</title>
    <link href="https://yguess.github.io/2017/11/17/es6%E5%87%BD%E6%95%B0%E5%8F%82%E6%95%B0%E9%BB%98%E8%AE%A4%E5%80%BC%E7%9A%84%E4%BD%9C%E7%94%A8%E5%9F%9F/"/>
    <id>https://yguess.github.io/2017/11/17/es6函数参数默认值的作用域/</id>
    <published>2017-11-16T16:00:00.000Z</published>
    <updated>2018-03-10T06:11:50.510Z</updated>
    
    <content type="html"><![CDATA[<p>在阮一峰的《es6入门》中，关于函数参数存在默认值时，有如下的代码</p><pre>// 代码1var x = 1;function foo(x, y = function() { x = 2; }) {  var x = 3;  y();  console.log(x);}foo() // 3x // 1</pre>这里按理说开始以为y内部的x指向的是外部环境下的x,即x=1。然而实际却不是。这是作用域的原因。在es6标准标准中，关于函数参数预设值的实现：>看规范9.2.12 FunctionDeclarationInstantiation部分    If default value parameter initializers exist, a second Environment Record is created for the body declarations.    步骤    27Else,    1.NOTE A separate Environment Record is needed to ensure that closures created by expressions in the formal parameter list do not have visibility of declarations in the function body.    2.Let varEnv be NewDeclarativeEnvironment(env).    3.Let varEnvRec be varEnv's EnvironmentRecord.大致意思就是在函数的参数存在预设值的时候，会创建一个独立的作用域，整个参数部分都会包含其中。若不存在预设值，则不会创建参数的作用域。   <pre>// 代码2let foo = 'outer';function bar(func = () => foo) {  let foo = 'inner';  console.log(func());}bar(); // outer</pre>在上面这种情况下，func = () => foo。由于func内并没有定义foo，在调用func时func会沿着作用域链在外部环境中找foo，所以func()返回outer。而在代码1中，函数参数的作用域中，存在定义的变量x，故foo()执行时，接收赋值的变量是参数作用域中的x而不是foo函数体内定义的x变量。回到代码1中，函数参数所在的作用域和函数内部的作用域相互独立，所以实际上存在3个变量x。<pre>// 代码3var x = 1;function foo(x=2, y = function(){ console.log(x); }) {  var x = 3;  y();  console.log(x);}foo() // 2       // 3x;    // 1</pre><p>还有一个问题是关于作用域。js中，作用域是静态(词法)作用域，即函数和变量的作用域在它们被定义的时候就已经决定了。</p><p><pre><br>// 代码4<br>var x = 1;<br>function outer(){<br>    console.log(x);<br>}<br>function foo() {<br>  var x = 3;<br>  var f1 = function(){<br>      return x;<br>  }</pre></p><p>  outer();<br>  return f1;<br>}<br>var func = foo(); // 1<br>func(); // 3<br><br>当一个函数内输出或返回一个变量值时，会现在函数内部查找对应的变量，存在即返回。若不存在，则会通过保存的作用域链向外部作用域查找。由于js是静态作用域，所以outer无论在哪儿调用，输出的都是全局作用域下的x(1),f1函数返回的则是foo函数内部定义的x(3)。如果是动态作用域，则outer应该输出3。</p><p>参考：<br><a href="https://www.zhihu.com/question/60394151" target="_blank" rel="external">ES6中函数参数默认值为函数的问题？</a></p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;p&gt;在阮一峰的《es6入门》中，关于函数参数存在默认值时，有如下的代码&lt;/p&gt;
&lt;pre&gt;
// 代码1
var x = 1;
function foo(x, y = function() { x = 2; }) {
  var x = 3;
  y();
  console.
      
    
    </summary>
    
    
      <category term="javascript" scheme="https://yguess.github.io/tags/javascript/"/>
    
  </entry>
  
  <entry>
    <title>Viewport</title>
    <link href="https://yguess.github.io/2017/11/17/viewport/"/>
    <id>https://yguess.github.io/2017/11/17/viewport/</id>
    <published>2017-11-16T16:00:00.000Z</published>
    <updated>2018-03-13T05:59:41.254Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Viewport学习记录"><a href="#Viewport学习记录" class="headerlink" title="Viewport学习记录"></a>Viewport学习记录</h2><p>在开发移动端项目时，以前都只知道在head中添加以下代码就可以使得在web的页面在移动端也显示的相对好看点，但具体不是很清楚原理。<br><code>&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no&quot; /&gt;</code><br>最近项目上写了一个移动端的小项目，为了兼容移动端的样式，使用了手淘的flexible.js，rem单位取代px。<br>rem我知道是以根元素(html)的字体宽度作为基准进行计算。<br>参考了以下两篇博文:<br><a href="http://lvdada.org/2016/01/28/viewport-and-flexibleJs/" target="_blank" rel="external">viewport探索 flexible.js解读</a><br><a href="http://www.html-js.com/article/Mobile-terminal-H5-mobile-terminal-HD-multi-screen-adaptation-scheme%203041" target="_blank" rel="external">移动端高清、多屏适配方案</a></p><h5 id="物理像素、独立像素、设备像素比"><a href="#物理像素、独立像素、设备像素比" class="headerlink" title="物理像素、独立像素、设备像素比"></a>物理像素、独立像素、设备像素比</h5><p>屏幕通常由很多像素点构成，我们经常说的分辨，例如1920<em>1080，就是指屏幕有1920\</em>1080个像素构成，是最小的单位，也是厂商定好的，无法更改。<br>设备的独立像素也称css像素，可以认为是将屏幕分成坐标系，每一个点代表一个css像素点，单位是px。独立像素和css像素之间的计算由相关系统计算，存在一定的对应关系。<br>设备像素比，定义了物理像素和css像素的关系，代表了1个css可以代表多少个物理像素点。计算公式：</p><blockquote><p>  设备像素比 = 物理像素 / css像素</p></blockquote><p>目前，js可以通过window.devicePixelRatio获取到设备像素比，css可以使用-webkit-device-pixel-ratio(其他的内核使用对应的标志)获得并配合media query使用。</p><h6 id="两个像素的关系"><a href="#两个像素的关系" class="headerlink" title="两个像素的关系"></a>两个像素的关系</h6><p>在PC上浏览器的宽度的调整并且宽度计算是通过物理像素，这使得在页面不缩放(100%)的情况下，1个css像素等于1个物理像素.放大到200%，一个css像素等于4个物理像素，css像素数减半。<br><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="/images/csspixels_100.gif" alt="1px==1px" title="">                </div>                <div class="image-caption">1px==1px</div>            </figure> 100%时，1css像素大小与设备像素相等<br><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="/images/csspixels_in.gif" alt="拉伸" title="">                </div>                <div class="image-caption">拉伸</div>            </figure> 放大过程,css像素被拉伸<br><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="/images/csspixels_out.gif" alt="缩小" title="">                </div>                <div class="image-caption">缩小</div>            </figure> 缩小过程,css像素被缩小</p><h5 id="viewport"><a href="#viewport" class="headerlink" title="viewport"></a>viewport</h5><p>浏览器中，百分比宽都是通过父元素的宽计算得到的。body的宽取自html,而html则是取自viewport,而viewport则取自浏览器窗口。viewport是用来约束顶级元素html的，它并不是一个html结构。</p><ul><li>screen.width</li><li>winodw.innerWidth</li><li>document.documentElement.clientWidth</li><li>document.documentElement.offsetwidth</li></ul><p>innerWidth获取浏览器可见内容区域的宽度(包含滚动条)<br><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="/images/innerWidth.png" alt="" title="">                </div>                <div class="image-caption"></div>            </figure><br>clientWidth获取viewport的宽(不包含滚动条)<br><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="/images/clientWidth.jpg" alt="" title="">                </div>                <div class="image-caption"></div>            </figure><br>offsetwid获取html的宽，之前说过viewport是限制html的内容区域，未修改时，html的宽都是100%继承viewport的宽。<br>在PC上，我们一般不会太关注这些。因为PC浏览器viewport由浏览器窗口大小决定，而移动端则会有明显的问题。</p><h4 id="移动端的viewport"><a href="#移动端的viewport" class="headerlink" title="移动端的viewport"></a>移动端的viewport</h4><p>在移动端显示PC的网页，实际情况如下图，这个viewport称为<strong>布局视口(layout viewport)</strong>。而网页显示在屏幕可视区域的部分成为视觉视口(visual viewport)。<br><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="/images/layoutViewport.png" alt="" title="">                </div>                <div class="image-caption"></div>            </figure><br><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="/images/visualviewport.jpg" alt="" title="">                </div>                <div class="image-caption"></div>            </figure>。<br>默认情况下，大多数移动端浏览器会将视觉视口这个框缩放到与布局视口相同，则会看到一下情况：<br><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="/images/mobile_web_page.png" alt="" title="">                </div>                <div class="image-caption"></div>            </figure></p><p>关于这两个视口的解释：</p><blockquote><p>把layout viewport想像成为一张不会变更大小或者形状的大图。现在想像你有一个小一些的框架，你通过它来看这张大图。（译者：可以理解为「管中窥豹」）这个小框架的周围被不透明的材料所环绕，这掩盖了你所有的视线，只留这张大图的一部分给你。你通过这个框架所能看到的大图的部分就是visual viewport。当你保持框架（缩小）来看整个图片的时候，你可以不用管大图，或者你可以靠近一些（放大）只看局部。你也可以改变框架的方向，但是大图（layout viewport）的大小和形状永远不会变。<br>visual viewport是页面当前显示在屏幕上的部分。用户可以通过滚动来改变他所看到的页面的部分，或者通过缩放来改变visual viewport的大小。</p></blockquote><p>在移动端，布局视口仍然是用来限制网页布局部分的视口，其大小仍然可以用clientWidth/Hieght得到。而视觉视口的大小则可以用innerWidth/height获取，并且取到的都是css像素。</p><p>######理想视口(ideal viewport)<br>所谓理想视口，就是在页面初始渲染好后，不经过用户缩放或拖动页面就能完美显示网页内容的视口。理想视口在不同的设备是一个不同的值，一般有设备设置，可通过这个<a href="http://viewportsizes.com/?filter=iphone" target="_blank" rel="external">链接</a>查询不同机型的理想视口。</p><h5 id="viewport-meta标签"><a href="#viewport-meta标签" class="headerlink" title="viewport meta标签"></a>viewport meta标签</h5><p>为了解决移动端视口，苹果最先引入了viewport meta以解决这个问题。属性：</p><blockquote><p>width：用来设置 layout viewport 的宽度，可以设为字符串device-width。<br>height：和 width 相对应，指定高度。<br>initial-scale：初始缩放比例，也即是当页面第一次 load 的时候缩放比例。<br>maximum-scale：允许用户缩放到的最大比例。<br>minimum-scale：允许用户缩放到的最小比例。<br>user-scalable：用户是否可以手动缩放</p></blockquote><p>因为布局视口是限制html布局的，所以只要给是布局视口设一个合适的值，视觉视口自动缩放在屏幕上就能合理的显示所有内容。我们一般设置width=device-width，浏览器会自动设置布局视口为理想视口，但还有一个initial-scale=1。<br>之前提到过，视觉视口会自动缩放到匹配布局视口，使得完整显示整个网页，但这样内容往往很小，需要放大才能看清。理想视口与视觉视口、缩放值之间的关系为：</p><blockquote><pre><code>visual viewport width = ideal viewport width / zoom factor</code></pre></blockquote><p>所以initial-scale=1，所做的事就是使得视觉视口、理想视口、布局视口三者保持一致。同时，由于某些安卓设备只有在initial-scale=1的情况下才会计算出视觉视口，并设置成理想视口，所有安卓设备下会手动设置为1。</p><h5 id="缩放"><a href="#缩放" class="headerlink" title="缩放"></a>缩放</h5><p>设备像素比（dpr），代表的是1个css像素在某个方向上能占据的物理像素点个数。<br>理想视口在设备是提供的，视觉视口中的像素是相对于它缩放得到的。放大时，视觉视口的css像素变少，反之则增多。而缩放的实质也是在改变一个css像素包含的设备像素个数。<br>理想视口有设备提供，其宽度也就是设备的独立像素。</p><blockquote><p>由以上公式可知: 视觉视口 / 理想视口 = 1 / scale </p></blockquote><p>当在设置了meta viewport之后，</p><blockquote><p>布局视口的宽==视觉视口的宽\==屏幕的宽</p></blockquote><p>故可知：dpr == 1 / scale</p><p>知道这些基础知识后，再去看flexible.js差不多应该就会理解工作原理了。</p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h2 id=&quot;Viewport学习记录&quot;&gt;&lt;a href=&quot;#Viewport学习记录&quot; class=&quot;headerlink&quot; title=&quot;Viewport学习记录&quot;&gt;&lt;/a&gt;Viewport学习记录&lt;/h2&gt;&lt;p&gt;在开发移动端项目时，以前都只知道在head中添加以下代码就可
      
    
    </summary>
    
    
      <category term="javascript" scheme="https://yguess.github.io/tags/javascript/"/>
    
  </entry>
  
  <entry>
    <title>获取网页中元素所有的宽、高获取方式</title>
    <link href="https://yguess.github.io/2017/10/26/%E5%AE%BD%E9%AB%98%E8%8E%B7%E5%8F%96%E6%96%B9%E5%BC%8F/"/>
    <id>https://yguess.github.io/2017/10/26/宽高获取方式/</id>
    <published>2017-10-25T16:00:00.000Z</published>
    <updated>2017-10-26T02:16:47.378Z</updated>
    
    <content type="html"><![CDATA[<p>###获取网页中元素所有的宽、高获取方式</p><blockquote><p>网页可见区域宽：document.body.clientWidth<br>网页可见区域高：document.body.clientHeight<br>网页可见区域宽：document.body.offsetWidth (包括边线的宽)<br>网页可见区域高：document.body.offsetHeight (包括边线的宽)<br>网页正文全文宽：document.body.scrollWidth<br>网页正文全文高：document.body.scrollHeight<br>网页被卷去的高：document.body.scrollTop<br>网页被卷去的左：document.body.scrollLeft<br>网页正文部分上：window.screenTop<br>网页正文部分左：window.screenLeft<br>屏幕分辨率的高：window.screen.height<br>屏幕分辨率的宽：window.screen.width<br>屏幕可用工作区高度：window.screen.availHeight<br>屏幕可用工作区宽度：window.screen.availWidth   </p></blockquote>]]></content>
    
    <summary type="html">
    
      
      
        &lt;p&gt;###获取网页中元素所有的宽、高获取方式&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;网页可见区域宽：document.body.clientWidth&lt;br&gt;网页可见区域高：document.body.clientHeight&lt;br&gt;网页可见区域宽：document.body
      
    
    </summary>
    
    
      <category term="js" scheme="https://yguess.github.io/tags/js/"/>
    
  </entry>
  
  <entry>
    <title>初识块级格式化上下文(Block Formatting Contexts)</title>
    <link href="https://yguess.github.io/2017/10/26/%E5%9D%97%E7%BA%A7%E6%A0%BC%E5%BC%8F%E5%8C%96%E4%B8%8A%E4%B8%8B%E6%96%87/"/>
    <id>https://yguess.github.io/2017/10/26/块级格式化上下文/</id>
    <published>2017-10-25T16:00:00.000Z</published>
    <updated>2017-10-26T02:16:00.600Z</updated>
    
    <content type="html"><![CDATA[<p>#初识块级格式化上下文(Block Formatting Contexts)</p><p>##前言<br>html文档中元素的定位有3种方式(普通流、绝对定位、浮动)，除普通流以外，浮动与绝对定位都会导致元素脱离普通流，按照各自的方式进行定位。<br>带有BFC属性的容器属于普通流的一种。</p><p>##块级格式化上下文 (BFC)<br>块格式化上下文是页面 CSS 视觉渲染的一部分。它是用于决定块盒子的布局及浮动相互影响范围的一个区域。</p><p>BFC是元素在拥有某些特定属性才显示的一种属性，有BFC特性的元素和其他普通流中的元素在样式上没有区别。但在功能上，具有BFC的容器内部与外部隔离，即容器内部的元素不会再布局上影响外部元素。</p><p>有BFC属性的容器可以包含浮动元素、会阻止外边距折叠、可以阻止元素被浮动元素覆盖。</p><p>##如何触发BFC<br>满足下面任意一个条件的元素会触发BFC:</p><blockquote><ul><li>根元素或其它包含它的元素</li><li>浮动 (元素的 float 不为 none)</li><li>绝对定位元素 (元素的 position 为 absolute 或 fixed)</li><li>行内块 inline-blocks (元素的 display: inline-block)</li><li>表格单元格 (元素的 display: table-cell，HTML表格单元格默认属性)</li><li>表格标题 (元素的 display: table-caption, HTML表格标题默认属性)</li><li>overflow 的值不为 visible的元素</li><li>弹性盒 flex boxes (元素的 display: flex 或 inline-flex)</li></ul></blockquote><p>以上是  <a href="https://developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/Block_formatting_context" target="_blank" rel="external">MDN</a> 上引发BFC属性的条件。</p><p>需要注意的是，”display:table” 本身并不产生 BFC，而是由它产生匿名框，匿名框中包含 “display:table-cell” 的框会产 BFC。 总之，对于 “display:table” 的元素，产生 BFC 的是匿名框而不是 “display:table”。</p><p>##BFC特性</p><p>###1. BFC可以包含浮动元素<br>通常，浮动的元素会脱离普通流，不仅会影响兄弟元素，也会影响父容器以及父容器兄弟元素。对于父容器，最直观的就是会使父容器高度塌陷<br><img src="http://img.blog.csdn.net/20160328140223107" alt="未浮动"></p><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="http://img.blog.csdn.net/20160328140318873" alt="浮动" title="">                </div>                <div class="image-caption">浮动</div>            </figure><p>给父容器添加overflow:hidden属性，使其引起BFC属性.<br><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="http://img.blog.csdn.net/20160328140822782" alt="这里写图片描述" title="">                </div>                <div class="image-caption">这里写图片描述</div>            </figure></p><p>###2. 阻止外边距折叠<br>两个相连的 div 在垂直上的外边距会发生叠加。<br><br>详细的解释：仅当两个块级元素相邻并且在同一个块级格式化上下文时，它们垂直方向之间的外边距才会叠加。也就是说，即便两个块级元素相邻，但当它们不在同一个块级格式化上下文时它们的边距也不会折叠。因此，阻止外边距折叠只需产生新的 BFC 。</p><p>这里父容器的上下设置了20px的外边距，而p元素有1em的上下外边距。可以看到第一个p元素与父容器顶部没有间距，两者外边距产生重叠。<br><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="http://img.blog.csdn.net/20160328140845422" alt="外边折叠" title="">                </div>                <div class="image-caption">外边折叠</div>            </figure><br>父容器添加overflow:hidden属性，使其引起BFC属性.这里仅第一个p元素与父容器的外边距未折叠，p元素之间外边距折叠。<br><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="http://img.blog.csdn.net/20160328140945576" alt="p元素外边距未折叠" title="">                </div>                <div class="image-caption">p元素外边距未折叠</div>            </figure><br>将中间的p元素用一个div包裹，并添加overflow:hidden属性，使其引起BFC属性.<br><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="http://img.blog.csdn.net/20160328141148969" alt="这里写图片描述" title="">                </div>                <div class="image-caption">这里写图片描述</div>            </figure></p><p>###3. 阻止元素被浮动元素覆盖<br>上面说过，浮动元素会对兄弟元素造成影响。若兄弟元素是块级元素，则会与浮动元素重叠，位于浮动元素之下。若为内联元素，则依次从左至右排列。<br><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="http://img.blog.csdn.net/20160328141331393" alt="覆盖" title="">                </div>                <div class="image-caption">覆盖</div>            </figure><br><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="http://img.blog.csdn.net/20160328141351549" alt="未覆盖" title="">                </div>                <div class="image-caption">未覆盖</div>            </figure></p><p>但是若子元素display:inline-block，则子元素宽度之和大于父容器宽度，则最后宽度相加超过父容器宽度的子元素换行显示。</p><p>##BFC处理浮动<br>通常我们清除浮动，方法有几种：</p><ul><li><ol><li>设置空div</li></ol><p>在父容器末尾添加空div,并设置clear:both清除浮动。这样很方便，但违背结构与表象分离的原则。</p></li><li><ol><li>设置overflow </li></ol><p>虽然设置其他属性也能引发BFC属性，但会对布局造成一些影响。设置overflow:hidden的影响相对较小，但在子元素的过大时，超出部分会被覆盖掉，设置auto或scroll又会产生滚动条。</p></li><li><ol><li>:after伪元素 </li></ol><p>通过为容器添加:after伪元素，并给伪元素设置overflow属性，添加IEhack，实现清除浮动。也是网上使用比较多的方法。<br>.clearfix{(<em>zoom: 1;}<br>.clearfix:after{content:’’;height:0;display:block; clear:both;/overflow:hidden;  /\</em>clear,overflow二选其一*/}</p></li></ul><p>##IE6、7下的BFC<br>由于早期IE6、7对于不支持BFC,所以需要通过IEhack解决。在IE6、7中，通过触发hasLayout私有属性实现BFC效果。从使用上看，hasLayout私有属性和BFC触发方式都是通过特有属性触发，IE6、7中大多通过设置zoom:1;触发，zoom用于设置或检索元素缩放比例，值1表示元素实际尺寸，所以设置1不会对元素显示造成影响。</p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;p&gt;#初识块级格式化上下文(Block Formatting Contexts)&lt;/p&gt;
&lt;p&gt;##前言&lt;br&gt;html文档中元素的定位有3种方式(普通流、绝对定位、浮动)，除普通流以外，浮动与绝对定位都会导致元素脱离普通流，按照各自的方式进行定位。&lt;br&gt;带有BFC属性的容器
      
    
    </summary>
    
    
      <category term="css" scheme="https://yguess.github.io/tags/css/"/>
    
  </entry>
  
  <entry>
    <title>Call Apply 和 Bind小结</title>
    <link href="https://yguess.github.io/2016/07/26/call%E3%80%81apply%E3%80%81bind/"/>
    <id>https://yguess.github.io/2016/07/26/call、apply、bind/</id>
    <published>2016-07-25T16:00:00.000Z</published>
    <updated>2018-03-10T06:15:36.805Z</updated>
    
    <content type="html"><![CDATA[<p>#Call Apply 和 Bind小结</p><p>###1.Call()<br>call()方法在使用一个指定的this值和若干个指定的参数值的前提下调用某个函数或方法.  </p><pre><code>fun.call(thisArg[, arg1[, arg2[, ...]]])  </code></pre><p>该方法接受的第一个参数为指定的替换对象，在非严格模式下若值为null或undefined,则会默认指向全局对象window.后面接受一连串的值作为参数,不能使数组或其他对象.<br>call()的调用即在调用thisArg对象时，可以调用fun的属性和方法.</p><p>#####示例代码<br>    function product(name, price) {<br>          var pName = name;<br>          var pPrice = price;<br>          return pName+’的价格是’+pPrice+’元/斤’;<br>    }<br>    function food(name, price) {</p><pre><code>}var apple = product.call(food,&apos;apple&apos;,3.5); console.log(apple()); #&quot;apple的价格是3.5元/斤&quot;  </code></pre><p>一般使用call方法可以用来调用父构造函数、调用匿名函数、指定上下文的this指向.<br>详细内容参考<a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/call" target="_blank" rel="external">MDN的call()部分</a>.</p><p>###Apply()<br>apply方法的作用和call方法作用一样，接受的第一个参数一样，后一个参数以数组或类数组对象的形式添加.</p><pre><code>fun.apply(thisArg[, argsArray])  </code></pre><p>详细内容参考<a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/apply" target="_blank" rel="external">MDN的apply()部分</a>.</p><p>###Bind()<br>bind()方法会创建一个新函数，当这个新函数被调用时，它的this值是传递给bind()的第一个参数, 它的参数是bind()的其他参数和其原本的参数.  </p><pre><code>fun.bind(thisArg[, arg1[, arg2[, ...]]])  </code></pre><p>#####参考代码<br>    this.x = 9;<br>    var module = {<br>          x: 81,<br>          getX: function() { return this.x; }<br>    };<br>    module.getX(); // 81<br>    var retrieveX = module.getX;<br>    retrieveX(); // 9<br>    var boundGetX = retrieveX.bind(module);<br>    boundGetX(); // 81<br>即创建一个新的函数boundGetX,当调用该函数时this指向的是module对象,则this.x值为81.<br>详细内容参考<a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/bind" target="_blank" rel="external">MDN的bind()部分</a>.</p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;p&gt;#Call Apply 和 Bind小结&lt;/p&gt;
&lt;p&gt;###1.Call()&lt;br&gt;call()方法在使用一个指定的this值和若干个指定的参数值的前提下调用某个函数或方法.  &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;fun.call(thisArg[, arg1[, arg2[
      
    
    </summary>
    
    
      <category term="javascript" scheme="https://yguess.github.io/tags/javascript/"/>
    
  </entry>
  
  <entry>
    <title>js调用百度地图API</title>
    <link href="https://yguess.github.io/2016/03/16/js%E8%B0%83%E7%94%A8%E7%99%BE%E5%BA%A6%E5%9C%B0%E5%9B%BEAPI/"/>
    <id>https://yguess.github.io/2016/03/16/js调用百度地图API/</id>
    <published>2016-03-15T16:00:00.000Z</published>
    <updated>2016-03-16T15:02:12.442Z</updated>
    
    <content type="html"><![CDATA[<p>前几天被要求在页面中调用地图并显示指定地点位置。虽然之前没弄过，但觉的应该很简单，毕竟按着别人的API调用就好。<br>在国内google地图是用不了了，只能选了百度地图。</p><hr><p>首先需要引用百度地图的API<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">&lt;script type=&quot;text/javascript&quot; src=&quot;http://api.map.baidu.com/api?v=1.3&quot;&gt;&lt;/script&gt;</div></pre></td></tr></table></figure></p><p>此处的v=1.3是指API的版本，目前百度地图API最高是2.0，而且自1.5版本以后的API，调用时需要到 <a href="http://lbsyun.baidu.com/apiconsole/key/create" target="_blank" rel="external">官方申请</a> 一个开发者的密钥，即为</p><pre><code>&lt;script type=&quot;text/javascript&quot; src=&quot;http://api.map.baidu.com/api?v=2.0&amp;ak=您的密钥&quot;&gt;&lt;/script&gt;</code></pre><p>设置1个div用于显示地图，然后再api下开始调用。最后大致如下：</p><pre><code>&lt;div id=&quot;map_address&quot; style=&quot;width: 500px; height: 500px; &quot;&gt;&lt;/div&gt;&lt;script type=&quot;text/javascript&quot; src=&quot;http://api.map.baidu.com/api?v=1.3&quot;&gt;&lt;/script&gt;&lt;script&gt;     var baidu_Point = new BMap.Point(104.066561,30.669561);  //经纬度坐标     var marker = new BMap.Marker(baidu_Point);               //标记     var pos_info = &quot;&lt;h5&gt;地点&lt;/h5&gt;&quot;                         +&quot;&lt;p style=&apos;font-size:12px;&apos;&gt;详细地址&lt;/p&gt;&quot;    var infoWindow = new BMap.InfoWindow(pos_info);          //信息展示    //地图初始化    var map = new BMap.Map(&quot;map_address&quot;);    map.centerAndZoom(baidu_Point, 20);//第二个参数指地图显示等级，数字越大显示越详细    map.addOverlay(marker);    map.openInfoWindow(infoWindow,baidu_Point);    map.addControl(new BMap.NavigationControl()); //控制工具    map.setCurrentCity(&quot;成都&quot;);                    // 设置地图显示的城市 此项是必须设置的    map.enableScrollWheelZoom(true);              //开启鼠标滚轮缩放&lt;/script&gt;</code></pre><p>以上就实现简单的调用，并显示在坐标处显示标志，如图</p><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="http://img.blog.csdn.net/20160316195513509" alt="这里写图片描述" title="">                </div>                <div class="image-caption">这里写图片描述</div>            </figure><p>确实不难(毕竟不是自己实现-_-!)。</p><hr><p>第一次用肯定会遇到一些小问题的….<br>百度地图查询地址需要的地点坐标</p><pre><code>var baidu_Point = new BMap.Point(104.066561,30.669561);  //经纬度坐标</code></pre><p>如上，接收1个经纬度位置。其实也可以接收一个字符串，即查询地。比如</p><pre><code>var baidu_Point = new BMap.Point(&apos;成都市金牛区&apos;);  //地点字符串</code></pre><p>我在使用时地点太详细好像有点问题，最后使用经纬度查询。但开始没找到如何获取详细经纬度，所以只好找了google的地图获取了经纬度，但设置好后发现显示位置有偏差！看了 <a href="http://lbsyun.baidu.com/index.php?title=jspopular/guide/introduction" target="_blank" rel="external">官方介绍</a> ,才知道百度使用的坐标不是GPS坐标</p><blockquote><p>国际经纬度坐标标准为WGS-84,国内必须至少使用国测局制定的GCJ-02,对地理位置进行首次加密。百度坐标在此基础上，进行了BD-09二次加密措施,更加保护了个人隐私。百度对外接口的坐标系并不是GPS采集的真实经纬度，需要通过坐标转换接口进行转换。</p></blockquote><p>好吧，原来还要进行地址转换。</p><pre><code>//谷歌坐标var x = 116.32715863448607;var y = 39.990912172420714;var ggPoint = new BMap.Point(x,y);//地图初始化var bm = new BMap.Map(&quot;allmap&quot;);bm.centerAndZoom(ggPoint, 15);bm.addControl(new BMap.NavigationControl());    //坐标转换完之后的回调函数translateCallback = function (data){  if(data.status === 0) {       bm.setCenter(data.points[0]);  }}setTimeout(function(){    var convertor = new BMap.Convertor();    var pointArr = [];    pointArr.push(ggPoint);    convertor.translate(pointArr, 3, 5, translateCallback)}, 1000);</code></pre><p>以上是 <a href="http://developer.baidu.com/map/jsdemo.htm#a5_1" target="_blank" rel="external">官方demo</a> 代码，很简单。</p><hr><p>后来百度发现原来百度自己有 <a href="http://s.suixingpay.com/static/baiduMap/baiduMap.jsp" target="_blank" rel="external">坐标拾取器</a> -_-!用来直接获取经纬度，简直醉了，智商堪忧！<br>附一下<a href="http://developer.baidu.com/map/jsdemo.htm#a5_1" target="_blank" rel="external">百度地图API地址</a>，demo的代码很详细，复制粘贴就能直接使用。<br>虽然不难，学着用用总是好的，在此记录一下！</p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;p&gt;前几天被要求在页面中调用地图并显示指定地点位置。虽然之前没弄过，但觉的应该很简单，毕竟按着别人的API调用就好。&lt;br&gt;在国内google地图是用不了了，只能选了百度地图。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;首先需要引用百度地图的API&lt;br&gt;&lt;figure class=&quot;highl
      
    
    </summary>
    
    
      <category term="javascript" scheme="https://yguess.github.io/tags/javascript/"/>
    
  </entry>
  
</feed>
