python装饰器

编写传参的装饰器

通常我们见到的简单装饰器这样的:

import json
import functools

def json_output(func):
@functools.wraps(decorated)
def inner(args, **kwargs):
result = func(
args, **kwargs)
returnjson.dumps(result)
returninner

@json_output
deff():
return{‘status’: ‘done’}

当装饰器应用于函数 f 上时,它接受 f 作为其参数,返回一个函数 inner ,且将他绑定到变量f上。

示例中我们编写的装饰器 json_output 只接受一个隐式参数——即被装饰的方法,在使用此装饰器时本身看上去是并没有参数的。然而有时候需要让装饰器自身带有一些需要的信息,从而使装饰器可以使用恰当的方式装饰方法。比如上面的例子中,我们想通过向装饰器传入不同的参数来控制输出结果的缩进(indent)和排序(sort)。我们可以这么做:

import json
import functools

def json_output(indent=None,sort_keys=False):
def actual_decorator(func):
@functools.wraps(func)
def inner(args, **kwargs):
result = func(
args, **kwargs)
returnjson.dumps(result,indent=indent,sort_keys=sort_keys)
returninner
returnactual_decorator

@json_output(indent=4)
deff():
return{‘status’: ‘done’}

理解传参的装饰器

初次看起来会觉得比较绕人,因为函数里嵌套了两个函数定义,然而实际上和之前一个版本的区别在于为了接收json序列化的参数多包装了一层,所以

@json_output(indent=4)
deff():
return{‘status’: ‘done’}

相当于

@actual_decorator
deff():
return{‘status’: ‘done’}

这样看起来就会明晰很多。

实际上, 装饰器里的 @ 后接收一个函数,该函数以被装饰的函数(例子中是f)为参数,并且返回一个函数。当需要在装饰函数的同时传入参数的话,那么就需要多包装一层,先传入参数(例子中是 indent=4 )返回一个装饰的函数(例子中是 actual_decorator ), 这个返回的的函数 就跟以前一样接受被装饰的函数(f)作为参数并且返回一个函数作为装饰最后的方法供调用。

传参和不传参的兼容

然而当我们像上面那样定义装饰器时,就不能这样调用:

import json
import functools

def json_output(indent=None,sort_keys=False):
def actual_decorator(func):
@functools.wraps(func)
def inner(args, **kwargs):
result = func(
args, **kwargs)
returnjson.dumps(result,indent=indent,sort_keys=sort_keys)
returninner
returnactual_decorator

@json_output
deff():
return{‘status’: ‘done’}

在实际的项目过程中,有时会出现这样的状况: 一开始写的装饰器时不需要使用时传参数的,后来发现有必要传参数,改好后原来不传参的装饰器不能正常使用了,这是修改原来使用的地方是项痛苦的事情。

这时候就需要对装饰器做一个兼容,使它在以下情况都可用:

@json_output
@json_output()
@json_output(indent=4)

具体做法如下:

import json
import functools

def json_output(decorated_=None,indent=None,sort_keys=False):
ifdecorated_ and(indent orsort_keys):
raise

def actual_decorator(func):
    @functools.wraps(func)
    def inner(*args, **kwargs):
        result = func(*args, **kwargs)
        returnjson.dumps(result,indent=indent,sort_keys=sort_keys)
    returninner
ifdecorated_:
    returnactual_decorator(decorated_)
else:
    returnactual_decorator

@json_output(indent=4)
def f1():
return{‘status’: ‘done’}

@json_output
def f2():
return{‘status’: ‘done’}

@json_output()
def f3():
return{‘status’: ‘done’}

print f1()
print f2()
print f3()

代码中关键的地方在于 json_output 在最后对参数 decorated 进行了判断,有的话证明是不传参调用,那么直接返回 actual_decorator 的调用;没有的话则代表是传参类型的调用(虽然参数可能不存在),那么返回 actual_decorator 。其中有点需要注意, josn_output 的传参需要使用关键字参数,如果像下面这样直接传一个位置参数,那么根据现在的实现会出现错误(因为它会被当成 decorated_ )。

@json_output(4) #错误的使用方法
def f4():
return{‘status’: ‘done’}

分享到

python中的单列模式

单例模式

单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。

比如,某个服务器程序的配置信息存放在一个文件中,客户端通过一个 AppConfig 的类来读取配置文件的信息。如果在程序运行期间,有很多地方都需要使用配置文件的内容,也就是说,很多地方都需要创建 AppConfig 对象的实例,这就导致系统中存在多个 AppConfig 的实例对象,而这样会严重浪费内存资源,尤其是在配置文件内容很多的情况下。事实上,类似 AppConfig 这样的类,我们希望在程序运行期间只存在一个实例对象。

在 Python 中,我们可以用多种方法来实现单例模式:

使用模块
使用 new
使用装饰器(decorator)
使用元类(metaclass)

使用模块

其实,Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。如果我们真的想要一个单例类,可以考虑这样做:

mysingleton.py

1
2
3
4
5
class My_Singleton(object):
def foo(self):
pass

my_singleton = My_Singleton()

将上面的代码保存在文件 mysingleton.py 中,然后这样使用:

1
2
3
from mysingleton import my_singleton

my_singleton.foo()

使用 new

为了使类只能出现一个实例,我们可以使用 new 来控制实例的创建过程,代码如下:

1
2
3
4
5
6
7
8
9
class Singleton(object):
_instance = None
def __new__(cls, *args, **kw):
if not cls._instance:
cls._instance = super(Singleton,cls).__new__(cls, *args, **kw)
return cls._instance

class MyClass(Singleton):
a = 1

在上面的代码中,我们将类的实例和一个类变量 _instance 关联起来,如果 cls._instance 为 None 则创建实例,否则直接返回 cls._instance。

执行情况如下:

1
2
3
4
5
6
7
8
>>> one = MyClass()
>>> two = MyClass()
>>> one == two
True
>>> one istwo
True
>>> id(one),id(two)
(4303862608,4303862608)

