Haml简介

Haml是X HTML Abstraction Markup Language的缩写,用Ruby写成,可以将写成的模版转换为HTML代码。Haml的优点是简洁省去了HTML很多繁琐的标签。

安装Haml:

1
gem install haml

Haml语法

  • HTML5 DOCTYPE
    1
    !!! 5

HTML:

1
<!DOCTYPE html>

  • XHTML Strict DOCTYPE
    1
    !!! Strict

HTML:

1
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

  • XML DOCTYPE
    1
    !!!XML

HTML:

1
<?xml version='1.0' encoding='utf-8' ?>

  • 标签
    %开头表示标签,如%html, %head, %body等。代码块的层级关系用缩进表示。
    1
    2
    3
    4
    5
    6
    !!!5
    %html
    %head
    %title Haml introduction
    %body
    give me five!

输出HTML为:

1
2
3
4
5
6
7
8
9
<!DOCTYPE html>
<html>
<head>
<title>Haml introduction</title>
</head>
<body>
give me five!
</body>
</html>

  • ID
    在ID前加上#即可:
    1
    2
    %div#mine
    %p#yours

HTML:

1
2
<div id="mine"></div>
<p id="yours"></p>

  • Class
    在Class前加.
    1
    2
    %div.mine
    %p.yours

HTML:

1
2
<div class="mine"></div>
<p class="yours"></p>

还可以添加多个Class:

1
%div.mine.yours

HTML:

1
<div class="mine yours"></div>

div是默认标签,如果只写ID或者Class,那么就默认是div标签:

1
#mine

HTML:

1
<div id='mine'></div>

ID和Class可以混用:

1
2
#mine.yours
#mine.yours.his

HTML:

1
2
<div class='yours' id='mine'></div>
<div class='yours his' id='mine'></div>

  • 属性

属性可以使用Ruby Hash语法表示:

1
2
%a{:href => 'http://hi.com'} hi
%input{:type => 'submit'}

HTML:

1
2
<a href='http://hi.com'>hi</a>
<input type='submit'>

或者可以写成:

1
2
%a(href='http://hi.com') hi
%input(type='submit')

  • 使用数组表示ID和Class:
    1
    2
    %p{:class => ['one','two']} hi
    %p{:id=> ['one','two']} hi

HTML:

1
2
<p class='one two'>hi</p>
<p id='one_two'>hi</p>

  • 注释

“/“起首的行表示HTML注释,”-#”起首的行表示Haml注释。还可以添加条件注释:

1
/[if IE] %link { :rel => "stylesheet", :href => "/css/ie.css" }

HTML:

1
<!--[if IE]> <link href="/css/ie.css" rel="stylesheet"> <![endif]-->

编译

1
haml input.haml output.html

更详细语法的请参考:
http://haml.info/docs/yardoc/file.REFERENCE.html

HAML Cheat Sheet

JavaScript数据类型转换

  • 非数值类型转换为数值类型

有三个函数可以实现:
Number()
parseInt()
parseFloat()

Number()函数遵循以下规则:

  1. true和false分别转换为1和0
  2. 如果参数是数值则不变
  3. null转换为0
  4. undefined 转换为NaN.
  5. 如果参数是字符串,则按照以下规则:

a. 如果只含数字,或(+-)符号,则转为相应的十进位数值,开头的”0”将被忽略:

1
2
3
4
5
6
> Number('-65')
-65
> Number('100')
100
> Number('00100')
100

b. 如果含有合法的浮点数值,如”1.2345”等,则转为此浮点数,忽略开头的”0”。

1
2
3
4
> Number('001.2345678')
1.2345678
> Number('-001.2345678')
-1.2345678

c. 如果含有合法的16进位数值,则转换为相应的十进制数值:

1
2
> Number('0xffff')
65535

d. 空字符串转换为0,包括只含空格的字符串:

1
2
3
4
5
6
> Number(' ')
0
> Number(' ')
0
> Number('')
0

e. 如果该字符串是其他格式,则返回NaN:

1
2
> Number('h')
NaN

  1. 当参数是对象时,调用对象的valueOf方法并按照上述规则转换,如果结果是NaN则调用toString()方法。

parseInt()将字符串转换为整型,规则为:如果首字符不是数字,+-符合,则返回NaN。空字符串会被转为NaN

1
2
3
4
> parseInt('')
NaN
> parseInt(' ')
NaN

如果首字符是数值,+-符号,那么就往下找,直到遇到非数值字符:

1
2
3
4
5
6
7
8
9
10
> parseInt('+ji')
NaN
> parseInt('+1ji')
1
> parseInt('-1ji')
-1
> parseInt('1234ji')
1234
> parseInt('1234.3333')
1234

parseInt()还可以接受一个基数参数(radix),表示按照多少进制转换:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
> parseInt('ffff', 16)
65535
> parseInt('110', 2)
6
> parseInt('110', 4)
20
> parseInt('110', 6)
42
> parseInt('110', 8)
72
> parseInt('110', 16)
272
> parseInt('110', 20)
420

parseFloat()工作方式和parseInt()类似,它可以接受一个字符串中有一个小数点,第二个小数点将被忽略:

1
2
3
4
> parseFloat('1.23')
1.23
> parseFloat('1.23.45')
1.23

parseFloat()只能转换10进制数,不能带基数参数(radix)。

  • 非字符串转换为字符串

非字符串可以通过toString()方法 显示 转换为字符串类型。

1
2
3
4
5
6
7
> 2.toString()
SyntaxError: Unexpected token ILLEGAL
这是JavaScript 解析器的一个错误, 它试图将点操作符解析为浮点数字面值的一部分。有很多变通方法可以让数字的字面值看起来像对象。

2..toString(); // 第二个点号可以正常解析
2 .toString(); // 注意点号前面的空格
(2).toString(); // 2先被计算

toString()方法在转换数值类型时可以加上radix参数:

1
2
3
4
5
6
var num = 10;
alert(num.toString()); //”10”
alert(num.toString(2)); //”1010”
alert(num.toString(8)); //”12”
alert(num.toString(10)); //”10”
alert(num.toString(16)); //”a”

null和undefined没有toString()方法。这时我们可以使用String()函数:

1
2
3
4
> String(null)
"null"
> String(undefined)
"undefined"
  • 转换成布尔值

使用Boolean方法,可以将任意类型的变量转为布尔值。以下六个值的转化结果为false,其他的值全部为true。

  1. undefined
  2. null
  3. -0
  4. +0
  5. NaN
  6. ‘’(空字符串)
1
2
3
4
5
Boolean(undefined) // false
Boolean(null) // false
Boolean(0) // false
Boolean(NaN) // false
Boolean('') // false

请注意,空对象{}和空数组[]都会被转成true。

1
2
Boolean([]) // true
Boolean({}) // true

所有对象的布尔值都是true,甚至连false对应的布尔对象也是true。

1
2
Boolean(new Boolean(false))
// true

Math notes

  • 导数

$C’ = 0$

$(x^n)’ = nx^{n-1}$

$(sinx)’ = cosx$

$(tanx)’ = \frac {1}{cos^2 x} = sec^2 x$

$(cotx)’ = - \frac {1} {sin^2 x} = -csc^2 x$

$(secx)’ = secxtanx$

$(cscx)’ = -cscxcotx$

$(ln|x|)’ = \frac{1}{x}$

$(log_a x)’ = \frac{1}{xlna}$

$(e^x)’ = e^x$

$(a^x)’ = a^xlna, a>0, a\ne1$

$(arcsinx)’ = \frac{1}{\sqrt{1-x^2}}$

$(arccosx)’ = -\frac{1}{\sqrt{1-x^2}}$

$(arctanx)’ = \frac{1}{1+x^2}$

$(arccot x)’ = -\frac{1}{1+x^2}$

  • 极限

$\lim_{n \to \infty}\frac{ln}{n} = 0$

$\lim_{n \to \infty}\sqrt[n]{n} = 1$

$\lim_{n \to \infty}x^{1/n} = 1(x>0)$

$\lim_{n \to \infty}x^n = 0(|x| < 1)$

$\lim_{n \to \infty}(1+\frac{x}{n})^n = e^x$

$\lim_{n \to \infty}\frac{x^n}{n!} = 0$

  • 积分

$\int kx\, dx = kx + C $ (K是常数)

$\int x^u\, dx = \frac {x^{u+1}} {u+1}+ C (u \ne -1)$

$\int \frac{dx} {x} = ln|x| + C$

$\int \frac{1}{1+x^2}dx = \arctan x+C$

$\int \frac{1}{\sqrt {1-x^2}}dx = \arcsin x+C$

$\int \cos x dx = \sin x+C$

$\int \sin x dx = -\cos x+C$

$\int \sec^2x dx = -\tan x+C$

$\int \csc^2x dx = -\cot x+C$

$\int \sec x \tan x dx = \sec x+C$

