The North Face 亚洲通娱乐

偶尔在优酷上看到The North Face的亚洲通娱乐,顿时感觉太有精神了,太进取了;
看过这亚洲通娱乐真让我觉得应该加入他们阵营,放弃Columbia。

以下是看到的三段亚洲通娱乐:

一、人类探索之光 – The North Face北面新探索客故事

二、The North Face_ INTO THE MIND by Sherpas Cine

三、The North Face Alex Honnold – El Sendero Lumin

用CSS3写出iPhone中的返回按钮

好像写这个有点晚了,iOS已经从拟物化的年代进化到了扁平化的年代,那些圆角+渐变+阴影的年代已经过去,不过在此仍然要去说下古老的iOS返回按钮。

在过去的年代,大家都以iOS的设计元素为自己移动版页面的设计元素;当中自然少不了经典的返回按钮,看着似乎非常简单的一个返回按钮,但是就是没有啥办法能用代码写出来似的,那个讨厌的三角箭头只能让前端工程师无奈的使用一张图片来拼接(如淘宝、天猫、百度、美团都是图片处理方式);或者就根本不用那个按钮(如Yahoo、Google、Facebook根本就不用);当然我也相信已经有大牛有很好的处理方案,只是不像我这样出来得瑟罢了。

好了,不多说那些无用的,来说说我的解决方案:

先看看设计稿(呵呵,就拿我们公司的来说了)
header

1、确定HTML的结构,用一个标签加伪类其实是不行的,所以我用了两个嵌套的标签

<a class="btn-back" href="#">
    <span>首页</span>
</a>

2、首先想到的是右边一个标准Button,这个比较秒杀吧,所以不多说了,上图和代码

header_1

.btn-back span {
	display: inline-block;
	font-size: 13px;
	line-height: 27px;
	height: 27px;
	padding: 0 10px;
	background: -webkit-linear-gradient(top, #5bbfd8, #449fb6);
	background: -moz-linear-gradient(top, #5bbfd8, #449fb6);
	border: 1px solid #2c96b2;
	border-radius: 5px;
	text-shadow: 0 -1px 0 rgba(0, 0, 0, .4);
}

3、左边是一个三角型,但是那个通过border搞的三角不行,幸好CSS只是旋转和变形,搞一个正方形旋转差不多能实现了

这里需要用到下直角等腰三角型求边的公式(长边=短边*根号2),估计很多人不记得了吧:)
因为我们的正方形需要旋转45°,所以其实我们是需要求那条短边,左边那个正方型的宽高就是短变长;27/1.4142≈19.09,取整数19
其实画出正方形后还好做几步处理:
1) 将渐变倾斜-45°
2) 变形基点设置为0,0
3) 将正方形旋转45°
4) 将正方型X轴压缩
header_2

/*这里用了一个伪类:before*/
.btn-back:before {
	margin: 50px;
	content: '';
	display: inline-block;
	width: 18px;
	height: 18px;
	background: -webkit-linear-gradient(-45deg, #6eb7c9, #449fb6);/*背景旋转-45°*/
	background: -moz-linear-gradient(-45deg, #6eb7c9, #449fb6);
	border: 1px solid #2c96b2;
	-webkit-transform-origin: 0 0;/*设置基点为0,0*/
	-moz-transform-origin: 0 0;
	-webkit-transform: scaleX(0.8) rotate(45deg);/*X轴压缩,旋转45;后面的属性将被先这执行°*/
	-moz-transform: scaleX(0.8) rotate(45deg);
}

4、感觉差不多了,合并;然后修饰下

这里修饰也有几步
1) 将左边的三角型进行绝对定位
2) 去掉按钮的左边框调整左边的两个圆角;并且设置为相对定位,z-index设置为2,这样可以盖住小三角的右半部分
3) 给左边的小三角加上圆角(因为圆角会减少高度,所以可能需要微调高度)header_3