使用装饰器

我们知道,装饰器(decorator)可以动态地修改一个类或函数的功能。这里,我们也可以使用装饰器来装饰某个类,使其只能生成一个实例,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from functools import wraps

def singleton(cls):
instances = {}
@wraps(cls)
def getinstance(*args, **kw):
if cls not in instances:
instances[cls] = cls(*args, **kw)
return instances[cls]
return getinstance

@singleton
class MyClass(object):
a = 1

在上面,我们定义了一个装饰器 singleton,它返回了一个内部函数 getinstance,该函数会判断某个类是否在字典 instances 中,如果不存在,则会将 cls 作为 key,cls(*args, **kw) 作为 value 存到 instances 中,否则,直接返回 instances[cls]。

使用 metaclass

元类(metaclass)可以控制类的创建过程,它主要做三件事:

拦截类的创建
修改类的定义
返回修改后的类

用元类实现单例模式的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton,cls).__call__(*args, **kwargs)
return cls._instances[cls]

# Python2
class MyClass(object):
__metaclass__ = Singleton

# Python3
# class MyClass(metaclass=Singleton):
# pass

小结

Python 的模块是天然的单例模式,这在大部分情况下应该是够用的,当然,我们也可以使用装饰器、元类等方法

分享到

python时间日期格式化

python中时间日期格式化符号:
%y 两位数的年份表示(00-99)
%Y 四位数的年份表示(000-9999)
%m 月份(01-12)
%d 月内中的一天(0-31)
%H 24小时制小时数(0-23)
%I 12小时制小时数(01-12)
%M 分钟数(00=59)
%S 秒(00-59)

%a 本地简化星期名称
%A 本地完整星期名称
%b 本地简化的月份名称
%B 本地完整的月份名称
%c 本地相应的日期表示和时间表示
%j 年内的一天(001-366)
%p 本地A.M.或P.M.的等价符
%U 一年中的星期数(00-53)星期天为星期的开始
%w 星期(0-6),星期天为星期的开始
%W 一年中的星期数(00-53)星期一为星期的开始
%x 本地相应的日期表示
%X 本地相应的时间表示
%Z 当前时区的名称
%% %号本身

分享到

bash入门栗子

【例子:001】判断输入为数字,字符或其他

1
2
3
4
5
6
7
8
#!/bin/bash  
read -p "Enter a number or string here:" input

case $input in
[0-9]) echo -e "Good job, Your input is a numberic! \n" ;;
[a-zA-Z]) echo -e "Good job, Your input is a character! \n" ;;
*) echo -e "Your input is wrong, input again! \n" ;;
esac

【例子:002】求平均数

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/bin/bash  

# Calculate the average of a series of numbers.

SCORE="0"
AVERAGE="0"
SUM="0"
NUM="0"

while true; do

echo -n "Enter your score [0-100%] ('q' for quit): "; read SCORE;

if (("$SCORE" < "0")) || (("$SCORE" > "100")); then
echo "Be serious. Common, try again: "
elif [ "$SCORE" == "q" ]; then
echo "Average rating: $AVERAGE%."
break
else
SUM=$[$SUM + $SCORE]
NUM=$[$NUM + 1]
AVERAGE=$[$SUM / $NUM]
fi

done

echo "Exiting."

【例子:003】自减输出