$\int e^x dx = e^x+C$

$\int a^x dx = \frac {a^x} {lna}+C$

$\int u\,dv=uv-\int v\,du$

  • 费马小定理

假如a是一个整数,p是一个质数,那么$a^p - a$是p的倍数,可以表示为
$a^p \equiv a \pmod{p}$
如果a不是p的倍数,这个定理也可以写成
$a^{p-1} \equiv 1 \pmod{p}$

  • 微积分基本定理

(1) 设$f$为定义在闭区间$[a,b]$的实函数
$F(x) = \int_a^x f(t)\, dt\,  $ ($x \in [a,b]$)
那么,$F(x)$可导,及$F’(x)=f(x)$
即:$\frac d{dx}\int_a^xf(t)dt=f(x)$

(2) 设 $f$ 为在闭区间 $[a, b]$ 内连续的实函数,及设 $F$ 为 $f$ 的一个原函数:
$F’(x) = f(x)\, $  $x \in [a,b]$
那么
$\int_a^b f(x)\,dx = F(b) - F(a)$

  • 无穷级数收敛性判断:


  • 常数e

$$
e=\lim_{n\to\infty}\left(1+\frac{1}{n}\right)^n
e=\sum_{n=0}^\infty \frac{1}{n!}
$$

  • 欧拉公式

$$
e^{i\theta}=\cos\theta+i\sin\theta
$$

  • 斯特灵公式

$$
n! \approx \sqrt{2\pi n}\, \left(\frac{n}{e}\right)^{n}
$$

  • 正态分布

均值为$\mu$, 方差为$\sigma^2$ (或标准差$\sigma$)
正态分布的概率密度函数:
$$f(x;\mu,\sigma)
=\frac{1}{\sigma\sqrt{2\pi}} \, \exp \left( -\frac{(x- \mu)^2}{2\sigma^2} \right)
$$

  • 叶斯定理:
    $$
    P(A_i|B) = \frac{P(B | A_i)\, P(A_i)}{\sum_j P(B|A_j)\,P(A_j)}
    $$

jQuery与JavaScript写法对比

jQuery是一个很流行的JaVascript库,简化了JavaScript的编程。作为学习,我们可以试试将jQuery的一些用法用原生的JavaScript写出来。

  1. $('#container'); //选择id为"container"的元素并生成新的jQuery对象
    JavaScript写法:var container = document.querySelectorAll("#container");

  2. $('#container').find('li'); //选择id为"container"元素的后代"li"元素
    JavaScript写法:
    var list = document.querySelectorAll("#container li");

  3. $('a').on('click', fn); //在标签a上绑定事件"click"
    JavaScript写法:

    1
    2
    3
    4
    5
    [].forEach.call( document.querySelectorAll('a'), function(el) {
    el.addEventListener('click', function() {
    //function code
    }, false);
    });

因为querySelectorAll返回静态的NodeList而非数组,所以我们不能直接使用forEach方法,必须在Array对象上使用forEach

  1. $('ul').on('click', 'a', fn); //绑定事件到"ul"标签,但是只在用户触发其子元素"a"时启动事件处理程序
    JavaScript写法:

    1
    2
    3
    4
    5
    document.addEventListener('click', function(e) {
    if ( e.target.matchesSelector('ul a') ) {
    // proceed
    }
    }, false);
  2. $('#box').addClass('wrap'); //为"#box"添加"wrap"类
    JavaScript写法:

    1
    document.querySelector('#box').classList.add('wrap');
  3. $('#list').next(); //查找选择"#list"的相邻元素
    JavaScript写法:

    1
    var next = document.querySelector('#list').nextSibling;
  4. $('\<div id=box>\</div>').appendTo('body'); //"body"标签添加子元素'\<div id=box>\</div>'
    JavaScript写法:

    1
    2
    3
    var div = document.createElement('div');
    div.id = 'box';
    document.body.appendChild(div);
  5. $(document).ready(fn);
    JavaScript写法:

    1
    2
    3
    document.addEventListener('DOMContentLoaded', function() {
    // have fun
    });
  6. '.box').css('color', 'red'); //将".box"的style改为:color: red
    JavaScript写法:

    1
    2
    3
    [].forEach.call( document.querySelectorAll('.box'), function(el) {
    el.style.color = 'red'; // or add a class
    }); //[]也可以写为`Array.prototype`
  7. ()
    JavaScript写法:

    1
    2
    3
    4
    var $ = function(el) {
    return document.querySelectorAll(el);
    };
    //Usage = $('.box');
  8. $("#wrap").empty();//删除"#wrap"的所有子元素

