imliyan.com终于启用了HTTP/2了。

为什么之前没支持

好吧,其实HTTP/2在本站是一直开启的,只是由于Google在去年不再支持被OpenSSL 1.0.2以下版本广泛支持的NPN,而转向了ALPN,但ALPN则最低需要OpenSSL 1.0.2版本,而目前的linux服务器,除了Ubuntu 16.04 LTS以及Debian 9.0,其他OpenSSL版本都低于1.0.2。由于OpenSSL是系统服务,直接升级OpenSSL版本可能导致不可预知的系统问题。

不升级OpenSSL怎么实现

  1. 最直接的: 升级系统到Ubuntu 16.04 LTSDebian 9.0

  2. 使用OpenSSL 1.0.2之后的版本从源码重新编译一个Nginx版本。(具体可参考Supporting HTTP/2 for Website Visitors - What Can You Do?

HTTP/2 的好处

升级HTTP/2,一大特性就是单个TCP连接并行处理多个请求的多路复用特性,有效提升网站速度。现在升级完,试了下,好像也没有快很多啊。 :-(

不过在国内连国外的服务器能快到那里呢。

:)

一直以来使用CSS绘制图形都十分麻烦,比如为了绘制一个三角形,常用的方法是通过控制border来进行绘制,圆形则通过border-radius绘制。这些方法虽然也能达到效果,但一来十分复杂,二来绘制的过程完全不符合人类思考方式。原因就在于这些属性在设计之初就不是用作这些用途的。clip-path属性就是专门用来处理这类问题的,目前主流浏览器已实现对其基础支持。

clip-path 基本用法

绘制三角形

HTML

<div class="clip demo1"></div>

CSS

.clip {
    width: 200px;
    height: 200px;
}
.demo1 {
    background-color: #1ce4c2;
    -webkit-clip-path: polygon(50% 0, 100% 100%, 0 100%);
    clip-path: polygon(50% 0, 100% 100%, 0 100%);
}

绘制圆形

HTML

<div class="clip demo2"></div>

CSS

.demo2 {
    background-color: #f2c145;
    -webkit-clip-path: circle();
    clip-path: circle();
}

绘制多边形

HTML

<div class="clip demo3"></div>

CSS

.demo3 {
    background-color: #cf45c8;
    -webkit-clip-path: polygon(20% 0, 80% 0, 100% 20%, 100% 80%, 80% 100%, 20%  100%, 0 80%, 0 20%);
    clip-path: polygon(20% 0, 80% 0, 100% 20%, 100% 80%, 80% 100%, 20%  100%, 0 80%, 0 20%);
}

绘制椭圆

HTML

<div class="clip demo4"></div>

CSS

.demo4 {
    background-color: #23ef6a;
    -webkit-clip-path: ellipse(40% 25% at 50% 50%);
    clip-path: ellipse(40% 25% at 50% 50%);
}

动画效果

动画一

HTML

<div class="clip demo4"></div>

CSS

.demo4 {
    background-color: #cf45c8;
    animation: circle 1s infinite alternate;
}
@keyframes circle {
    0% {
        -webkit-clip-path: circle(100px);
        clip-path: circle(100px);
    }
    100% {
        -webkit-clip-path: circle(0);
        clip-path: circle(0);
    }
}

动画二

HTML

<div class="clip demo6"></div>

CSS

.demo6 {
    background-color: #8ac351;
    animation: msg 1s infinite alternate ease-in-out;
}
@keyframes msg {
    0% {
        -webkit-clip-path: polygon(0% 0%, 100% 0%, 100% 75%, 75% 75%, 75% 100%, 50% 75%, 0% 75%);
        clip-path: polygon(0% 0%, 100% 0%, 100% 75%, 75% 75%, 75% 100%, 50% 75%, 0% 75%);
    }
    100% {
        -webkit-clip-path: polygon(50% 0%, 90% 20%, 100% 60%, 75% 100%, 25% 100%,   0% 60%, 10% 20%);
        clip-path: polygon(50% 0%, 90% 20%, 100% 60%, 75% 100%, 25% 100%,   0% 60%, 10% 20%);
    }
}

制作有趣的效果

探索

HTML

<div id="dark">
    <div id="ring">
        <h1>The Ring</h1><p>Three Rings for the Elven-kings under the   sky,
        Seven for the Dwarf-lords in their halls of stone,
        Nine for Mortal Men doomed to die,
        One for the Dark Lord on his dark throne
        In the Land of Mordor where the Shadows lie.
        One Ring to rule them all, One Ring to find them,
        One Ring to bring them all, and in the darkness bind them,
        In the Land of Mordor where the Shadows lie。</p>
    </div>
</div>

CSS

#dark {
    background-color: #000;
}
#ring{
    background: #fff;
    padding: 1em;
    font-family: 'Times New Roman', Times, serif;
    text-align: center;
    white-space: pre;
    -webkit-clip-path: circle(50px at 200px 100px);
    clip-path: circle(50px at 200px 100px);
}