代码如下:
[scriptname: doit.sh]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
while (( $# > 0 ))  
do
echo $*
shift
done
```
/> ./doit.sh a b c d e
a b c d e
b c d e
c d e
d e
e


# 【例子:004】在文件中添加前缀
代码如下:

# 人名列表
# cat namelist
Jame
Bob
Tom
Jerry
Sherry
Alice
John
```sh
# 脚本程序
# cat namelist.sh
#!/bin/bash
for name in $(cat namelist)
do
echo "name= " $name
done
echo "The name is out of namelist file"

输出结果

./namelist.sh

name= Jame
name= Bob
name= Tom
name= Jerry
name= Sherry
name= Alice
name= John

【例子:005】批量测试文件是否存在

代码如下:

[root@host ~]# cat testfile.sh

1
2
3
4
5
6
7
8
9
#!/bin/bash  


for file in test*.sh
do
if [ -f $file ];then
echo "$file existed."
fi
done

[root@host ~]# ./testfile.sh
test.sh existed.
test1.sh existed.
test2.sh existed.
test3.sh existed.
test4.sh existed.
test5.sh existed.
test78.sh existed.
test_dev_null.sh existed.
testfile.sh existed.

【例子:005】用指定大小文件填充硬盘

代码如下:

[root@host ~]# df -ih /tmp
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/mapper/vg00-lvol5
1000K 3.8K 997K 1% /tmp
[root@host ~]# cat cover_disk.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/bin/env bash  
counter=0
max=3800
remainder=0
while true
do
((counter=counter+1))
if [ ${#counter} -gt $max ];then
break
fi
((remainder=counter%1000))
if [ $remainder -eq 0 ];then
echo -e "counter=$counter\tdate=" $(date)
fi
mkdir -p /tmp/temp
cat < testfile > "/tmp/temp/myfile.$counter"
if [ $? -ne 0 ];then
echo "Failed to write file to Disk."
exit 1
fi
done
echo "Done!"

[root@host ~]# ./cover_disk.sh
counter=1000 date= Wed Sep 10 09:20:39 HKT 2014
counter=2000 date= Wed Sep 10 09:20:48 HKT 2014
counter=3000 date= Wed Sep 10 09:20:56 HKT 2014
cat: write error: No space left on device
Failed to write file to Disk.
dd if=/dev/zero of=testfile bs=1M count=1

【例子:006】通过遍历的方法读取配置文件

代码如下:

[root@host ~]# cat hosts.allow
127.0.0.1
127.0.0.2
127.0.0.3
127.0.0.4
127.0.0.5
127.0.0.6
127.0.0.7
127.0.0.8
127.0.0.9
[root@host ~]# cat readlines.sh

1
2
3
4
5
6
7
8
9
10
#!/bin/env bash  
i=0
while read LINE;do
hosts_allow[$i]=$LINE
((i++))
done < hosts.allow
for ((i=1;i<=${#hosts_allow[@]};i++)); do
echo ${hosts_allow[$i]}
done
echo "Done"

[root@host ~]# ./readlines.sh
127.0.0.2
127.0.0.3
127.0.0.4
127.0.0.5
127.0.0.6
127.0.0.7
127.0.0.8
127.0.0.9
Done

【例子:007】简单正则表达式应用

代码如下:

[root@host ~]# cat regex.sh

1
2
3
4
5
6
7
8
9
10
11
#!/bin/env sh  
#Filename: regex.sh
regex="[A-Za-z0-9]{6}"
if [[ $1 =~ $regex ]]
then
num=$1
echo $num
else
echo "Invalid entry"
exit 1
fi

[root@host ~]# ./regex.sh 123abc
123abc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/env bash  
#Filename: validint.sh
validint(){
ret=`echo $1 | awk '{start = match($1,/^-?[0-9]+$/);if (start == 0) print "1";else print "0"}'`
return $ret
}

validint $1

if [ $? -ne 0 ]; then
echo "Wrong Entry"
exit 1
else
echo "OK! Input number is:" $1
fi

【例子:008】简单的按日期备份文件

代码如下:

#!/bin/bash  

NOW=$(date +"%m-%d-%Y")      # 当前日期  
FILE="backup.$NOW.tar.gz"    # 备份文件  
echo "Backing up data to /tmp/backup.$NOW.tar.gz file, please wait..."  #打印信息  
tar xcvf /tmp/backup.$NOW.tar.gz /home/ /etc/ /var       # 同时备份多个文件到指定的tar压缩文件中  
echo "Done..."  
分享到

bash简单实用命令

help 帮助命令

ls —help |more 获取ls 命令帮助,并分屏显示。

  1. 列出文件目录清单dir 和ls
    ls -a :显示当前目录中文件和子目录,包含隐含文件。

ls -l :以长格式来显示当前目录中文件的详细信息。(最常用)

ls -al | more :以长格式显示当前目录中文件的详细信息,并包含隐含文件,同时如果一屏显示不完分屏显示(相当于dos中的dir /p /a)

  1. 切换路径cd

同windows 一样,“.”表示当前目录自己,“..”表示上一级目录,所以,在命令行中输入cd ..(注意中间有空格),就回到上一级目录,当然也可以输入绝对路径来改变工作目录。例如:输入cd /usr/share/fonts并回车就切换到根目录下usr下share 子目录中的fonts子目录。

  1. 建立目录mkdir

mkdir 目录名 :在当前目录中创建“目录名”目录。

  1. 删除文件或目录 rm

相当于dos 中的del和deltree 命令

例示:

rm -f *.txt 强制删除当前目录下所有的txt 文件

rm -fr 某目录名 强制删除当前目录下的某目录(包括其所有文件及子目录)

注意:删除目录也可用rmdir,但是该命令只能删除空目录,不方便。

  1. 复制文件或目录 cp

相当于dos 中的copy 和xcopy

例示:

cp *.txt /home 复制当前目录中所有txt 文件到/home 目录中

cp -r 某目录名 /home 把当前目录中的某目录(包含其子目录)复制到/home 目录中

分享到

移动端前端适配方案

关于移动适配技术方案4种对比:

  1. 媒体查询的方式即CSS3的meida queries
  2. flex 弹性布局 (天猫首页)
  3. rem+viewport缩放 (淘宝首页)
  4. rem 方式 (魅族移动端的实现方式)

Media Queries

meida queries 的方式可以说是我早期采用的布局方式,它主要是通过查询设备的宽度来执行不同的 css 代码,最终达到界面的配置。核心语法是:

1
2
3
@media screen and (max-width: 600px) { /*当屏幕尺寸小于600px时,应用下面的CSS样式*/
/*你的css代码*/
}

优点

  • media query可以做到设备像素比的判断,方法简单,成本低,特别是对移动和PC维护同一套代码的时候。目前像- Bootstrap等框架使用这种方式布局
  • 图片便于修改,只需修改css文件
  • 调整屏幕宽度的时候不用刷新页面即可响应式展示

缺点

  • 代码量比较大,维护不方便
  • 为了兼顾大屏幕或高清设备,会造成其他设备资源浪费,特别是加载图片资源
  • 为了兼顾移动端和PC端各自响应式的展示效果,难免会损失各自特有的交互方式

flex弹性布局

它的viewport是固定的:
高度定死,宽度自适应,元素都采用px做单位。

rem+viewport 缩放

根据屏幕宽度设定 rem 值,需要适配的元素都使用 rem 为单位,不需要适配的元素还是使用 px 为单位。
根据rem将页面放大dpr倍, 然后viewport设置为1/dpr.

  • 如iphone6 plus的dpr为3, 则页面整体放大3倍, 1px(css单位)在plus下默认为3px(物理像素)
  • 然后viewport设置为1/3, 这样页面整体缩回原始大小. 从而实现高清。

设备的物理分辨率/(devicePixelRatio * scale)
在scale为1的情况下,device-width = 设备的物理分辨率/devicePixelRatio 。

rem 实现

viewport也是固定的:
通过以下代码来控制rem基准值(设计稿以720px宽度量取实际尺寸)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
!function (d) {
var c = d.document;
var a = c.documentElement;
var b = d.devicePixelRatio;
var f;

function e() {
var h = a.getBoundingClientRect().width, g;
if (b === 1) {
h = 720
}
if(h>720) h = 720;//设置基准值的极限值
g = h / 7.2;
a.style.fontSize = g + "px"
}

if (b > 2) {
b = 3
} else {
if (b > 1) {
b = 2
} else {
b = 1
}
}
a.setAttribute("data-dpr", b);
d.addEventListener("resize", function () {
clearTimeout(f);
f = setTimeout(e, 200)
}, false);
e()
}(window);

css通过sass预编译,设置量取的px值转化rem的变量$px: (1/100)+rem;;

淘宝实现方式

transform: scale(0.5)

CSS代码:

1
2
3
4
5
6
7
8
div{
width: 1px;
height: 100%;
display: block;
border-left: 1px solid #e5e5e5;
-webkit-transform: scaleX(.5);
transform: scaleX(.5);
}

缺点:

  • 圆角无法实现,实现4条边框比较麻烦,并且只能单独实现,如果嵌套,会对包含的效果产生不想要的效果,所以此方案配合:after和before独立使用较多。
    box-shadow

实现方法:

利用CSS对阴影处理的方式实现0.5px的效果。

1
-webkit-box-shadow:0 1px 1px -1px rgba(0, 0, 0, 0.5);

优点:

基本所有场景都能满足,包含圆角的button,单条,多条线。

缺点:

  • 颜色不好处理, 黑色 rgba(0,0,0,1) 最深的情况了。有阴影出现,不好用。
  • 大量使用box-shadow可能会导致性能瓶颈。
  • 四条边框实现效果不理想。

图片实现

使用 background-image 实现1px有两种方式: 渐变 linear-gradient 或直接使用图片(base64)。

渐变 linear-gradient (50%有颜色,50%透明)

单条线:

1
2
3
4
5
6
7
div {
height: 1px;
background-image: -webkit-linear-gradient(top,transparent 50%,#000 50%);
background-position: top left;
background-repeat: no-repeat
background-size: 100% 1px;
}

多条线:

1
2
3
4
5
6
div {
background-image:-webkit-linear-gradient(top, transparent 50%, #000 50%),-webkit-linear-gradient(bottom, transparent 50%, #000 50%),-webkit-linear-gradient(left, transparent 50%, #000 50%),-webkit-linear-gradient(right, transparent 50%, #000 50%);
background-size: 100% 1px,100% 1px,1px 100%,1px 100%;
background-repeat: no-repeat;
background-position: top left, bottom left, left top, right top;
}

优点:

  • 可以设置单条,多条边框
  • 可以设置颜色

    缺点:

  • 大量使用渐变可能导致性能瓶颈

  • 代码量大
  • 多背景图片有兼容性问题
分享到

web前端自适应技巧相关学习

meta基础知识

H5页面窗口自动调整到设备宽度,并禁止用户缩放页面

1
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />

忽略将页面中的数字识别为电话号码

1
<meta name="format-detection" content="telephone=no" />

忽略Android平台中对邮箱地址的识别

1
<meta name="format-detection" content="email=no" />

当网站添加到主屏幕快速启动方式,可隐藏地址栏,仅针对ios的safari

1
2
<meta name="apple-mobile-web-app-capable" content="yes" />
<!-- ios7.0版本以后,safari上已看不到效果 -->

将网站添加到主屏幕快速启动方式,仅针对ios的safari顶端状态条的样式

1
2
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<!-- 可选default、black、black-translucent -->

viewport模板

viewport模板——通用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport">
<meta content="yes" name="apple-mobile-web-app-capable">
<meta content="black" name="apple-mobile-web-app-status-bar-style">
<meta content="telephone=no" name="format-detection">
<meta content="email=no" name="format-detection">
<title>标题</title>
<link rel="stylesheet" href="index.css">
</head>

<body>
这里开始内容
</body>

</html>

viewport模板 - target-densitydpi=device-dpi,android 2.3.5以下版本不支持

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=750, user-scalable=no, target-densitydpi=device-dpi">
<!-- width取值与页面定义的宽度一致 -->
<meta content="yes" name="apple-mobile-web-app-capable">
<meta content="black" name="apple-mobile-web-app-status-bar-style">
<meta content="telephone=no" name="format-detection">
<meta content="email=no" name="format-detection">
<title>标题</title>
<link rel="stylesheet" href="index.css">
</head>

<body>
这里开始内容
</body>

</html>

移动端如何定义字体font-family

中文字体使用系统默认即可,英文用Helvetica

1
2
/* 移动端定义字体的代码 */
body{font-family:Helvetica;}

移动端字体单位font-size选择px还是rem

对于只需要适配少部分手机设备,且分辨率对页面影响不大的,使用px即可

对于需要适配各种移动设备,使用rem,例如只需要适配iPhone和iPad等分辨率差别比较挺大的设备

rem配置参考,适合视觉稿宽度为640px的:

1
<meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport">

1
2
3
4
5
6
7
8
html{font-size:10px}
@media screen and (min-width:321px) and (max-width:375px){html{font-size:11px}}
@media screen and (min-width:376px) and (max-width:414px){html{font-size:12px}}
@media screen and (min-width:415px) and (max-width:639px){html{font-size:15px}}
@media screen and (min-width:640px) and (max-width:719px){html{font-size:20px}}
@media screen and (min-width:720px) and (max-width:749px){html{font-size:22.5px}}
@media screen and (min-width:750px) and (max-width:799px){html{font-size:23.5px}}
@media screen and (min-width:800px){html{font-size:25px}}

移动端click屏幕产生200-300 ms的延迟响应

触摸事件的响应顺序

1、ontouchstart
2、ontouchmove
3、ontouchend
4、onclick

什么是Retina 显示屏,带来了什么问题

retina:一种具备超高像素密度的液晶屏,同样大小的屏幕上显示的像素点由1个变为多个,如在同样带下的屏幕上,苹果设备的retina显示屏中,像素点1个变为4个

在高清显示屏中的位图被放大,图片会变得模糊,因此移动端的视觉稿通常会设计为传统PC的2倍

那么,前端的应对方案是:
设计稿切出来的图片长宽保证为偶数,并使用backgroud-size把图片缩小为原来的1/2

1
2
//例如图片宽高为:200px*200px,那么写法如下
.css{width:100px;height:100px;background-size:100px 100px;}

其它元素的取值为原来的1/2,例如视觉稿40px的字体,使用样式的写法为20px

1
.css{font-size:20px}

ios系统中元素被触摸时产生的半透明灰色遮罩怎么去掉

1
a,button,input,textarea{-webkit-tap-highlight-color: rgba(0,0,0,0;)}

部分android系统中元素被点击时产生的边框怎么去掉

1
2
3
4
a,button,input,textarea{
-webkit-tap-highlight-color: rgba(0,0,0,0;)
-webkit-user-modify:read-write-plaintext-only;
}

webkit表单元素的默认外观怎么重置

1
.css{-webkit-appearance:none;}

禁止ios和android用户选中文字

1
.css{-webkit-user-select:none}

禁止ios 长按时不触发系统的菜单,禁止ios&android长按时下载图片

1
.css{-webkit-touch-callout: none}

IE10(winphone8)表单元素默认外观如何重置

禁用 radio 和 checkbox 默认样式

::-ms-check 适用于表单复选框或单选按钮默认图标的修改,同样有多个属性值,设置它隐藏 (display:none) 并使用背景图片来修饰可得到我们想要的效果。

1
2
3
input[type=radio]::-ms-check,input[type=checkbox]::-ms-check{
display: none;
}

禁用PC端表单输入框默认清除按钮

当表单文本输入框输入内容后会显示文本清除按钮,::-ms-clear 适用于该清除按钮的修改,同样设置使它隐藏 (display:none) 并使用背景图片来修饰可得到我们想要的效果。

1
2
3
input[type=text]::-ms-clear,input[type=tel]::-ms-clear,input[type=number]::-ms-clear{
display: none;
}

禁用 select 默认下拉箭头

::-ms-expand 适用于表单选择控件下拉箭头的修改,有多个属性值,设置它隐藏 (display:none) 并使用背景图片来修饰可得到我们想要的效果。

1
2
3
select::-ms-expand {
display: none;
}

打电话发短信写邮件怎么实现

打电话,发短信(winphone系统无效),写邮件

1
2
3
<a href="tel:0755-10086">打电话给:0755-10086</a>
<a href="sms:10086">发短信给: 10086</a>
<a href="mailto:peun@foxmail.com">peun@foxmail.com</a>

屏幕旋转的事件和样式

事件

window.orientation,取值:正负90表示横屏模式、0和180表现为竖屏模式;

1
2
3
4
5
6
7
8
9
10
11
window.onorientationchange = function(){
switch(window.orientation){
case -90:
case 90:
alert("横屏:" + window.orientation);
case 0:
case 180:
alert("竖屏:" + window.orientation);
break;
}
}

样式

1
2
3
4
5
6
7
8
9
//竖屏时使用的样式
@media all and (orientation:portrait) {
.css{}
}

//横屏时使用的样式
@media all and (orientation:landscape) {
.css{}
}

audio元素和video元素在ios和andriod中无法自动播放

应对方案:触屏即播

1
2
3
$('html').one('touchstart',function(){
audio.play()
})

手机拍照和上传图片

的accept 属性

1
2
3
4
<!-- 选择照片 -->
<input type=file accept="image/*">
<!-- 选择视频 -->
<input type=file accept="video/*">

使用总结:

ios 有拍照、录像、选取本地图片功能
部分android只有选取本地图片功能
winphone不支持
input控件默认外观丑陋

微信浏览器用户调整字体大小后页面矬了,怎么阻止用户调整

原因

android侧是复写了layoutinflater 对textview做了统一处理
ios侧是修改了body.style.webkitTextSizeAdjust值
解决方案:

android使用以下代码,该接口只在微信浏览器下有效(感谢jationhuang同学提供)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* 页面加入这段代码可使Android机器页面不再受到用户字体缩放强制改变大小
* 但是会有一个1秒左右的延迟,期间可以考虑通过loading展示
* 仅供参考
*/
(function(){
if (typeof(WeixinJSBridge) == "undefined") {
document.addEventListener("WeixinJSBridgeReady", function (e) {
setTimeout(function(){
WeixinJSBridge.invoke('setFontSizeCallback',{"fontSize":0}, function(res) {
alert(JSON.stringify(res));
});
},0);
});
} else {
setTimeout(function(){
WeixinJSBridge.invoke('setFontSizeCallback',{"fontSize":0}, function(res) {
alert(JSON.stringify(res));
});
},0);
}
})();

ios使用-webkit-text-size-adjust禁止调整字体大小
body{-webkit-text-size-adjust: 100%!important;}
最好的解决方案:

整个页面用rem或者百分比布局

消除transition闪屏

网络都是这么写的,但我并没有测试出来

1
2
3
4
5
6
.css{
/*设置内嵌的元素在 3D 空间如何呈现:保留 3D*/
-webkit-transform-style: preserve-3d;
/*(设置进行转换的元素的背面在面对用户时是否可见:隐藏)*/
-webkit-backface-visibility: hidden;
}

开启硬件加速

解决页面闪白
保证动画流畅

1
2
3
4
5
6
.css {
-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}

input在ios下,输入的时候英文首字母的默认大写

1
<input autocapitalize="off" autocorrect="off" />

android 上去掉语音输入按钮

1
input::-webkit-input-speech-button {display: none}

移动端使用框架

  1. zepto.js
  2. iscroll.js
    解决页面不支持弹性滚动,不支持fixed引起的问题~
    实现下拉刷新,滑屏,缩放等功能~
  3. underscore.js

滑屏框架 slip.js iSlider.js fullpage.js
swiper.js

  1. flex布局
    flex布局目前可使用在移动中,并非所有的语法都全兼容,但以下写法笔者实践过,效果良好~
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* ============================================================
flex:定义布局为盒模型
flex-v:盒模型垂直布局
flex-1:子元素占据剩余的空间
flex-align-center:子元素垂直居中
flex-pack-center:子元素水平居中
flex-pack-justify:子元素两端对齐
兼容性:ios 4+、android 2.3+、winphone8+
============================================================ */
.flex{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}
.flex-v{-webkit-box-orient:vertical;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}
.flex-1{-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1;}
.flex-align-center{-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;}
.flex-pack-center{-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;}
.flex-pack-justify{-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;}

实例: 两端对齐

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport">
<meta content="yes" name="apple-mobile-web-app-capable">
<meta content="black" name="apple-mobile-web-app-status-bar-style">
<meta content="telephone=no" name="format-detection">
<meta content="email=no" name="format-detection">
<style type="text/css">
/* ============================================================
flex:定义布局为盒模型
flex-v:盒模型垂直布局
flex-1:子元素占据剩余的空间
flex-align-center:子元素垂直居中
flex-pack-center:子元素水平居中
flex-pack-justify:子元素两端对齐
兼容性:ios 4+、android 2.3+、winphone8+
============================================================ */
.flex{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}
.flex-v{-webkit-box-orient:vertical;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}
.flex-1{-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1;}
.flex-align-center{-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;}
.flex-pack-center{-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;}
.flex-pack-justify{-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;}
</style>
</head>
<body>

<div class="flex flex-pack-justify">
<div>模块一</div>
<div>模块二</div>
<div>模块三</div>
<div>模块四</div>
</div>

</body>
</html>

  1. FastClick

消除在移动浏览器上触发click事件与一个物理Tap(敲击)之间的300延迟

  1. Sea.js

提供简单、极致的模块化开发体验

分享到

viewpor网页自适应

viewport 手机端浏览器可视窗口大小

实际浏览器可视域的大小比默认viewport 宽度小 ,就会出现滚动条

1px 在不同设备上有不同定义

计算器显示器是通过显示像素点,显示图片的,像素越多看的细,像素越少越模糊,这个就是物理像素.
在css 中也有px属性,叫做设备独立像素
devicePixelRatio = 物理像素 / 独立像素。

viewport三大理论 ppk

  1. layout viewport layout viewport的宽度可以通过document.documentElement.clientWidth 来获取
  2. visual viewport visual viewport的宽度可以通过window.innerWidth 来获取
  3. ideal viewport 没有一个固定的尺寸,不同的设备拥有有不同的ideal viewport。

利用meta标签使用viewport

移动设备默认的viewport是layout viewport,也就是那个比屏幕要宽的viewport,但在进行移动设备网站的开发时,我们需要的是ideal viewport。
那么怎么才能得到ideal viewport呢?这就该轮到meta标签出场了。

1
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1,user-scalable=no">

width 设置layout viewport 的宽度,为一个正整数,或字符串”device-width”
initial-scale 设置页面的初始缩放值,为一个数字,可以带小数
minimum-scale 允许用户的最小缩放值,为一个数字,可以带小数
maximum-scale 允许用户的最大缩放值,为一个数字,可以带小数
height 设置layout viewport 的高度,这个属性对我们并不重要,很少使用
user-scalable 是否允许用户进行缩放,值为”no”或”yes”, no 代表不允许,yes代表允许

把当前的viewport宽度设置为 ideal viewport 的宽度

1
<meta name="viewport" content="width=device-width">  or <meta name="viewport" content="initial-scale=1">

淘宝的布局方案解析

(1)动态设置viewport的scale

1
2
var scale = 1 / devicePixelRatio;  
document.querySelector('meta[name="viewport"]').setAttribute('content','initial-scale=' + scale + ',maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');

淘宝布局的第二个要点,就是html元素的font-size的计算公式,font-size = deviceWidth / 10:
(2)动态设置html的font-size

1
2
3
4
5
6
7
//flexible中定义<html>font-size
var width = docEl.getBoundingClientRect().width;
if (width / dpr > 540) {
width = 540 * dpr;
}
var rem = width / 10;
docEl.style.fontSize = rem + 'px';

(3)布局的时候,各元素的css尺寸=设计稿标注尺寸/设计稿横向分辨率/10
(4)font-size可能需要额外的媒介查询,并且font-size不使用rem

淘宝移动端自适应方案—lib.flexible库解析

它的主要js文件有三个,包括flexiblecss.js、flexible.js、makegrid.js
flexible.js—布局的核心js
flexiblecss.js—注入统一的css样式,比如去掉所有元素的内外边距,去掉默认边框等等
makegrid.js—栅格系统

阿里CDN:

其中initial-dpr会把dpr强制设置为给定的值。如果手动设置了dpr之后,不管设备是多少的dpr,都会强制认为其dpr是你设置的值。在此不建议手动强制设置dpr,因为在Flexible中,只对iOS设备进行dpr的判断,对于Android系列,始终认为其dpr为1。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
if (!dpr && !scale) {  
var isAndroid = win.navigator.appVersion.match(/android/gi);
var isIPhone = win.navigator.appVersion.match(/iphone/gi);
var devicePixelRatio = win.devicePixelRatio;
if (isIPhone) {
// iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
dpr = 3;
} else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
dpr = 2;
} else {
dpr = 1;
}
} else {
// 其他设备下,仍旧使用1倍的方案
dpr = 1;
}
scale = 1 / dpr;
}

flexible的实质 能通过js动态更改meta标签

1
2
3
4
5
6
7
8
9
10
11
var metaEl = doc.createElement('meta');  
var scale = isRetina ? 0.5:1;
metaEl.setAttribute('name', 'viewport');
metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
if (docEl.firstElementChild) {
document.documentElement.firstElementChild.appendChild(metaEl);
} else {
var wrap = doc.createElement('div');
wrap.appendChild(metaEl);
documen.write(wrap.innerHTML);
}
  • 动态改写标签
  • 给元素添加data-dpr属性,并且动态改写data-dpr的值
  • 给元素添加font-size属性,并且动态改写font-size的值

把视觉稿中的px转换成rem

目前Flexible会将视觉稿分成100份,而每一份被称为一个单位a。同时1rem单位被认定为10a。
1a = 7.5px
1rem = 75px
那么我们的视觉稿就分成了10a,也就是整个宽度为10rem,对应的font-size为75px;

推荐CSSREM——px转化rem小工具

使用[data-dpr]属性来区分不同dpr下的文本字号大小。

1
2
3
4
5
6
7
8
9
10
11
div {  
width: 1rem;
height: 0.4rem;
font-size: 12px; // 默认写上dpr为1的fontSize
}
[data-dpr="2"] div {
font-size: 24px;
}
[data-dpr="3"] div {
font-size: 36px;
}

字体慎用rem,误差太大了,因为不能满足任何屏幕下字体大小相同,所以建议标题类用rem,要求字体大小相同的部分还是用px

栅格系统—makegrid.js

js 代码

1
2
3
4
5
6
7
8
9
10
var gridMode = {  
'750-12':{ designWidth:750,designUnit:6,columnCount:12,columnXUnit:7,gutterXUnit:3,edgeXUnit:4
},
'750-6': { designWidth:750,designUnit:6,columnCount:6,columnXUnit:17,gutterXUnit:3,edgeXUnit:4
},
'640-12': { designWidth:640,designUnit:4,columnCount:12,columnXUnit:11,gutterXUnit:2,edgeXUnit:3
},
'640-6': { designWidth:640,designUnit:4,columnCount:6,columnXUnit:24,gutterXUnit:2,edgeXUnit:3
}
}

参数说明
lib.flexible.makeGrid(params)
• [Object params]

  • designWidth - 设计稿宽度

  • designUnit - 设计稿最小单位a(以px为单位)

  • columnCount - 栅格列数
  • columnXUnit - 栅格列宽(以a为单位)
  • gutterXUnit - 栅格间距(以a为单位)

  • edgeXUnit - 页面左右边距(以a为单位)

  • className - 栅格样式的名称(可省略,默认为grid)

利用meta输出栅格样式


栅格化代码举例

1
2
3
4
5
6
<meta content="modeName=640-12" name="grid" />  
<div class="grid">
<div class="col-4"></div>
<div class="col-4"></div>
<div class="col-4"></div>
</div>

瞅瞅flexible.js 源码

flexible.js—布局的核心js,里边主要包含下边几点来实现适配布局

1)设置像素比dpr和scale
有两种模式:一种是自适应,一种是手动配置dpr
适应模式:根据已有的meta标签来设置dpr和scale
手动配置:
2)如果没有设置缩放比,根据苹果用户或者安卓用户设置缩放比。iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案,安卓的均采用1。
源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var isAndroid = win.navigator.appVersion.match(/android/gi);  
var isIPhone = win.navigator.appVersion.match(/iphone/gi);
var devicePixelRatio = win.devicePixelRatio;
if (isIPhone) {
// iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
dpr = 3;
} else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
dpr = 2;
} else {
dpr = 1;
}
} else {
// 其他设备下,仍旧使用1倍的方案
dpr = 1;
}

3)前边谈到淘宝布局方案的时候,说到淘宝触屏版布局的前提就是viewport的scale根据devicePixelRatio动态设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//为html标签添加data-dpr属性
docEl.setAttribute('data-dpr', dpr);
//如果没有meta[name="viewport",添加meta标签
if (!metaEl) {
metaEl = doc.createElement('meta');
metaEl.setAttribute('name', 'viewport');
metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
if (docEl.firstElementChild) {
docEl.firstElementChild.appendChild(metaEl);
} else {
var wrap = doc.createElement('div');
wrap.appendChild(metaEl);
doc.write(wrap.innerHTML);
}
}

4)为html标签添加data-dpr属性
document.documentElement.setAttribute(‘data-dpr’, dpr);
5)刷新页面的rem基准值 (API—lib.flexible.refreshRem())

