basecss.net
2016-04-02T08:50:15.000Z
http://www.basecss.net/
basecss
Hexo
JavaScript 位运算学习
http://www.basecss.net/2014/03/27/code-learning/
2014-03-27T01:23:31.000Z
2016-04-02T08:50:15.000Z
<p>这几天粗略的阅读了一下 <a href="http://angularjs.org/" target="_blank" rel="external">AngularJS</a> 的源码,在这个过程中发现有这么两段代码挺有意思的:</p>
<figure class="highlight js"><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">var</span> manualLowercase = <span class="function"><span class="keyword">function</span> (<span class="params">s</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> isString(s) ? s.replace(<span class="regexp">/[A-Z]/g</span>, <span class="function"><span class="keyword">function</span>(<span class="params">ch</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">String</span>.fromCharCode(ch.charCodeAt(<span class="number">0</span>) | <span class="number">32</span>)</span><br><span class="line"> }) : s</span><br><span class="line">}</span><br><span class="line"><span class="keyword">var</span> manualUppercase = <span class="function"><span class="keyword">function</span> (<span class="params">s</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> isString(s) ? s.replace(<span class="regexp">/[a-z]/g</span>, <span class="function"><span class="keyword">function</span>(<span class="params">ch</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">String</span>.fromCharCode(ch.charCodeAt(<span class="number">0</span>) & ~<span class="number">32</span>)</span><br><span class="line"> }) : s</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<blockquote>
<p>这两段代码用来处理字母大小写转换,由于某些国家(土耳其)使用 <code>toLowerCase()</code> 和 <code>toUpperCase()</code> 不能正确的转换字母大小写,因而需要手动的处理。</p>
</blockquote>
<a id="more"></a>
<p>为什么说这两段代码有意思?其实是觉得其中用<strong>位运算</strong>处理字母大小写的代码很巧妙,其核心代码如下:</p>
<figure class="highlight js"><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">ch.charCodeAt(<span class="number">0</span>) | <span class="number">32</span> <span class="comment">// 大写转小写</span></span><br><span class="line">ch.charCodeAt(<span class="number">0</span>) & ~<span class="number">32</span> <span class="comment">// 小写转大写</span></span><br></pre></td></tr></table></figure>
<p>在分析两段代码之前,先来回顾一下 JavaScript 中的两个概念:<strong>整数</strong>和<strong>位运算</strong>。</p>
<p>从严格意义上讲,ECMAScript 中有两种类型的整数:有符号的整数(正数和负数)和无符号的整数(只有正数)。而默认情况下 JavaScript 中的整数都是有符号的。</p>
<p>而在不考虑 ECMAScript 中数字格式存储与转换(为 32 位)的情况下,实际上我们操作的都是 32 位的整数。而对于上面提到的有符号整数而言,其中前 31 位(<code>end<-start</code>)表示数字的值,最后1位表示符号位(<code>0</code> 表示正,<code>1</code> 表示负)。</p>
<p>这里提到的 32 位的整数在计算机底层都是使用二进制格式存储的,而这个二进制由 <code>0</code> 和 <code>1</code> 组成,其中每一位都有对应的十进制数字结果,整个二进制数值代表的十进制结果由所有这些位对应的十进制数字之和。</p>
<p>这篇文章中不考虑负数的情况,一个 32 位二进制格式的数字看起来如下所示,这里以 10 为例:</p>
<figure class="highlight basic"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="symbol">0 </span><span class="number">0</span> <span class="number">0</span> <span class="number">0</span> <span class="number">0</span> <span class="number">0</span> <span class="number">0</span> <span class="number">0</span> <span class="number">0</span> <span class="number">0</span> <span class="number">0</span> <span class="number">0</span> <span class="number">0</span> <span class="number">0</span> <span class="number">0</span> <span class="number">0</span> <span class="number">0</span> <span class="number">0</span> <span class="number">0</span> <span class="number">0</span> <span class="number">0</span> <span class="number">0</span> <span class="number">0</span> <span class="number">0</span> <span class="number">0</span> <span class="number">0</span> <span class="number">0</span> <span class="number">0</span> <span class="number">1</span> <span class="number">0</span> <span class="number">1</span> <span class="number">0</span></span><br></pre></td></tr></table></figure>
<blockquote>
<p>二进制数字计算的方式:<code>number ( Math.pow(2, index))</code>,这里的 <code>number</code> 表示二进制中对应位上的数值 0/1,<code>index</code> 表示该数值在整个二进制格式的数字中的索引。注意一个二进制格式的起始点在右侧。</p>
<p>那么上面的数字就等于:<code>1 * Math.pow(2,3) + 1 * Math.pow(2, 1) = 10</code>。</p>
</blockquote>
<p>前面提到了,这些二进制的数字实际上都是在计算机的底层完成的,而 ECMAScript 中刚好提供了二进制运算相关的操作符,这些操作符都是直接对运算数进行二进制操作的,并且都是发生在幕后的。</p>
<p>JavaScript 中有 7 个位运算相关的运算符:</p>
<ul>
<li><strong>按位非(NOT)</strong> - 用一个波浪线” <code>~</code> “表示,对二进制的每一位进行取反操作,即将 <code>0</code> 变成 <code>1</code>,将 <code>1</code> 变成 <code>0</code>。</li>
<li><strong>按位与(AND)</strong> - 用一个和好” <code>&</code> “表示,必须有两个操作数,先对齐二进制位,然后把对应位都为 <code>1</code> 的为筛下来,其他的都为 <code>0</code>。</li>
<li><strong>按位或(OR)</strong> - 用一个竖线” <code>|</code> “表示,也必须有两个操作数,对齐位之后只要对应位有 1 就筛下来,只有同时位 0 时才返回 <code>0</code>。</li>
<li><strong>按位异或(XOR)</strong> - 用一个插入符号” <code>^</code> “表示,也必须有两个操作数,对齐位之后不同的返回 1,相同的返回 0。</li>
<li><strong>左移</strong> - 用两个小于号” <code><<</code>表示,顾名思议,将操作数左移指定位数,右侧空位用 0 补齐。</li>
<li><strong>有符号右移</strong> - 用两个大于号” <code>>></code> “表示,保留符号位,剩下的右移指定位。</li>
<li><strong>无符号右移</strong> - 用三个大于号” <code>>>></code> “表示,往右侧移动指定位数。</li>
</ul>
<p>以上这些位运算符,最终操作的都是二进制数值。</p>
<p>在上面的代码中分别涉及到了<strong>按位非</strong>,<strong>按位与</strong>,<strong>按位或</strong>三种运算。先来针对上面的两段代码讲解一下这三个位运算符:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ch.charCodeAt(<span class="number">0</span>) | <span class="number">32</span></span><br></pre></td></tr></table></figure>
<p>这段代码通过正则表达式匹配到给定字符串中的每个大写字母: <code>A-Z</code>;接下来使用字符串对象的 <code>charCodeAt()</code> 方法拿到该字符对应的 Unicode 编码,恰好这个编码是一个数字;最后使用<strong>按位或</strong>运算获取到另外一个数字。</p>
<p>为什么这里执行对数值 32 的<strong>按位或</strong>运算呢?当然这肯定不是空穴来风。那么我们先从大写字母及对应的 Unicode 值分析看看。不难发现,<code>A-Z</code> 对应的 Unicode 编码分别为 <code>65-90</code>;而这写编码对应的二进制表示分别为:<code>1000001</code> … <code>1011010</code>。再看看小些字母对应的数据:其 Unicode 编码分别为:<code>97-122</code>,对应的二进制表示分别为:<code>1100001</code>…<code>1111010</code>。最后将它们放入一张表格中对比如下:</p>
<blockquote>
<p>提示:使用 <code>(1).toString(2)</code> 便可以拿到每个数字对应的二进表示法的有效位。</p>
</blockquote>
<table>
<thead>
<tr>
<th style="text-align:center">大写字母二进制有效位</th>
<th style="text-align:center"><code>1000001</code></th>
<th style="text-align:center">…</th>
<th style="text-align:center"><code>1011010</code></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center">小写字母二进制有效位</td>
<td style="text-align:center"><code>1100001</code></td>
<td style="text-align:center">…</td>
<td style="text-align:center"><code>1111010</code></td>
</tr>
</tbody>
</table>
<p>在这个表格中没有完整列出每个字母对应的二进制有效位。但是通过完整的对比不难发现,大写字母与小写字母的二进制有效位都是 7 位,对这些数值进行对不不难发现大小写字母的二进制有效位中:大写字母的第 6 位为 0;而小写字母的第 6 位为 1;而每个大小写自己的二进制有效位中刚好只有这一位不同。</p>
<p>因此我们在求值大写字母的对应的小写字母的二进制数值时转换大写字母的二进制数值第 6 位即可,其他的位是一样的不用转换。而第 6 位为 1 时,其对应的十进制数值刚好是 32(<code>1 * Math.pow(2, 5)</code>),32 对应的二进制数值的有效位为:<code>100000</code>。</p>
<p>那么如何转换这里的第 6 位呢?我们的目的是将大写字母二进制数值第 6 位的 0 转换为 1,而其他的位不变。最终我们只需要拿一个刚好第 6 位为 1,其他位为 0 的二进制数值与大写字母的二进制数值进行位运算操作即可,这个能够用来进行有效位运算的二进制数值则为 <code>100000</code>,而 JavaScript 中的<strong>按位或</strong>操作刚好能有做到这一点。</p>
<p>而在 JavaScript 中,我们并不能直接操作一个二进制的数值,二进制的运算都是在低层完成的,在 JavaScript 中这些都是按位运算符的使命。那么,在前面使用 <code>charCodeAt()</code> 方法已经拿到了大写字母对应的 Unicode 编码-即一个有效的十进制数字;而 <code>100000</code> 对应的十进制数字为 32。</p>
<p>由此得出结论,使用大写字母对应的 Unicode 编码与 32 作按位或运算便能正确的拿到其对应的小写字母的 Unicode 编码,其操作过程如下:</p>
<p><strong>以大写字母 <code>A</code> 为例</strong>:</p>
<table>
<thead>
<tr>
<th style="text-align:center">1</th>
<th style="text-align:center">0</th>
<th style="text-align:center">0</th>
<th style="text-align:center">0</th>
<th style="text-align:center">0</th>
<th style="text-align:center">0</th>
<th style="text-align:center">1</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center"></td>
<td style="text-align:center">1</td>
<td style="text-align:center">0</td>
<td style="text-align:center">0</td>
<td style="text-align:center">0</td>
<td style="text-align:center">0</td>
<td style="text-align:center">0</td>
</tr>
<tr>
<td style="text-align:center">1</td>
<td style="text-align:center">1</td>
<td style="text-align:center">0</td>
<td style="text-align:center">0</td>
<td style="text-align:center">0</td>
<td style="text-align:center">0</td>
<td style="text-align:center">1</td>
</tr>
</tbody>
</table>
<p>如此,便拿到了一个二进制数值:<code>1100001</code>,对应的十进制数字为 97(parseInt(‘1100001’, 2))。最后使用 String 对象的 <code>fromCharCode()</code> 方法得到的字符便是大写字母 <code>A</code> 对应的小写字母 <code>a</code>。</p>
<p>整个转换的过程中,所有的这些操作实际上都是在底层(?内存中)完成的。</p>
<p>上面剖析了大写字母转小写字母的过程。接下来再看看小写字母转大写字母。在上面的代码中,我们可以看到转大写字母的代码为:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ch.charCodeAt(<span class="number">0</span>) & ~<span class="number">32</span></span><br></pre></td></tr></table></figure>
<p>首先,同大写字母一样,使用字符串对象 (String) 的 <code>charCodeAt()</code> 方法拿到对应的 Unicode 编码(也是一个十进制数值)。在上面的字母二进制数值对比表格中我们已经找到了规律:即转换每个字母对应的二进制数值的第 6 位即可。那么如何将小写字母的二进制数值的第 6 位 1 转换为 0,而其位不变呢?</p>
<p>前面将大写字母的第 6 位 0 转为 1,我们使用了<strong>按位或</strong>来保证将第 6 位正确的转换为 1。而这一次小写转大写的过程中,我们必须保证正确的将第 6 位 1 转换为 0,其他位不变即可。由此得出,这一次进行位运算的基本条件必须保证第二个操作数的第 6 位为 0,而其他位该是 1 的是 1,该是 0 的是 0。</p>
<p>那么如何做到这一点呢?根据位运算的特点以及上面的分析,我们保证第 6 位不同即可,那么拿 <code>011111</code> 与小写字母的二进制数值进行<strong>按位与</strong>运算运算即可。而对 32 进行<strong>按位非</strong>运算的结果刚好为 <code>011111</code>。</p>
<p><strong>以小写字母 <code>a</code> 为例</strong></p>
<table>
<thead>
<tr>
<th style="text-align:center">1</th>
<th style="text-align:center">1</th>
<th style="text-align:center">0</th>
<th style="text-align:center">0</th>
<th style="text-align:center">0</th>
<th style="text-align:center">0</th>
<th style="text-align:center">1</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center"></td>
<td style="text-align:center">0</td>
<td style="text-align:center">1</td>
<td style="text-align:center">1</td>
<td style="text-align:center">1</td>
<td style="text-align:center">1</td>
<td style="text-align:center">1</td>
</tr>
<tr>
<td style="text-align:center">1</td>
<td style="text-align:center">0</td>
<td style="text-align:center">0</td>
<td style="text-align:center">0</td>
<td style="text-align:center">0</td>
<td style="text-align:center">0</td>
<td style="text-align:center">1</td>
</tr>
</tbody>
</table>
<blockquote>
<p>这里不一定必须是 <code>011111</code>。比如拿一个完整的 32 位 <code>11111111111111111111111111011111</code> 也可以。但是在上述环境中,<code>011111</code> 就能满足需求,而这个二进制数值对应的数值刚好是对 32 进行<strong>按位非</strong>的运算结果。</p>
</blockquote>
<p>根据前面的分析,这样就拿到了大写字母 A 对应的二进制数值,再对它编码便可以返回最终的大写字母。</p>
<p>至此,对 AngularJS 中这两段代码的分析就完成了。也算是对 JavaScript 中的位运算做了一次巩固,温习。</p>
<p>其实 JavaScript 中的位运算远远不止这一点,我们还可以使用其他位运算符做到很多事情。下面是一些例子,不妨分析一下其运算原理:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 获取 0-max 之间随机整数</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">random</span> (<span class="params">max</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">Math</span>.random() * max | <span class="number">0</span>;</span><br><span class="line"> <span class="comment">// 获取 1-max 之间的随机整数</span></span><br><span class="line"> <span class="comment">// return Math.random() * max | 1</span></span><br><span class="line">}</span><br><span class="line"><span class="comment">// 奇偶判断</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">isOdd</span> (<span class="params">number</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> (<span class="built_in">parseInt</span>(number) & <span class="number">1</span>) === <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">isEven</span> (<span class="params">number</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> (<span class="built_in">parseInt</span>(number) & <span class="number">1</span>) === <span class="number">1</span>;</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 取整</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">int</span> (<span class="params">number</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> number | <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 取半</span></span><br><span class="line">number >> <span class="number">1</span>;</span><br><span class="line"><span class="comment">// 2x</span></span><br><span class="line">number << <span class="number">1</span>;</span><br><span class="line"><span class="comment">// 随机颜色</span></span><br><span class="line"><span class="string">'#'</span>+ (<span class="string">'000000'</span> + (<span class="built_in">Math</span>.random()*<span class="number">0xFFFFFF</span><<<span class="number">0</span>).toString(<span class="number">16</span>)).slice(<span class="number">-6</span>);</span><br><span class="line"><span class="comment">// 还可以挖掘更多的技巧....</span></span><br></pre></td></tr></table></figure>
<p>一些本文中用到的代码片段:</p>
<figure class="highlight js"><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="comment">// 获取字符 Unicode 编码值</span></span><br><span class="line">str.charCodeAt(<span class="number">0</span>);</span><br><span class="line"><span class="comment">// 获取字符二进制数值有效位</span></span><br><span class="line">str.charCodeAt(<span class="number">0</span>).toString(<span class="number">2</span>);</span><br><span class="line"><span class="comment">// 解析二进制数值</span></span><br><span class="line"><span class="built_in">parseInt</span>(binaryNumber, <span class="number">2</span>);</span><br><span class="line"><span class="comment">// 解析 Unicode 数值位对应的字符</span></span><br><span class="line"><span class="built_in">String</span>.fromCharCode(unicodeNumber);</span><br></pre></td></tr></table></figure>
<p>写在最后,虽然代码很小,但是其中学问还是蛮大的,仔细分析一下感觉收获很多。在这里尤其感谢我的导师 <a href="http://www.toobug.net" target="_blank" rel="external">@toobug</a> 不厌其烦的在 KFC 给我讲解了很多基础知识。</p>
<p><strong>参考资料</strong>:</p>
<ul>
<li><a href="http://www.w3school.com.cn/js/pro_js_operators_bitwise.asp" target="_blank" rel="external">ECMAScript 位运算</a></li>
<li><a href="http://www.ituring.com.cn/book/946" target="_blank" rel="external">JavaScript 高级程序设计(第三版) 3.5.2 位操作符</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators" target="_blank" rel="external">MDN - 位运算符</a></li>
</ul>
<p>这几天粗略的阅读了一下 <a href="http://angularjs.org/">AngularJS</a> 的源码,在这个过程中发现有这么两段代码挺有意思的:</p>
<figure class="highlight js"><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">var</span> manualLowercase = <span class="function"><span class="keyword">function</span> (<span class="params">s</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> isString(s) ? s.replace(<span class="regexp">/[A-Z]/g</span>, <span class="function"><span class="keyword">function</span>(<span class="params">ch</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">String</span>.fromCharCode(ch.charCodeAt(<span class="number">0</span>) | <span class="number">32</span>)</span><br><span class="line"> }) : s</span><br><span class="line">}</span><br><span class="line"><span class="keyword">var</span> manualUppercase = <span class="function"><span class="keyword">function</span> (<span class="params">s</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> isString(s) ? s.replace(<span class="regexp">/[a-z]/g</span>, <span class="function"><span class="keyword">function</span>(<span class="params">ch</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">String</span>.fromCharCode(ch.charCodeAt(<span class="number">0</span>) & ~<span class="number">32</span>)</span><br><span class="line"> }) : s</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<blockquote>
<p>这两段代码用来处理字母大小写转换,由于某些国家(土耳其)使用 <code>toLowerCase()</code> 和 <code>toUpperCase()</code> 不能正确的转换字母大小写,因而需要手动的处理。</p>
</blockquote>
classList 笔记
http://www.basecss.net/2013/12/27/classlist/
2013-12-26T17:08:22.000Z
2016-04-02T09:05:47.000Z
<p>HTML5 中新增了一个 <code>classList</code> API,顾命思议使用它能够获取一个 html 元素的 class 列表,并且能够使用 JavaScript 来管理这个 class 列表。比如:增删改。</p>
<p>使用 <code>classList</code> 非常方便,在此之前操作元素的 class 可谓相当头疼。</p>
<a id="more"></a>
<h3 id="获取-classList"><a href="#获取-classList" class="headerlink" title="获取 classList"></a>获取 <code>classList</code></h3><p>获取一个元素的 <code>classList</code> 非常容易,通过元素的 <code>classList</code> 属性就能简单的获取到元素的 class 列表。</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">div</span> <span class="attr">id</span>=<span class="string">"dom"</span> <span class="attr">class</span>=<span class="string">"classA classB classC"</span>></span><span class="tag"></<span class="name">div</span>></span></span><br></pre></td></tr></table></figure>
<p>获取元素的 <code>classList</code>。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> dom = <span class="built_in">document</span>.getElementById(<span class="string">'dom'</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> domClassList = dom.classList</span><br><span class="line"><span class="built_in">console</span>.log(domClassList)</span><br></pre></td></tr></table></figure>
<p>在浏览器中,元素的 <code>classList</code> 属性会返回一个 <code>DOMTokenList</code> 对象,这个对象包含了该元素的 class 列表,以及代表列表长度的 <code>length</code> 属性。</p>
<figure class="highlight js"><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><br><span class="line"> <span class="number">0</span>: <span class="string">'classA'</span>,</span><br><span class="line"> <span class="number">1</span>: <span class="string">'classB'</span>,</span><br><span class="line"> <span class="number">2</span>: <span class="string">'classC'</span>,</span><br><span class="line"> length: <span class="number">3</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>W3C 规范中并没有 <code>classList</code> 对应的规范,仅仅是在 <a href="http://www.w3.org/TR/dom/#dom-element-classlist" target="_blank" rel="external">DOM4规范中提及</a>, DOM4 规范中规定 <code>classList</code> 属性返回一个关联的 <code>DOMTokenList</code> 对象,这个对象就代表着相关对象的 classes [class列表]。</p>
<ul>
<li><a href="http://www.w3.org/TR/dom/#domtokenlist" target="_blank" rel="external">DOMTokenList</a></li>
</ul>
<blockquote>
<p>如果要查看 <code>classList</code> 所属类型,应该使用 <code>element.classList instanceof DOMTokenList</code> 的方式,而 <code>typeof element.classList</code> 会返回 ‘object’。</p>
</blockquote>
<h3 id="操作class列表"><a href="#操作class列表" class="headerlink" title="操作class列表"></a>操作class列表</h3><p>DOMTokenList 规范提供了一系列可以用于 <code>classList</code> 属性的属性和方法,包括:</p>
<ul>
<li><code>add()</code> 用于给 class 列表中添加一个或多个 class [CSS 类]</li>
<li><code>remove()</code> 从现有的列表中删除一个或者多个 class</li>
<li><code>contains()</code> 检查给定的 class 是否在列表中,返回布尔值</li>
<li><code>toggle()</code> 切换列表中的某个 class</li>
<li><code>item()</code> 获取列表中指定索引的 class。<em>与获取数组元素的方式相同</em></li>
<li><code>toString()</code> 将列表转换为一个字符串</li>
<li><code>length</code> 获取列表中 class 个数总数</li>
<li><code>value</code> 给 classList 对象添加一个自定的属性或者方法</li>
</ul>
<h5 id="classList-add"><a href="#classList-add" class="headerlink" title="classList.add()"></a>classList.add()</h5><p>使用 <code>classList.add()</code> 给指定元素添加 class 非常简单,只需要将需要添加的 class 以字符串的形式传递给 <code>add()</code> 方法即可。多个 class 之间使用逗号 <code>,</code> 分割。</p>
<figure class="highlight js"><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">dom.classList.add(<span class="string">'classD'</span>)</span><br><span class="line">dom.classList.add(<span class="string">'classE'</span>, <span class="string">'classF'</span>)</span><br></pre></td></tr></table></figure>
<blockquote>
<p><code>dom.classList.add('a,b,c,d,e')</code> 的方式实际上也是合法的,但是这个逗号分割的字符串会作为一个 class 添加给 <code>dom.classList</code>。</p>
</blockquote>
<h5 id="classList-remove"><a href="#classList-remove" class="headerlink" title="classList.remove()"></a>classList.remove()</h5><p>与添加 class 一样简单,只需指定需要移除的 class 即可,多个 class 之间使用逗号分割。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">dom.classList.remove(<span class="string">'classA'</span>, <span class="string">'classB'</span>)</span><br></pre></td></tr></table></figure>
<p><strong>关于添加和移除多个 class</strong></p>
<p>DOM4 规范中规定:</p>
<ul>
<li><a href="http://dom.spec.whatwg.org/#dom-domtokenlist-add" target="_blank" rel="external">dom-domtokenlist-add/remove</a><ul>
<li>如果参数为空,抛出语法错误异常</li>
<li>如果参数字符串包含任意的ASCII空格,抛出InvalidCharacterError异常</li>
<li>如果给定的参数 class 在现有的列表中不存在就添加</li>
<li>合法的操作都会触发 DOMTokenList 更新操作</li>
</ul>
</li>
<li>对于移除操作,如果参数在列表中存在就移除,否则什么都不干。</li>
</ul>
<p>对于浏览器不支持使用空格分割的形式同时添加或移除多个 class,但是使用现有的方法很容易扩展。</p>
<figure class="highlight js"><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="keyword">if</span> (!DOMTokenList.prototype.addmore) {</span><br><span class="line"> DOMTokenList.prototype.addmore = <span class="function"><span class="keyword">function</span> (<span class="params">classes</span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> classes = classes.split(<span class="string">' '</span>),</span><br><span class="line"> i = <span class="number">0</span>,</span><br><span class="line"> classesLen = classes.length</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">for</span> (i, i < classesLen; i++) {</span><br><span class="line"> <span class="keyword">if</span> (classes[i].trim()) {</span><br><span class="line"> <span class="keyword">this</span>.add(classes[i])</span><br><span class="line"> <span class="comment">// remove</span></span><br><span class="line"> <span class="comment">// this.remove(classes[i])</span></span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>使用现有的方式也很容易扩展更多的操作 classList 的方法,比如:以数组的形式添加/删除多个 class,处理使用逗号分割的连续字符串 (<code>a,b,c</code>) 等等。</p>
<h5 id="classList-contains"><a href="#classList-contains" class="headerlink" title="classList.contains()"></a>classList.contains()</h5><p>这个方法会根据检查结果返回 <code>true</code> 和 <code>false</code>。如果列表中存在给定的参数,则返回 <code>true</code>,反之,返回 <code>false</code>。</p>
<figure class="highlight js"><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">dom.classList.contains(<span class="string">'classD'</span>)</span><br><span class="line">dom.classList.contains(<span class="string">'classD'</span>,<span class="string">'classE'</span>)</span><br></pre></td></tr></table></figure>
<blockquote>
<p>多个之间也可以使用逗号分割的字符串列表。对于依赖于指定的 class 是否存在于列表的后续操作,<code>contains()</code> 是非常有用的。</p>
</blockquote>
<h5 id="classList-toggle"><a href="#classList-toggle" class="headerlink" title="classList.toggle()"></a>classList.toggle()</h5><p><code>classList.toggle()</code> 也很简单。通常情况下我们会通过程序的方式或者用户触发某个函数来添加或移除列表中 class。使用 <code>toggle()</code> 方法可以很容易做到。</p>
<figure class="highlight js"><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">dom.addEventListener(<span class="string">'click'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"> dom.classList.toggle(<span class="string">'classE'</span>)</span><br><span class="line">}, <span class="literal">false</span>)</span><br></pre></td></tr></table></figure>
<blockquote>
<p><code>toggle()</code> 方法会返回 Boolean 值,当将指定类移除时返回 <code>false</code>, 反之返回 <code>true</code>。</p>
</blockquote>
<p><code>classList</code> 的 <code>toggle()</code> 方法还有可选的第二个参数。如果第二个参数设置为 <code>true</code>,那么就会将参数 class 添加到元素中,而不是移除,反之设置 <code>false</code> 删除指定的 class 。</p>
<blockquote>
<p>PS: 第二参数的支持取决于浏览器,实际上加不加是一样的。不支持第二参数的浏览器会忽略它。</p>
</blockquote>
<h5 id="classList-item"><a href="#classList-item" class="headerlink" title="classList.item()"></a>classList.item()</h5><p>NodeList中也有 <code>item()</code> 方法。 <code>classList</code> 的 <code>item()</code> 方法返回列表指定索引的 class (索引从 <code>0</code> 开始)。假设有如下代码:</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">p</span> <span class="attr">id</span>=<span class="string">"domP"</span> <span class="attr">class</span>=<span class="string">"a b c d e f"</span>></span><span class="tag"></<span class="name">p</span>></span></span><br></pre></td></tr></table></figure>
<p>获取指定索引的 class:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> p = <span class="built_in">document</span>.getElementById(<span class="string">'domP'</span>)</span><br><span class="line"></span><br><span class="line">p.classList.item(<span class="number">0</span>) <span class="comment">// 'a'</span></span><br><span class="line">p.classList.item(<span class="number">4</span>) <span class="comment">// 'e'</span></span><br></pre></td></tr></table></figure>
<blockquote>
<p><code>classList</code> 的 <code>item()</code> 方法不能用来做添加或删除操作,会报错。</p>
</blockquote>
<h5 id="classList-toString"><a href="#classList-toString" class="headerlink" title="classList.toString()"></a>classList.toString()</h5><p>这个方法将指定元素的 class 列表转换为一个字符串。</p>
<blockquote>
<p><code>toString()</code> 并不是 DOMTokenList 规范中特有的。</p>
</blockquote>
<h5 id="classList-length"><a href="#classList-length" class="headerlink" title="classList.length"></a>classList.length</h5><p>返回指定元素 class 列表长度。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">p.classList.length <span class="comment">// 5</span></span><br></pre></td></tr></table></figure>
<h5 id="classList-value"><a href="#classList-value" class="headerlink" title="classList.value"></a>classList.value</h5><p>由于 classList 就是一个对象,因此我们可以给他添加属性和方法,就像操作一般的对象一样。如:</p>
<figure class="highlight js"><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">classList.someProperty = <span class="string">'xxx'</span></span><br><span class="line">classList.someMethod = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{}</span><br></pre></td></tr></table></figure>
<h3 id="低版本兼容-classList-polyfill"><a href="#低版本兼容-classList-polyfill" class="headerlink" title="低版本兼容(classList polyfill)"></a>低版本兼容(classList polyfill)</h3><p>提到 DOM 操作,兼容性就是个头疼的问题。尤其是 classList 这类非常好用的 API。 IE 到 10.0 才支持它,因此我们可以使用一些扩展的脚本程序来兼容不支持 classList 的浏览器。</p>
<ul>
<li><a href="http://caniuse.com/#search=classlist" target="_blank" rel="external">classList兼容性查看</a></li>
<li><a href="https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills#classlist" target="_blank" rel="external">Modernizr推荐的一些polyfill脚本</a></li>
<li><a href="https://gist.github.com/devongovett/1381839" target="_blank" rel="external">gist</a></li>
<li><a href="https://github.com/eligrey/classList.js" target="_blank" rel="external">classList.js - 兼容IE8+</a></li>
<li><a href="https://gist.github.com/termi/3952026" target="_blank" rel="external">gits2</a></li>
</ul>
<p>可以使用如下方式来检测浏览器是否支持 <code>classList</code>:</p>
<figure class="highlight js"><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="keyword">if</span> (<span class="string">'classList'</span> <span class="keyword">in</span> <span class="built_in">document</span>.createElement(<span class="string">'div'</span>)) {</span><br><span class="line"> <span class="comment">// 使用 classList</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>HTML5 中新增了一个 <code>classList</code> API,顾命思议使用它能够获取一个 html 元素的 class 列表,并且能够使用 JavaScript 来管理这个 class 列表。比如:增删改。</p>
<p>使用 <code>classList</code> 非常方便,在此之前操作元素的 class 可谓相当头疼。</p>
CSS半透明总结
http://www.basecss.net/2013/07/09/opacity/
2013-07-08T23:30:06.000Z
2016-04-02T09:12:30.000Z
<h2 id="opacity-属性"><a href="#opacity-属性" class="headerlink" title="opacity 属性"></a>opacity 属性</h2><p>CSS 中的 <code>opacity</code> 属性用于给元素指定一个 0 (全透明) 至1 (不透明) 的透明度值,但是这个值会应用到覆盖在背景之上的元素。</p>
<a id="more"></a>
<h5 id="兼容性如下"><a href="#兼容性如下" class="headerlink" title="兼容性如下:"></a>兼容性如下:</h5><table>
<thead>
<tr>
<th style="text-align:center">Chrome</th>
<th style="text-align:center">FireFox</th>
<th style="text-align:center">Internet Explorer</th>
<th style="text-align:center">Opera</th>
<th style="text-align:center">Safari</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center">1.0</td>
<td style="text-align:center">1.0</td>
<td style="text-align:center">9.0</td>
<td style="text-align:center">9.0</td>
<td style="text-align:center">1.2</td>
</tr>
</tbody>
</table>
<h2 id="IE中的半透明"><a href="#IE中的半透明" class="headerlink" title="IE中的半透明"></a>IE中的半透明</h2><p>在 IE8 及早期版本的 IE 中,需要使用 IE 系私有的 filter 属性处理,其中分别有三种方式:</p>
<ul>
<li><code>filter: alpha(opacity=value);</code> <sup>[1]</sup></li>
<li><code>filter: "alpha(opacity=value)";</code> <sup>[2]</sup></li>
<li><code>-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";</code> <sup>[3]</sup></li>
<li><code>filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=50);</code></li>
</ul>
<p>[1] 直到 IE9 才支持 <code>opacity</code> 属性,但是在之前的版本中都使用支持 <code>filter</code> 替代,并且在IE中使用 <code>filter</code> 属性实现透明的元素需要触发 hasLayout 使其具备 layout 特性。</p>
<p>[2] <strong><strong style="color:red;">据说</strong></strong>在 IE8 标准模式中,<code>filter</code> 属性的值需要使用引号包裹起来。</p>
<p>[3] IE4-IE9 中支持的一种扩展形式的编写方式。</p>
<p>[4] IE 中介绍了 <code>-ms-filter</code>,实质上只是 <code>filter</code> 属性的一个代名词。在 IE10 中不再存在。</p>
<h2 id="前缀"><a href="#前缀" class="headerlink" title="前缀"></a>前缀</h2><p>FireFox 0.9 之前使用 <code>-moz-opacity</code> 实现,之后便重命名为 <code>opacity</code>。 但之后 <code>-moz-opacity</code> 一直都作为 <code>opacity</code> 的别名存在。但是 FireFox 3.5 之后不再支持 <code>-moz-opacity</code> 属性,此时也移除了在 JavaScript 中支持的 <code>MozOpacity</code> 属性。<strong>据说</strong>在 FireFox 早期版本中 <code>opacity</code> 属性的实现取决于其 Gecko 的版本。</p>
<p>在早期发布的 Safari 1.2 中支持 <code>-khtml-opacity</code> 的方式实现半透明。</p>
<p>Konqueror 从不支持 <code>-khtml-opacity</code> 的形式,而是从 4.0 开始便支持 <code>opacity</code>。</p>
<h5 id="应用"><a href="#应用" class="headerlink" title="应用"></a>应用</h5><p>在实际应用中,由于 <code>opacity</code>/<code>filter</code> 的透明度会应用于子元素,因而常见的的做法是使用两个毗邻的元素,一个用于处理背景层,一个用于处理前景的内容层。其中背景层的要层叠在内容层底部,使用定位的方式便可以实现。示例:</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><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.bg</span> {</span><br><span class="line"> <span class="attribute">height</span>: <span class="number">100px</span>;</span><br><span class="line"> <span class="attribute">background</span>: <span class="number">#000</span>;</span><br><span class="line"> <span class="attribute">-ms-filter</span>:<span class="string">"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"</span>;</span><br><span class="line"> <span class="attribute">filter</span>: <span class="built_in">alpha</span>(opacity=50);</span><br><span class="line"> <span class="attribute">-moz-opacity</span>: .<span class="number">5</span>;</span><br><span class="line"> <span class="attribute">-khtml-opacity</span>: .<span class="number">5</span>;</span><br><span class="line"> <span class="attribute">opacity</span>: .<span class="number">5</span>;</span><br><span class="line">}</span><br><span class="line"><span class="selector-class">.content</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">0</span>;</span><br><span class="line"> <span class="attribute">height</span>: <span class="number">100px</span>;</span><br><span class="line"> <span class="attribute">color</span>: <span class="number">#fff</span>;</span><br><span class="line"> <span class="attribute">z-index</span>: <span class="number">10</span>; <span class="comment">/* 处理层叠 */</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<figure class="highlight html"><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="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"content"</span>></span>内容<span class="tag"></<span class="name">div</span>></span></span><br><span class="line"><span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"bg"</span>></span><span class="tag"></<span class="name">div</span>></span></span><br></pre></td></tr></table></figure>
<h2 id="RGBA"><a href="#RGBA" class="headerlink" title="RGBA"></a>RGBA</h2><p>CSS 2.1 中开始支持 RGB 色彩值,CSS3 中为 RGB 色彩添加了 Alpha 通道。可以用于处理 alpha 渲染和 alpha 合成[据说 alpha 与 RGBA 是有故事的]。RGBA 允许将元素设置为透明,但不影响子元素。</p>
<figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.selector</span> {</span><br><span class="line"> <span class="attribute">background</span>: <span class="built_in">rgba</span>(0,200,200,.5);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h5 id="RGBA兼容性"><a href="#RGBA兼容性" class="headerlink" title="RGBA兼容性"></a>RGBA兼容性</h5><table>
<thead>
<tr>
<th style="text-align:center">Chrome</th>
<th style="text-align:center">FireFox</th>
<th style="text-align:center">Internet Explorer</th>
<th style="text-align:center">Opera</th>
<th style="text-align:center">Safari</th>
<th style="text-align:center">iOS(Safari)</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center">All</td>
<td style="text-align:center">3.0</td>
<td style="text-align:center">9.0</td>
<td style="text-align:center">10.x+</td>
<td style="text-align:center">3.x+</td>
<td style="text-align:center">All</td>
</tr>
</tbody>
</table>
<h5 id="IE中的RGBA"><a href="#IE中的RGBA" class="headerlink" title="IE中的RGBA"></a>IE中的RGBA</h5><p>IE9 之前的 IE 版本不支持 RGBA,可以使用一个私有的 CSS 滤镜实现 RGBA 的效果。[IE 中的 : ARGB 啦] 示例代码:</p>
<figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.selector</span> {</span><br><span class="line"> <span class="attribute">filter</span>: progid:DXImageTransform.Microsoft.<span class="built_in">gradient</span>(startColorstr=#FFFFFFFF,endColorstr=#FFFFFFFF);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>DXImageTransform.Microsoft.gradient 滤镜中的 startColorstr 参数值是 #AARRGGBB 形式的,其中 AA 便是代表不透明度 (Alpha 通道值) 的十六进制表示,其中 00 表示全透明,FF 表示完全不透明,转化为十进制便是 0~255 范围之间的值,剩下的六位便是 RRGGBB 颜色的十六进制代码。</p>
<p>Alpha计算方式: <code>x = value*255/10</code> -> 再转换为十六进制。</p>
<h5 id="应用-1"><a href="#应用-1" class="headerlink" title="应用"></a>应用</h5><p>RGBA 可应用于 background,border 属性中,在早期版本的 FireFox 中 border 的拐角处的 rgba 会叠加。[测试在 FireFox17 中不再出现叠加的现象]。</p>
<p>在 IE9 中,已经支持 RGBA 形式,但是同时也支持 filter 形式。因此需要使用 hack 的方式清除 filter 形式。</p>
<figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-pseudo">:root</span> <span class="selector-class">.selector</span> {</span><br><span class="line"> <span class="attribute">filter</span>: none\<span class="number">9</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h5 id="转换函数"><a href="#转换函数" class="headerlink" title="转换函数"></a>转换函数</h5><p>这里提供一个 RGBA 值转换为 ARGB 的函数:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span><br><span class="line"> * @param Number 转换为十六进制的值</span><br><span class="line"> */</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">toHex</span> (<span class="params">val</span>)</span>{</span><br><span class="line"> val = <span class="built_in">parseInt</span>(val)</span><br><span class="line"> val = <span class="built_in">Math</span>.max(<span class="number">0</span>,val)</span><br><span class="line"> val = <span class="built_in">Math</span>.min(val,<span class="number">255</span>)</span><br><span class="line"> val = <span class="built_in">Math</span>.round(val)</span><br><span class="line"> <span class="keyword">return</span> <span class="string">'0123456789ABCDEF'</span>.charAt((val - val % <span class="number">16</span>) / <span class="number">16</span>) + <span class="string">'0123456789ABCDEF'</span>.charAt(val % <span class="number">16</span>)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span><br><span class="line"> * @param String 字符串形式的 rgba 值</span><br><span class="line"> */</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">toArgb</span> (<span class="params">val</span>)</span>{</span><br><span class="line"> <span class="keyword">var</span> valArr = val.split(<span class="string">"("</span>)[<span class="number">1</span>].split(<span class="string">")"</span>)[<span class="number">0</span>].split(<span class="string">","</span>),</span><br><span class="line"> red = toHex(valArr[<span class="number">0</span>]),</span><br><span class="line"> green = toHex(valArr[<span class="number">1</span>]),</span><br><span class="line"> blue = toHex(valArr[<span class="number">2</span>]),</span><br><span class="line"> alpha = toHex(valArr[<span class="number">3</span>] * <span class="number">255</span>)</span><br><span class="line"> <span class="keyword">return</span> <span class="string">'#'</span>+ alpha + red + green + blue</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="opacity-属性"><a href="#opacity-属性" class="headerlink" title="opacity 属性"></a>opacity 属性</h2><p>CSS 中的 <code>opacity</code> 属性用于给元素指定一个 0 (全透明) 至1 (不透明) 的透明度值,但是这个值会应用到覆盖在背景之上的元素。</p>