JS

let ring = document.querySelector('#ring')
window.addEventListener('mousemove', (e) => {
    let x = e.pageX
    let y = e.pageY
    let ox = ring.offsetLeft
    let oy = ring.offsetTop
    let newPath = `circle(50px at ${x-ox}px ${y-oy}px)`
    ring.style['clip-path'] = newPath
})

在下图移动鼠标查看效果

The Ring

Three Rings for the Elven-kings under the sky, Seven for the Dwarf-lords in their halls of stone, Nine for Mortal Men doomed to die, One for the Dark Lord on his dark throne In the Land of Mordor where the Shadows lie. One Ring to rule them all, One Ring to find them, One Ring to bring them all, and in the darkness bind them, In the Land of Mordor where the Shadows lie。

放大镜

HTML

<div id="dark2">
    <div id="ring2">
        <h1>The Ring</h1><p>Three Rings for the Elven-kings under the sky,
    Seven for the Dwarf-lords in their halls of stone,
    Nine for Mortal Men doomed to die,
    One for the Dark Lord on his dark throne
    In the Land of Mordor where the Shadows lie.
    One Ring to rule them all, One Ring to find them,
    One Ring to bring them all, and in the darkness bind them,
    In the Land of Mordor where the Shadows lie。</p>
    </div>
</div>

CSS

#dark2 {
    background-color: #000;
    position: relative;
}
#ring2, #ring2c{
    background: #fff;
    font-family: 'Times New Roman', Times, serif;
    text-align: center;
    white-space: pre;
}
#ring2c {
    transform: scale(1.3);
    transform-origin: 50% 50%;
    -webkit-clip-path: circle(30px at 200px 100px);
    clip-path: circle(50px at 200px 100px);
    position: absolute;
    top: 0;
    left: 0;
}

JS

let dark2 = document.querySelector('#dark2')
let ring2 = document.querySelector('#ring2')
let ring2c = ring.cloneNode(true)
ring2c.id = 'ring2c'
dark2.appendChild(ring2c)
dark2.addEventListener('mousemove', (e) => {
    let x = e.pageX
    let y = e.pageY
    let ox = dark2.offsetLeft
    let oy = dark2.offsetTop
    let newPath = `circle(50px at ${x-ox}px ${y-oy}px)`
    ring2c.style['clip-path'] = newPath
    let newOrigin = `${x-ox}px ${y-oy}px`
    ring2c.style['transform-origin'] = newOrigin
})

The Ring

Three Rings for the Elven-kings under the sky, Seven for the Dwarf-lords in their halls of stone, Nine for Mortal Men doomed to die, One for the Dark Lord on his dark throne In the Land of Mordor where the Shadows lie. One Ring to rule them all, One Ring to find them, One Ring to bring them all, and in the darkness bind them, In the Land of Mordor where the Shadows lie。

配合shape-outsize进行排版

shape-outsized属性与clip-path相似,都可以剪切除一定的图形。不过shape-outsized主要与float属性配合使用,使文字围绕浮动元素剪切过的路径而不是浮动元素的边缘。

<div>
    <div id="float"></div>
    <p id="p">Three Rings for the Elven-kings under the sky,
        Seven for the Dwarf-lords in their halls of stone,
        Nine for Mortal Men doomed to die,
        One for the Dark Lord on his dark throne
        In the Land of Mordor where the Shadows lie.
        One Ring to rule them all, One Ring to find them,
        One Ring to bring them all, and in the darkness bind them,
        In the Land of Mordor where the Shadows lie。
    </p>
</div>

CSS

#float {
    width: 200px;
    height: 200px;
    background-color: #23bcc7;
    clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%,    32% 57%, 2% 35%, 39% 35%);
    shape-outside: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21%     91%, 32% 57%, 2% 35%, 39% 35%);
    float: left;
}

Three Rings for the Elven-kings under the sky, Seven for the Dwarf-lords in their halls of stone, Nine for Mortal Men doomed to die, One for the Dark Lord on his dark throne In the Land of Mordor where the Shadows lie. One Ring to rule them all, One Ring to find them, One Ring to bring them all, and in the darkness bind them, In the Land of Mordor where the Shadows lie。


参考

问题:[]等于false

看下边的表达式:

[] == false
//  true

if ([]) {
    console.log('啦啦啦')
}
// 啦啦啦

额?[]不是等于false么? 而且,再看这里:

![] == false
// true

=_=!

究竟相等不相等?

不过这不是bug,而是由于JavaScript语言对==的处理方式引起的。

JavaScript相等性判断

  1. ==

  2. ===

  3. Object.is

先说后两个:

全等操作符===

全等操作符比较两个值是否相等,两个被比较的值在比较前都不进行隐式转换。如果两个被比较的值具有不同的类型,这两个值是不全等的。否则,如果两个被比较的值类型相同,值也相同,并且都不是 number 类型时,两个值全等。最后,如果两个值都是 number 类型,当两个都不是 NaN,并且数值相同,或是两个值分别为 +0 和 -0 时,两个值被认为是全等的。

在日常中使用全等操作符几乎总是正确的选择。对于除了数值之外的值,全等操作符使用明确的语义进行比较:一个值只与自身全等。对于数值,全等操作符使用略加修改的语义来处理两个特殊情况:第一个情况是,浮点数 0 是不分正负的。区分 +0 和 -0 在解决一些特定的数学问题时是必要的,但是大部分境况下我们并不用关心。全等操作符认为这两个值是全等的。第二个情况是,浮点数包含了 NaN 值,用来表示某些定义不明确的数学问题的解,例如:正无穷加负无穷。全等操作符认为 NaN 与其他任何值都不全等,包括它自己。(等式 (x !== x) 成立的唯一情况是 x 的值为 NaN)

Object.is()

Object.is 在三等号判等的基础上特别处理了 NaN 、 -0 和 +0 ,保证 -0 和 +0 不再相同,但 Object.is(NaN, NaN) 会返回 true。

非严格相等==

与全等操作符不同的是,非严格相等操作符在比较两个值A == B的时候,如果两者类型不同,会先进行类型转换,转换为同一类型后再进行比较。具体的转换规则如下:

equal

ToNumber(A) 尝试在比较前将参数 A 转换为数字,这与 +A(单目运算符+)的效果相同。通过尝试依次调用 A 的A.toString 和 A.valueOf 方法,将参数 A 转换为原始值(Primitive)。

第一列为被比较值A的类型,第一排为被比较值B的类型。

关于[] == false

如此我们看[] == false[]Object类型,falseBoolean类型,所以真正的比较表达式是:

ToPrimitive([]) == ToNumber(false)

ToPrimitive([])通过调用[].toString()得到空字符串""ToNumber(false)false转换为数字0,因此:

"" == 0

然后是字符串与数字进行非严格相等比较,又进行了类型转换:

ToNumber("") === 0

也就是:

0 === 0

因此返回true

所以,[] == false表达式的值为true,但空数组对象本身[]是不被视为false的。实际上,JavaScript中视为false的有false, null, undefined, 0, "", NaN,其他类型可通过类型转换转换为Boolean类型

关于![] == false

逻辑非操作符!的优先级(15)高于等号操作符优先级(10),因此在比较前先进行的是![],结果是false,因此实际比较是:

false == false

因此返回true

不是bug的bug

Explicit is better than implicit.

Readability counts.

好的代码应该是清晰明了、可读性好的,语言最好也是。而在一个相等操作符==上,JavaScript进行了如此多的内部操作,不仅新手容易迷惑,就连有经验的程序员也可能一时搞不明白一个表达式到底出了什么问题。因此也有了如下观点:

最好永远都不要使用相等操作符。全等操作符的结果更容易预测,并且因为没有隐式转换,全等比较的操作会更快。

参考:

为什么使用 CSS Variables

在开发一个 Web 应用的时候,经常需要为许多元素设置属性(如colorwidthheight)等,即使很多元素具有相同的属性,我们还是要为每个元素单独设置属性。这样一旦应用更改主题,比如更改主色调,那么要为每一个元素一个一个地修改,为什么不能像大部分编程语言一样,定义一个变量,用这个变量来设置对象(元素)的属性?这样只需要修改变量值就可以修改所有的属性值了。CSS Variables 就是做这个的。

为什么不用SASS/LESS

像 SASS 和 LESS 这些 CSS 预处理语言也支持变量定义等多种有用特效,它们是很有用的工具,但是这些工具有一个明显的缺点:它们是静态的,最终还是要编译为CSS,不能在运行时进行更改,也就不能动态的运用主题更改或者进行某些响应式设计。而 CSS Variables 是 CSS 的原生属性,没有这些问题,同时结合未来可能出现的新的 CSS 特性,它可以发挥出更大的作用。

浏览器支持情况

具体的支持情况可在caniuse查看,目前除IE外,所有主流浏览器都实现了对 CSS Variables 的支持。

CSS Variables 基本用法

定义变量