1
2
3
4
5
6
7
8
9
10
11
12
//根据dpr和物理像素设置rem
function refreshRem(){
//getBoundingClientRect().width相当于物理像素
var width = docEl.getBoundingClientRect().width;
// width / dpr > 540等于独立像素
if (width / dpr > 540) {
width = 540 * dpr;
}
var rem = width / 10;
docEl.style.fontSize = rem + 'px';
flexible.rem = win.rem = rem;
}

6)什么时候执行refreshRem()呢?
第一种当窗口大小发生变化,也就是触发resize事件的时候;

1
2
3
4
win.addEventListener('resize', function() {  
clearTimeout(tid);
tid = setTimeout(refreshRem, 300);
}, false);

第二种是当重新载入页面时,判断是否是缓存,如果是缓存,执行refreshRem()

1
2
3
4
5
6
win.addEventListener('pageshow', function(e) {  
if (e.persisted) {
clearTimeout(tid);
tid = setTimeout(refreshRem, 300);
}
}, false);

7)rem转化px (API—lib.flexible.rem2px([Number|String digital]))

1
2
3
4
5
6
7
8
flexible.rem2px = function(d) {  
//已定义var rem = width / 10;
var val = parseFloat(d) * this.rem;
if (typeof d === 'string' && d.match(/rem$/)) {
val += 'px';
}
return val;
}