JavaScript写法:

1
2
3
4
var parent = document.querySelectorAll("#wrap");
while (parent.firstChild) {
parent.removeChild(parent.firstChild);
}

参考:http://net.tutsplus.com/tutorials/javascript-ajax/from-jquery-to-javascript-a-reference/

CSS优先级计算

我们知道,当css样式同时作用于某个元素时,会产生层叠。浏览器层叠各个来源样式的顺序为:

1.浏览器默认样式表

2.用户样式表

3.作者链接样式表(按照它们链接到页面的先后顺序)

4.作者嵌入样式

5.作者行内样式

浏览器会按照上述顺序依次检查每个来源的样式,并在有定义的情况下,更新对每个标签属性值的设定。整个检查更新过程结束后,再将每个标签以最终设定的样式显示出来。

浏览器层叠还有一套层叠机制来计算优先级。

  • !important

如果某个声明后面加上!important则表明此样式具有最高权重。如果有多个声明使用!important则按照下面的规则来计算优先级。

  • 计算特指度(Specificity)

我们使用style属性-I-C-E来表示特指度。这里style属性表示行内样式。比如:

<p style="color: #ffffff"></p>

I 表示id,C表示class,E表示element。

下面这个图很好的诠释了CSS特指度:(来自http://css-tricks.com/specifics-on-css-specificity/)

1.某个元素使用行内样式,则在style属性的位置上加1;

2.选择符中有一个ID,就在I的位置上加1;

3.选择符中有一个类,就在C的位置上加1;

4.选择符中有一个元素(标签)名,就在E的位置上加1;

我们通过一些例子来说明:(来自http://css-tricks.com/specifics-on-css-specificity/)





注意:

1.(*) 选择符没有特指度 (0,0,0,0)

2.伪元素 (e.g. ::first-line) 在E上加1,而不是在C上加1

3.伪类选择器:not()本身不加特指度,只是在括号里面的元素加上特指度

举个例子来说明:

我们创建这样一个html文档:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf8">
<title>CSS特指度计算</title>
<link rel=stylesheet href="style.css" />
<style type="text/css">
em {color: blue;}
</style>
</head>

<body>
<article id="first">
<p class="odd"><em style="color: black">第一段文字</em></p>
<p>第二段文字</p>
</article>
</body>
</html>

style.css内容如下:

1
2
3
article#first p.odd em {
color: red;
}

这里为<em>设定了3个样式:分别是行内样式,嵌入样式和外部样式表。因为行内样式的特指度最高,所以应用行内样式,结果显示为<em>标签下的文字颜色为黑色。

Play with this gist on SassMeister.

如果去掉行内样式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf8">
<title>CSS特指度计算</title>
<link rel=stylesheet href="style.css" />
<style type="text/css">
em {color: blue;}
</style>
</head>

<body>
<article id="first">
<p class="odd"><em>第一段文字</em></p>
<p>第二段文字</p>
</article>
</body>
</html>

<em>标签下的文字颜色为红色,因为外部样式表中特指度比嵌入样式高。

如果在嵌入样式上加上!important则文字显示为蓝色。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf8">
<title>CSS特指度计算</title>
<link rel=stylesheet href="style.css" />
<style type="text/css">
em {color: blue !important;}
</style>
</head>

<body>
<article id="first">
<p class="odd"><em>第一段文字</em></p>
<p>第二段文字</p>
</article>
</body>
</html>

Play with this gist on SassMeister.

  • 设定的样式胜过继承的样式

设定的样式胜过继承的样式,此时不用考虑特指度(即显式设定优先)。下面简单解释一下,比如下面的标记

1
2
3
<div id="cascade_demo">
<p id="inheritance_fact">Inheritance is <em>weak</em> in the Cascade</p>
</div>

和下面的规则

1
2
div#cascade_demo p#inheritance_fact {color:blue;}
2 - 0 - 2 (高特指度)

会导致单词“weak”变成蓝色,因为它从父元素p那里继承了这个颜色值。

但是,只要我们再给em添加一条规则

1
2
em {color:red;}
0 - 0 - 1 (低特指度)

em就会变成红色。因为,虽然它的特指度低(0-0-1),但em继承的颜色值,会被为它明确(显式)指定的颜色值覆盖,就算(隐式)遗传该颜色值的规则的特指度高(2-0-2)也没有用。

参考

1.http://css-tricks.com/specifics-on-css-specificity/

2.《CSS设计指南》