.btn-back {
	font: 14px/27px Arial,Helvetica,sans-serif;
	color: #fff;
	text-decoration: none;

	position: relative;
	display: block;
	margin-top: 11px;
}
/*按钮主体*/
.btn-back span {
	display: inline-block;
	font-size: 13px;
	line-height: 27px;
	height: 27px;
	padding: 0 10px 0 5px;
	background: -moz-linear-gradient(top, #5bbfd8, #449fb6);
	background: -webkit-linear-gradient(top, #5bbfd8, #449fb6);
	border: 1px solid #2c96b2;
	border-left: 0;
	border-radius: 2px 5px 5px 2px;
	text-shadow: 0 -1px 0 rgba(0, 0, 0, .4);

	margin-left: 12px;
	position: relative;
	z-index: 2;
}
/*左边的小三角*/
.btn-back:before {
	content: '';
	display: inline-block;
	width: 20px;
	height: 20px;
	background: -moz-linear-gradient(-45deg, #5bbfd8, #449fb6);/*背景旋转-45°*/
	background: -webkit-linear-gradient(-45deg, #5bbfd8, #449fb6);
	border: 1px solid #2c96b2;
	-webkit-transform-origin: 0 0;/*设置基点为0,0*/
	-moz-transform-origin: 0 0;
	-webkit-transform: scaleX(0.8) rotate(45deg);/*X轴压缩,旋转45°*/
	-moz-transform: scaleX(0.8) rotate(45deg);
	border-radius: 3px 2px;

	position: absolute;
	left: 13px;
	top: -1px;
}

5、最后给出一个成品

这个只能说实现一个不完美的返回按钮,因为有些阴影效果比较难搞定。但是我觉得是一个不错的替代方案,总比几K的图片靠谱(体积变小,没有额外的请求)

Demo地址: http://honglei.net/demo/ios_back_button.html

通过JS判断联网类型和连接状态

中国的移动网络环境复杂,为了给用户带去更好访问体验,开发者希望能了解用户当前的联网方式,然后给用户一个符合当前网络环境的请求结果。

W3C的规范中给出了一个方法来获得现在的网络状态navigator.connection;根据Working Draft 29 November 2012协议规范我们可以从接口中获得bandwidth(带宽,M/s)和metered两个参数的值;还提供了一个监听方法,来时刻监听接入环境的变化情况。现实中我们发现很多浏览器并没有返回bandwidth值,而且遵守了Working Draft 07 June 2011的协议返回给我们type(类型,wifi/2g/3g/4g)。

我们接下来就看看各家的支持情况

Android 2.3+ Browser UC Dolphin QQ浏览器 Baidu Firefox Chrome Opera Mini Maxthon
Yes No* Yes Yes* Yes Yes(New) No No Yes

说明下在iPhone中任何浏览器都无法得到相关信息。

通过上面的说明,我们发现还是可以通过这个参数了解很大一部分用户的联网情况的,并且为他们提供更加优质的体验。
接下来我们重点说说各浏览器的返回情况。

大部分浏览器会返回一个int型的类型,其中的特例是QQ浏览器,返回的就是类型名称,对应关系如下

返回值 QQ返回值 类型
0 unknown UNKNOWN
1 ethernet ETHERNET
2 wifi WIFI
3 2g CELL_2G
4 3g CELL_3G
5 4g CELL_4G(中国现在也会出现这个值,是hspa+)
? none NONE

接下去是一个更大的特例,这就是firefox,他使用了新版规范,所以返回的是bandwidth;不过很奇怪的是只要是wifi或3G他就返回20,如果是2G返回的就是0.1953125;每次都一样不管现在网络状态到底是多少。这个问题还会继续跟进。

给大家提供一个demo地址:http://honglei.net/demo/net.html

Demo中对不支持connection的浏览器直接返回了{type:0},这样就很便利解决了某些浏览器不支持的问题;对于不支持又能上网的浏览器处理为“unknown”当然也是合乎情理的。

很多工程师觉得这个功能支持还不好,还是先不使用的好;但是我觉得只要错误能被处理,风险能被把控,为什么不给那些先天优秀的客户提供更友好的体验呢。

今天同学说到让后端判断速度,这个可能有点难;不过确实可以通过每次的异步请求去得到用户大概的速度(加载的时间和文件大小其实前端都能得到),然后在选择性的提供某些服务,之后也准备向这个方向上多思考下。

多台DD-WRT配置WDS

还要公司需要做无线网络覆盖,但是不想使用网线,所以只能使用WDS亚洲通娱乐来实现。

因为考虑到网络的稳定性、成本等因素,我们最后确定选用官翻的CISCO的E1550。
E1550是CISCO下Linksys的设备,支持802.11n无线协议,最高300M无线传输速度,使用Broadcom BCM5358 300MHz处理器,64MB RAM,16M ROM,并且可以方便的刷DD-WRT、Tomato这样的第三方固件。

其实,最初我们考虑过很多方案;比如CISCO的RE1000,RE1000是专门的中继网桥设备,设置非常简单,最后因为我们使用同样的SSID,结果多台设备连接后出现了环路,引起数据风暴,网络瘫痪;后来也相过使用DD-WRT中的中继网桥,结果一样。无奈最后只能选择WDS来解决,因为WDS需要绑定MAC,所以可能对之后的维护会带来一定的问题,但是也正因为WDS需要绑定MAC,所以不会出现环路现象。

下面我们就说说DD-WRT设置WDS的方法和注意点。

一、设置主路由

其实主路由的设置说白了就是你想怎么设置怎么设置;比如WAN口设置,如果是PPPOE那就设置成PPPOE,需要打开DHCP就打开,IP怎么设置都可以。见下图:ap1_base
无线部分也是按照自己的需求设置SSID,密码(我们的解决方案中未涉及到密码问题),但是注意无线信道(Wireless Channel)需要固定下,不要使用自动,不然很有可能组网失败,就算成功那也会寻找的非常慢。见下图:ap1-wifi
接下去就是关键的WDS部分的设置了,首先将第一项的类型选择成“LAN”,后面填上需要连接的无线设备的MAC地址。见下图:(最上面那个是本设备的MAC地址)ap1-wds

二、设置次路由(除了主路由外)

首先关闭次路由的WAN口和DHCP功能,并且注意IP主要冲突。见下图:ap2_base
无线设置完全保持和主路由一样就可以,密码也要保持一致。见下图:ap2-wifi
最后设置WDS,将需要与他连接的MAC地址填入,并且将类型设置为LAN,这里设置两个MAC,一个是前一台的MAC地址,一个是后一台的MAC地址,我们是串联模式。见下图:ap2-wds

我们使用的是串联的连接方式,所以第一台设置的MAC是第二台,第二台设置的MAC是第一台和第三台的,第三台设置的MAC是第二台和第四台的,依次继续,直到最后一台设置的MAC为前一台的;当然你也可以是辐射状的,第一台设置第二级路由的MAC地址,第二级路由的MAC设置为第一台路由的MAC;但是一定要主要千万不要形成环路。

最后,还要感谢PlayPC提供的测试路由;大家也可以去他们家选购自己喜爱的产品,官翻版本,绝对超值哦;而且店主也是爱玩之人,超级友好。店铺地址:http://playpc.taobao.com/

Mysql 主从设置

最近刚好有人问到Mysql主从库怎么配置,想想干脆写篇文章,也方便以后使用。
Mysql设置主从后可以缓解数据库的读取压力,将读表操作分散到从库进行。

首先我们假设:
主库(Master): 10.10.1.10
从库(Slave): 10.10.1.11 从库可以多台,但是需要考虑主从之间的传输速度

 

主库配置

首先修改 my.cof

vim /etc/my.cof

保证配置文件中有以下语句
server-id = 1    //master端ID号
log-bin = /usr/local/mysql/data/mysql-bin    //日志路径及文件名

以下语句按照需要配置
binlog-do-db = data    //需要同步的数据库(通过多行添加多个,如果没有次行,就是同步不允许以外所有的库)
binlog-ignore-db = mysql    //不需要同步的数据库(通过多行添加多个)
binlog-ignore-db = information_schema
//以上配置都是通过use table实现的,如果你使用database.table可能会存在问题;
//比如你忽略mysql库,但是你在data库中运行 UPDATE mysql.table SET xxx 词句依然不会被忽略

添加从库同步帐号权限,以及查看主库状态

mysql -uroot -p
mysql> GRANT REPLICATION SLAVE ON *.* TO '<slave_username>'@'<slave_ip>' IDENTIFIED BY '<slave_password>';
mysql> FLUSH PRIVILEGES;
mysql> SHOW MASTER STATUS; //查看主库日志状态

 

从库设置

首先修改 my.cof

vim /etc/my.cof

保证配置文件中有以下语句
server-id = 2    //slave端ID号,保证比master端ID大

添加从库同步帐号权限,以及查看主库状态

mysql -uroot -p
mysql> CHANGE MASTER TO
MASTER_HOST='<master_host>',
MASTER_USER='<master_username>',
MASTER_PASSWORD='<master_password>',
MASTER_LOG_FILE='<log_file>', //同步的起始日志文件名称
MASTER_LOG_POS='<log_position>'; //同步的起始Position
mysql> START SLAVE; //开始同步
mysql> SHOW SLAVE STATUS \G //查看从库状态

 

注意

1、如果您的主库日志文件一直存在就直接将起始日志文件定位到第一个日志的第一个位置就可以。
2、如果您的主库日志不完整,按请先锁定主库,然后将主数据库导入从数据库中。
3、一旦开始主从同步切勿使用“RESET MASER”来清除主库日志。

 

附:将主库文件备份到从库

锁定主库

mysql -uroot -p
mysql> FLUSH TABLES WITH READ LOCK;
mysql> SHOW MASTER STATUS; //将信息记录下来,要在从库配置中使用到

备份数据库文件

rsync -var /usr/local/mysql/data/ 10.10.1.11:/usr/local/mysql/data/

解锁主库

mysql -uroot -p
mysql> UNLOCK TABLES;

然后配置从库

 

附:删除主库日志

Mysql命令删除

mysql -uroot -p
mysql> SHOW BINARY LOGS;
mysql> PURGE BINARY LOGS TO 'mysql-bin.000003'; //上面取出的文件名称

Rm命令删除

cd /usr/local/mysql/data/
rm -f mysql-bin.000001
rm -f mysql-bin.000002
//切勿删除最后一个日志文件

Linux下将内存虚拟成硬盘

因为硬盘的IO开销很大,所以就计划在系统中将部分内存虚拟成硬盘;记得多年前曾经在Windows下通过软件虚拟出来过,所以就Google Linux中虚拟的方法。
最后发现在Linux中干这个事情超级简单,连第三方软件都不用,一个命令搞定。
Linux中将内存虚拟成硬盘的方法有两种:

Ramdisk

Ramdisk是用一部分内存空间来模拟硬盘分区,大小不可改变。

mkfs -t ext2 /dev/ram0
mkdir /ram
mount /dev/ram0 /ram
df -hl

完成后发现只有16M,跪了,这个确实不太实用。

tmpfs

tmpfs是一种基于内存的文件系统,也可以使用swap分区来存储,tmpfs是一个文件系统,并不是块设备。

df -hl

查看tmpfs的大小,你会发现其实已经挂在到/dev/shm,其实就可以直接使用了。
也许你想要定一个自己期望的大小,那就使用下面的命令

mount -t tmpfs -o size=2G tmpfs /ram
df -hl

现在就是一个完全自己定义大小的tmpfs格式的空间了。

既然是内存型存储就意味着掉点之后数据肯定全部丢失,所以要合理使用内存虚拟出来的硬盘系统。

Centos下添加PHP对MSSQL的支持

其实很少会有连接SQL Server的机会,不过我们公司刚好有个应用需要使用的SQL Server的数据库,所以也知道给LNMP安装MSSQL的扩展。
搜索网上的相关文章一般的解决方案是Freetds,Freetds的主要功能就是让Linux系统可以访问SQL Server服务。

安装Freetds

Freetds 官方网站是 http://www.freetds.org,可以去官方网站下载程序,文中下载的是0.92.79版本。

wget ftp://ftp.freetds.org/pub/freetds/stable/freetds-0.92.79.tar.gz

然后解压,并且编译安装

tar -zxvf freetds-0.92.79.tar.gz
cd freetds-0.92.79
./configure --prefix=/usr/local/freetds
gmake
gmake install

安装完成后可以使用命令测试下

/usr/local/freetds/bin/tsql -S 192.168.0.10:1433 -U sa

安装PHP的MSSQL扩展

本服务器使用的是lnmp集成环境,php是5.3.21;如果是单独安装php的也一样;先进入下载加压后的PHP文件目录,然后编译安装

cd /data/lnmp0.9-full/php-5.3.21
cd ext/mssql
/usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config --with-mssql=/usr/local/freetds
make
make install

随后在php.ini中添加扩展

vim /usr/local/php/etc/php.ini

在最后加入一行

extension = "mssql.so"

最后重启php即可

配置Freetds

vim /usr/local/freetds/etc/freetds.conf

在文件中加入以下语句

[sqlservername]
host = 192.168.0.10
port = 1433
tds version = 7.0
client charset = UTF-8

PHP中测试连接

新建一个php文件,放入以下代码

$conn = mssql_connect("sqlservername", "sa", "password") or die ("无法连接");
echo $conn;

现在你的php已经完全支持连接SQL Server了。

跨域iframe自适应高度

这个可能是一个老生常谈的问题了,搜索google和百度应该也是文章大把大把的;处理方式也大同小异,今天又有哥们问这个问题,所以还是将自己的处理方式写出来。

最早遇到这个问题是07年在Yahoo的时候,当时SNS盛行,Yahoo也决定做SNS,其中就有应用是iframe模式的,但是iframe的页面在对方服务器上,使用的也是别人的域名,Yahoo也不可能给对方提供二级或三级域名;那就遇到一个问题,怎样去调整iframe的高度,让他做到自适应;大家都知道JS为了安全,是不能跨域执行的,所以只能通过其他方式实现;感谢克军同学当时给的建议。

下面具体说说怎么实现吧。

首先因为iframe是跨域的,所以不能直接用JS来控制,只能通过一个中间键,我们这里选择在iframe的页面(页面B)中再iframe一个父页面(页面A)同域的页面(页面C);这样页面C就能和页面A进行无障碍的通讯了;因为页面B iframe 页面C,所以页面B可以改写页面C的href值;到这里大家应该看明白啥意思了,来张图说明下:
iframe

A页面中的内容

A页面主要就是接收C页面传过来的内容并且去完成相应的操作。可能有人会说直接C页面来操作不就可以了?但是那样处理不太好,因为可能A页面中还有很多其他的公共方法,比如美化过的Alert等,所以如果能做一个公共的方法来接收C页面传过来的值会更加方便之后的框架调整,而且也不建议总是去修改页面C。

<iframe id="ifr" src="iframe_b.html" height="200" width="400"></iframe>
<script type="text/javascript">
var ifr_el = document.getElementById("ifr");
function getIfrData(data){
    ifr_el.style.height = data+"px";
}
</script>

B页面中的内容

B页面的主要内容当然是怎么把值传递给C页面,前面说了是将值传递到C页面的href中,所以只要修改iframe的src就可以,因为不用刷新C页面,所以可以用过hash的方式传递给C页面

<div id="box">
	<button id="btn_auto" type="button">Height Auto: off</button>
	<button id="btn_plus10" type="button">Height +10px</button>
	<button id="btn_minus10" type="button">Height -10px</button>
</div>
<iframe id="ifr" src="iframe_c.html" width="0" height="0"></iframe>
<script type="text/javascript">
var box_el = document.getElementById("box"),
    btn_auto_el = document.getElementById("btn_auto"),
    btn_plus10_el = document.getElementById("btn_plus10"),
    btn_minus10_el = document.getElementById("btn_minus10"),
    ifr_el = document.getElementById("ifr");

var isAuto = false,
    oldHeight = 0,
    ifrSrc = ifr_el.src.split("#")[0];

btn_auto_el.onclick = function(){
	if(!isAuto){
		isAuto = true;
		btn_auto_el.innerHTML = "Height Auto: on";
	}else{
		isAuto = false;
		btn_auto_el.innerHTML = "Height Auto: off";
	}
}
btn_plus10_el.onclick = function(){
	var height = box_el.offsetHeight;
	box_el.style.height = (10+height)+"px";
}
btn_minus10_el.onclick = function(){
	var height = box_el.offsetHeight;
	box_el.style.height = (height-10)+"px";
}
setInterval(function(){
	if(isAuto){
		var height = document.body.scrollHeight;
		height += 20;
		if(oldHeight != height){
			oldHeight = height;
			ifr_el.src = ifrSrc+"#"+oldHeight;
		}
	}
}, 200);
</script>

C页面中的内容

C页面的唯一功能就是接收B页面通过href传进来的值并且传递给A页面,可到B页面传来的值可以通过一个定时器不停去查看location.href是否被改变,但是这样感觉效率很低,还有个方式就是在新的浏览器中通过onhashchange事件(IE8+,Chrome5.0+,Firefox3.6+,Safari5.0+,Opera10.6+)来监听href的改变。

<script type="text/javascript">
var oldHeight = 0;

setInterval(function(){
	var height = location.href.split("#")[1];
	if(height && oldHeight != height){
		oldHeight = height;
		if(window.parent.parent.getIfrData){
			window.parent.parent.getIfrData(oldHeight);
		}
	}
}, 200);
</script>

高度应用只是iframe跨域传值中最简单也是最常见应用,其实能扩展出很多其他的需求,之前在Yahoo的项目中就将iframe中的弹出框操作也传递到了外面,以保证样式的统一和页面的全遮盖。

最后举个“栗子”,演示请看http://www.honglei.net/demo/iframe_a.html

Centos 虚拟机网络的处理

公司大规模使用KVM,很多时候就是把Centos的虚拟机克隆后直接使用。直接克隆带来的问题就是网卡设置会发生变化,需要调整。一般会有一下几个问题。

网卡变成了eth-2和eth-3

其实这个并不影响使用,但是有些时候就是看着不爽;这个是可以调整的,方法如下

vim /etc/udev/rules.d/70-persistent-net.rules

里面可以看到所有网卡的mac和相关信息,直接删除上面的两块网卡配置,并且将下面的网卡设置中的name更换成eth-0和eth-1就可以;重启,再使用ifconfig查看,发现已经是eth-0和eth-1了

每次需要重新设置IP地址中的MAC

有时克隆后的虚拟机并不需要更改IP,就算需要更改IP也会有个讨厌的事情,就是同时需要修改设备的MAC地址,那个东西还超级难记住;
其实不用这么纠结,直接把设置文件中的MAC地址那项删除即可

vim /etc/sysconfig/network-scripts/ifcfg-eth0
删除 HWADDR="00:1E:0B:XX:XX:XX" 这行

这样以后更换虚拟机网卡就再也不用修改MAC地址

DNS设置

说起来这个不算虚拟机中的东西,不过也说说,很多时候可以ping通IP,但是无法ping通域名,那就要设置DNS了

vim /etc/resolv.conf
添加一下格式的内容
nameserver 8.8.8.8

局域网内可能很多请求是内部的,但是使用IP有些时候遇到服务器调整就需要都去修改,其实可以使用内部的DNS服务器来做服务器请求的统一管理。

服务器名称修改

虚拟机克隆以后换作其他用途,但是机器名还是原来的,好郁闷吧,这个也可以修改

vim /etc/sysconfig/network
修改 HOSTNAME= 后面的值即可
也可以用 hostname newname 即时修改机器名称(重启后无效)

然后重启就OK

一转眼到这家公司已经快4年了,刚开始充满激情,希望自己的梦想能够实现,但是梦想始终没有实现,不过梦想仍然存在。

也许公司不是这么的好,但是回问自己:“想要一个怎样的公司呢?”;最后发现公司的好与坏其实在于员工,如果每个人都像我这样动摇,不坚持,甚至怀疑,那公司又怎样变好。

年中这样的怀疑应该到大的极限,想换工作,甚至已经差不多在新公司正式上班,但是最后我发现,那个也不是我想要的;也感谢庄哥让我真正知道了我要的是什么;这一年就没有啥好的状态,也许就是不信,不信公司,不信“老大”。

其实这一年的很多事情让我成长了,朋友的项目,庄哥的发展路,还有公司员工的去留;其实现在看来信不信不在于别人,在于自己,信什么的根本是信自己。

工作中是信自己能让公司更好,而不是信公司回让我更好。既然这样那就别管老大,就像庄哥说的“把老大给解放了”;勇于去承担,用心做。