rem转化px计算公式=d*(width/10)
8)px转化rem (API—lib.flexible.px2rem([Number|String digital]))

1
2
3
4
5
6
7
flexible.px2rem = function(d) {  
var val = parseFloat(d) / this.rem;
if (typeof d === 'string' && d.match(/px$/)) {
val += 'rem';
}
return val;
}

px转化rem计算公式=d/(width/10)

css布局适配问题避免:

  1. 盒子,图片等宽度设置首选百分比,次而选择rem,高度可以是固定值
  2. 字体可以不用rem,误差太大了,且不能满足任何屏幕下字体大小相同,所以建议标题类用rem,要求字体大小相同的部分还是用px;
  3. 遇到内容排列显示的布局,建议放弃float,可以直接使用display:inline-block。
  4. 慎用position属性;absolute会脱离文档流,relative则不会
  5. 如何解决盒子边框溢出?当你把元素宽度设为 width:100%时,有时可能会遇到元素的宽度超出了屏幕,
    这时可对元素加box-sizing:border-box属性,用来指定盒子大小包含边框和内边距
  6. 去除button在ios上的默认样式
    -webkit-appearance: none; border-radius: 0;
  7. 不想让按钮touch时有蓝色的边框
    outline:none;
  8. 去除webkit的滚动条
    element::-webkit-scrollbar{

    display: none;
    }

  9. 遇到过一个问题就是,当手机端点击input弹出键盘,整个视窗的高度就会变为减去键盘的高度,
    页面底部样式会乱,当时解决方法是用js获取整个页面高度赋值给body,等于说在不同的设备下写死不同的body高度值,底部就不会乱了
    $(“body”).css(“height”,parseInt($(“.wrap”).height())+parseInt($(“.icon-main”).height()));
  10. 如果想改变 placeholder里的文字,需要用c伪类
    ::-webkit-input-placeholder{

    color:#ccc
    }