变量的定义格式是--somevar,如下--text-color: red,即将red的值赋给--text-color

要使用定义的变量,使用var()函数,如下var(--text-color)会返回--text-color对应的值,也即是red

CSS:

:root {
    --text-color: red
}
.cv-test {
    color: var(--text-color)
}

HTML:

<p class='cv-test'>May The force be with you.</p>

结果:


May The force be with you.


支持作用域与继承

CSS Variables 的另一个特性是支持作用域,这就意味着我们可以在不同的层级定义相同名称的变量。如果某元素没有 CSS Variables,则会继承父元素。

利用这一特性,我们也可以通过媒体查询写出响应式的样式来。

CSS:

.scopeone {
    --text-color: green
}

.scopetwo {
    --text-color: orange
}

.cv-test {
    color: var(--text-color)
}

/*结合媒体查询定义变量*/
@media (max-width: 1000px) {
    :root {
        --text-color: lime
    }
}

HTML:

<p class='cv-test'>My name is Ozymandias</p>

<div class='scopeone'>
    <p class='cv-test'>
        <span>King<span> of kings
    </p>
</div>

<div class='scopetwo'>
    <p class='cv-test'>Look on my works</p>
</div>

结果:


My name is Ozymandias

King of kings

Look on my works


关于var()函数

var()函数的语法如下:

var(<custom-property-name> [, <declaration-value> ]? )

custom-property-name也就是我们预先定义的变量名,declaration-value则是在custom-property-name不存在或不能正常解析是作为备选值。

CSS:

.scopethree {
    color: var(--undefined-color, yellow) 
}

HTML:

<p class='scopethree'>One ring to rule them all</p>

结果:


One ring to rule them all


var()函数几个注意点

不能将var()函数返回的值作为变量名:

/*错误用法*/
:root {
    --mt: margin-top;
    var(--mt): 10px; 
}

不能将var()函数返回的值作为部分变量值:

/*错误用法*/
:root {
    --big: 20;
    font-size: var(--big)px; 
}

如果属性值是由变量计算的来,最好结合calc()函数使用:

CSS:

.scopefour {
    --big: 20;
    font-size: calc((var(--big) + 5) * 1px); 
}

HTML:

<p class='scopefour'>One ring to find them</p>

结果:


One ring to find them


使用 JS 动态设定 CSS 样式

前文提到过,CSS Variables 相比 SASS/LESS 的一个优点是可以动态修改,我们可以通过 JS 来动态改变 CSS Variables:

打开控制台,输入以下代码:

getComputedStyle(document.documentElement).getPropertyValue('--text-color')

就可以得到我们在:root作用域内设置的--text-color变量值,这里就是red

然后可以通过下列代码设置变量值,就可以做到批量修改属性值了:

document.documentElement.style.setProperty('--text-color', 'pink');

// 或者使用另一个变量值来作为setProperty的参数
document.documentElement.style.setProperty('--text-color', 'var(--backup-color)');

实例:

<p class='cv-test'>one ring to rule them all</p>
<p class='cv-test2'>one ring to find them</p>
<p class='cv-test3'>one ring to bring them all</p>
<p class='cv-test4'>and in the darkness bind them</p>
<button id='topurple'>紫色</button>
<button id='toskyblue'>天蓝色</button>
<style>
    cv-test2 {
        color: var(--text-color)
    }
    cv-test3 {
        color: var(--text-color)
    }
    cv-test4 {
        color: var(--text-color)
    }
</style>
<script>
    document.getElementById('topurple').addEventListener('click', () => {
        document.documentElement.style.setProperty('--text-color', 'purple');
    })
    document.getElementById('toskyblue').addEventListener('click', () => {
        document.documentElement.style.setProperty('--text-color', 'var(--backup-color)');
    })
</script>

结果:


one ring to rule them all

one ring to find them

one ring to bring them all

and in the darkness bind them


参考


When you grow up you tend to get told the world is the way it is and your life is just to live your life inside the world. Try not to bash into the walls too much. Try to have a nice family life, have fun, save a little money.

That’s a very limited life. Life can be much broader once you discover one simple fact, and that is – everything around you that you call life, was made up by people that were no smarter than you. And you can change it, you can influence it, you can build your own things that other people can use.

The minute that you understand that you can poke life and actually something will, you know if you push in, something will pop out the other side, that you can change it, you can mold it. That’s maybe the most important thing. It’s to shake off this erroneous notion that life is there and you’re just gonna live in it, versus embrace it, change it, improve it, make your mark upon it.

I think that’s very important and however you learn that, once you learn it, you’ll want to change life and make it better, cause it’s kind of messed up, in a lot of ways. Once you learn that, you’ll never be the same again.

—— Steve Jobs