附上简单淘宝适配源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta content="modeName=640-12" name="grid" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="description" content="">
<meta name="keywords" content="">
<title></title>
<style>
</style>
</head>
<body>
<style>
.grid{
margin-top: 1rem ;
background-color: #ccc;
padding-top: 0.6rem;
}
.grid > div {
text-align: center;
font-size:0.4rem;
}
.pic{
width:2rem;
height:2rem;
margin-bottom: 0.4rem;
}
.pic img{
width:1.4rem;
height:1.4rem;
}
.pic p{
width:2rem;
height:0.6rem;
position:relative;
top:2px;
color:#666;
}
</style>
<div class="grid">
<div class="col-3">
<div class="pic">
<img src="./../../img_lib/persion.png" alt="">
<p>天猫</p>
</div>
<div class="pic">
<img src="./../../img_lib/persion.png" alt="">
<p>聚划算</p>
</div>
</div>
<div class="col-3">
<div class="pic">
<img src="./../../img_lib/persion.png" alt="">
<p>天猫</p>
</div>
<div class="pic">
<img src="./../../img_lib/persion.png" alt="">
<p>聚划算</p>
</div>
</div>
<div class="col-3">
<div class="pic">
<img src="./../../img_lib/persion.png" alt="">
<p>天猫</p>
</div>
<div class="pic">
<img src="./../../img_lib/persion.png" alt="">
<p>聚划算</p>
</div>
</div>
<div class="col-3">
<div class="pic">
<img src="./../../img_lib/persion.png" alt="">
<p>天猫</p>
</div>
<div class="pic">
<img src="./../../img_lib/persion.png" alt="">
<p>聚划算</p>
</div>
</div>
</div>
</body>
<script src="http://g.tbcdn.cn/mtb/lib-flexible/0.3.2/flexible_css.js"></script>
<script src="http://g.tbcdn.cn/mtb/lib-flexible/0.3.2/flexible.js"></script>
<script src="http://g.tbcdn.cn/mtb/lib-flexible/0.3.2/makegrid.js"></script>
</html>
分享到

web前端基础知识备忘录

关于前端一些html css js 基础相关知识

CSS/CSS3长度、时间、频率、角度

一、CSS长度值

em 相对于父元素的字体大小
ex 相对于小写字母”x”的高度
gd 一般用在东亚字体排版上,这个与英文并无关系
rem 相对于根元素字体大小
vw 相对于视窗的宽度:视窗宽度是100vw
vh 相对于视窗的高度:视窗高度是100vh
vm 相对于视窗的宽度或高度,取决于哪个更小
ch 相对于0尺寸
px 相对于屏幕分辨率而不是视窗大小:通常为1个点或1/72英寸
in inch, 表英寸
cm centimeter, 表厘米
mm millimeter, 表毫米
pt 1/72英寸
pc 12点活字,或1/12点
% 相对于父元素。正常情况下是通过属性定义自身或其他元素

二、时间、频率、角度

deg degrees, 角度
grad grads, 百分度
rad radians, 弧度
turn turns, 圈数
ms milliseconds, 毫秒数
s seconds, 秒数
Hz Hertz, 赫兹
kHz kilohertz, 千赫

动态高度

1
min-height:calc(100vh + 51px);

导入自定义字体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*定义字体*/
@font-face{

font-family: matos;/* family name*/
src:url(fonts/glyphicons.woff), /*网页标准字体*/
url(fonts/glyphicons.ttf), /*apple 和ms 共同推出的字体格式*/
url(fonts/glyphicons.eot), /* 支持老版本ie字体*/
url(fonts/glyphicons.svg), /* 可变矢量图字体 scalable vector graphics*/
}

/* 使用字体*/
p{
font-family:matos;
}

分享到

google代码追踪标签管理器

tag manager

放入头部

1
2
3
4
5
6
7
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-N56SN5T');</script>
<!-- End Google Tag Manager -->

放入body尾部

1
2
3
4
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-N56SN5T"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->

ga

跟踪 ID:UA-104393124-1

1
2
3
4
5
6
7
8
9
10
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

ga('create', 'UA-104393124-1', 'auto');
ga('send', 'pageview');

</script>

百度上非阻塞方式ga

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script>
var gaJsHost = (("https:" == document.location.protocol)?"https://ssl." : "http://www.");
var head = document.getElementsByTagName("head")[0] || document.documentElement;
var script = document.createElement("script");
script.src = gaJsHost + "google-analytics.com/ga.js";
var done = false; // 防止onload,onreadystatechange同时执行
// 加载完毕后执行,适应所有浏览器
script.onload = script.onreadystatechange = function() {
if (!done && (!this.readyState ||
this.readyState === "loaded" ||
this.readyState === "complete")){
done = true;
try {
var pageTracker = _gat._getTracker("UA-104393124-1");
pageTracker._trackPageview();
} catch(err) {}
script.onload = script.onreadystatechange = null;
}
};
head.insertBefore(script,head.firstChild);
</script>
分享到