免费使用Github micro plan 两年

Github去年面向学生和教师推出免费两年的 Github micro plan计划,也就是说两年内,你可以免费使用5个私有仓库来托管你的代码。

在线申请地址是: https://education.github.com/

这项计划是针对学生群体,而Github对学生群体的识别只针对edu后缀的邮箱,也就是说,如果你有edu后缀的邮箱,那你就可以免费使用micro plan计划了。

那么接下来的问题就是:去哪里搞个edu邮箱呢?

好吧,这个问题只能求助万能的淘宝,在淘宝搜索“edu邮箱”果然出现很多结果,找个便宜的,几块钱一个的,付款之后,拿这个邮箱再去Github申请免费2年的micro plan计划吧。

本人已成功申请到了,看图。(PS:别举报我等这些穷屌丝啊`~~)

QQ截图20140425223616

最后,当然如果你想用私人仓库,但又不想搞那么麻烦,弄个edu邮箱什么的。那么,可推荐你使用 https://bitbucket.org

bitbucket和Github最主要的区别就是bitbucket可以免费使用无数个私人仓库。而且现在bitbucket已经支持中文界面了。

建议申请bitbucket的时候,使用和Github一样的邮箱,这样可以共同使用一个SSH Key,免得麻烦再去生成一个。

利用chrome的workspace快速调试CSS

使用Workspace条件:

  • Chrome V31+(正式版)
  • 本地服务器开发
image001

1、点击F12工具的设置按钮 

image002
image003

2、点击左侧的workspace 

3、点击Add folder 

image004
image005
image006

4、选择服务器所在的根目录,之后确定会chrome会在上面做出一个提示,点击允许 

5、双击下图所示的地方,配置映射关系, 

6、点击Edit按钮写映射关系,视具体情况填写,注意右边的/一定要填写(关键性步骤) 

image007
image008

7、然后回到一个页面中去,试着去更改一个样式数值,验证是否生效 

8、最后看看是否成功 

注意Workspace只对外部引入的CSS样式有效!

bootstrap中 $.fn.Aa.Constructor = Aa

在bootstrap js源码中,在插件最后经常看到

$.fn.Aa.Constructor = Aa

这样一句。

这里注意,Constructor 是大写的C,而不是我们常写的那个constructor。

这句的作用,是将插件类暴露给外界,这样可以修改和添加类里面的方法了。

如下面语句,初始化tooltip后,给Tooltip新增test方法。

$.fn.tooltip.Constructor.prototype.test = function(){
        console.log('test')
    }
    $('#example').tooltip('test')

在调用插件后,在控制台会输出test字符串。

再举一个栗子:

var tmp = $.fn.tooltip.Constructor.prototype.show;
$.fn.tooltip.Constructor.prototype.show = function () {
  tmp.call(this);
  if (this.options.callback) {
    this.options.callback();
  }
}

$('#selector').tooltip({ 
  placement: 'top', 
  callback: function() { 
    alert('hello') 
  } 
});

给show方法新增一个callback回调。

CentOS VPS硬盘挂载操作

有些VPS 默认没有帮你挂载硬盘,这时你的VPS默认空间是很小的。挂载硬盘 实际就相当于你接了个移动硬盘来扩容。 
而硬盘挂载操作也比较简单,主要就是以下几句代码:

mkdir  /mnt/sdb
mkfs.ext3    /dev/xvdb1
mount /dev/xvdb1 /mnt/sdb

那么接下来,详细记录一下硬盘挂载的步骤。

1. 添加磁盘,查看磁盘状况

fdisk -l

2. 用fdisk 对/dev/xvdb进行分区

fdisk /dev/xvdb

说明:通过第一步查看了硬盘名称后,再对相应的硬盘座分区。 
然后看着说明依次输入n、p、1、w 四个步骤。(详细请看文章后面的步骤过程)

3. 格式化 /dev/xvdb1 分区

mkfs -t ext3 /dev/xvdb1

4. 创建目录 并将 /dev/sdb1 挂在到该目录下


mkdir /mnt/sdb
mount /dev/xvdb1 /mnt/sdb

5. 验证挂载是否成功

df -k

6. 设置开机自动挂载

vi /etc/fstab

这里用Vi命令进行文件编辑 
/dev/xvdb1 41279536 180240 39002416 1% /mnt/sdb

以下是我的完整操作流程记录:

[root@MyCloudServer ~]# fdisk -l

Disk /dev/xvdb: 42.9 GB, 42949672960 bytes
255 heads, 63 sectors/track, 5221 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

Disk /dev/xvdb doesn't contain a valid partition table

Disk /dev/xvda: 10.7 GB, 10737418240 bytes
255 heads, 63 sectors/track, 1305 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

	Device Boot	  Start		 End	  Blocks   Id  System
/dev/xvda1   *		   1		  13	  104391   83  Linux
/dev/xvda2			  14		1044	 8281507+  8e  Linux LVM
/dev/xvda3			1045		1305	 2096482+  8e  Linux LVM

[root@MyCloudServer ~]

# fdisk /dev/xvdb Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel Building a new DOS disklabel. Changes will remain in memory only, until you decide to write them. After that, of course, the previous content won’t be recoverable. The number of cylinders for this disk issetto 5221. There is nothing wrong with that, but this is larger than 1024, and could in certain setups cause problems with: 1) software that runs at boot time (e.g., old versions of LILO) 2) booting and partitioning software from other OSs (e.g., DOS FDISK, OS/2 FDISK) Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite) Command (m for help): p Disk /dev/xvdb: 42.9 GB, 42949672960 bytes 255 heads, 63 sectors/track, 5221 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Device Boot Start End Blocks Id System Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 1 First cylinder (1-5221, default 1): Usingdefault value 1 Last cylinder or +size or +sizeM or +sizeK (1-5221, default 5221): Usingdefault value 5221 Command (m for help): w The partition table has been altered! Calling ioctl() to re-read partition table. Syncing disks.

[root@MyCloudServer ~]

# fdisk -l Disk /dev/xvdb: 42.9 GB, 42949672960 bytes 255 heads, 63 sectors/track, 5221 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Device Boot Start End Blocks Id System /dev/xvdb1 1 5221 41937651 83 Linux Disk /dev/xvda: 10.7 GB, 10737418240 bytes 255 heads, 63 sectors/track, 1305 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Device Boot Start End Blocks Id System /dev/xvda1 * 1 13 104391 83 Linux /dev/xvda2 14 1044 8281507+ 8e Linux LVM /dev/xvda3 1045 1305 2096482+ 8e Linux LVM

[root@MyCloudServer ~]

# mkfs -t ext3 /dev/xvdb1 mke2fs 1.39 (29-May-2006) Filesystem label= OS type: Linux Block size=4096 (log=2) Fragment size=4096 (log=2) 5242880 inodes, 10484412 blocks 524220 blocks (5.00%) reserved for the super user First data block=0 Maximum filesystem blocks=0 320 block groups 32768 blocks per group, 32768 fragments per group 16384 inodes per group Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 4096000, 7962624 Writing inode tables: done Creating journal (32768 blocks): done Writing superblocks and filesystem accounting information: done This filesystem will be automatically checked every 36 mounts or 180 days, whichever comes first. Use tune2fs -c or -i to override.

[root@MyCloudServer ~]

# ls

[root@MyCloudServer ~]

# cd /

[root@MyCloudServer /]

# ls bin dev home lost+found misc net proc sbin srv tmp var boot etc lib media mnt opt root selinux sys usr

[root@MyCloudServer /]

# mount /dev/xvdb1 /mnt/sdb mount: mount point /mnt/sdb does not exist

[root@MyCloudServer /]

# cd mnt/sdb -bash: cd: mnt/sdb: 没有那个文件或目录

[root@MyCloudServer /]

# cd mnt/

[root@MyCloudServer mnt]

# ls xs-tools

[root@MyCloudServer mnt]

# mkdir sdb

[root@MyCloudServer mnt]

# mount /dev/xvdb1 /mnt/sdb

[root@MyCloudServer mnt]

# df -k 文件系统 1K-块 已用 可用 已用% 挂载点 /dev/mapper/VolGroup00-LogVol00 9743696 1425864 7814872 16% / /dev/xvda1 101086 44628 51239 47% /boot tmpfs 524380 0 524380 0% /dev/shm /dev/xvdb1 41279536 180240 39002416 1% /mnt/sdb

[root@MyCloudServer mnt]

# vi /etc/fstab

Chrome渲染分析之Timeline工具的使用

页面的绘制时间(paint time)是每一个前端开发都需要关注的的重要指标,它决定了你的页面流畅程度。而如何去观察页面的绘制时间,找到性能瓶颈,可以借助Chrome的开发者工具。

本文主要介绍Chrome渲染分析工具 Rendering。

/

如上图,按F12调出开发者工具,然后按“ESC”调出Rendering界面。

以上5个选项的意思如下:

  • 1、Show paint rectangles 显示绘制矩形
  • 2、Show composited layer borders 显示层的组合边界(注:蓝色的栅格表示的是分块)
  • 3、Show FPS meter 显示FPS帧频
  • 4、Enable continuous page repainting 开启持续绘制模式 并 检测页面绘制时间
  • 5、Show potential scroll bottlenecks 显示潜在的滚动瓶颈。

1、Show paint rectangles

开启 显示绘制矩形 这个选项,可以看到绿色的框(之前的版本都是红色的框,现在改绿色了,呵呵),这个绿色的框,表示页面正在绘制的区域,即是页面正在渲染,发生绘制操作的区域。 这是用来了解滚动时页面表现的第一个指示器。

鼠标移到图片上,可以发现css3动画的位移,而css3动画的位移导致页面重绘,重绘的区域即是绿色框住的部分。细心的朋友可能会发现,这个绿色框住的部分,并不仅仅就是刚好那个div所在的区域,而涉及到周边的位置。发生这种情况的原因,是页面的重绘是个连带反应,会影响周边元素。

/

开启这个选项之后,可以做一些常规的页面交互操作,如Slider切换,拍拍网左侧导航mouse over时效果,可以看到页面效果所影响的范围。

再比如滚动页面,拍拍首页会出现一个返回顶部的按钮,滚动的时候,会发现返回顶部这个区域在不停的进行重绘,而返回顶部是position:fixed定位的。这也解释了为什么fixed定位是最耗性能的属性之一

/

如果这个时候,我们给头部的再加个position:fixed,然后滚动页面时,会发现整个页面都几乎是绿色框住了,这主要是所有具有fixed定位的元素,在页面绘制时会处于同一个渲染层级上,一头一尾的fixed无疑会导致整个页面进行重绘,性能非常差。

/

这里提到一个渲染层级的概念,webkit内核的浏览器在进行页面绘制、渲染并最终展示在浏览器窗口上,实际上就像是Photoshop上的图层,不同的图层进行叠加最后生成一个图片的过程。

这个层的详细介绍,我下一篇文章会详细介绍,这里先卖个关子。

回到之前的话题,既然绿色框住的部分表示页面重绘,那哪些操作会导致重绘呢?

影响页面重绘的因素

主要有2大类:

  • 1、页面滚动
  • 2、互动操作
  • 1).Dom节点被Javascript改变,导致Chrome重新计算页面的layout。
  • 2).动画不定期更新。
  • 3).用户交互,如hover导致页面某些元素页面样式的变化。
  • 4).调整窗口大小 和 改变字体
  • 5).内容变化,比如用户在input框中输入文字
  • 6).激活 CSS 伪类,比如 :hover
  • 7).计算 offsetWidth 和 offsetHeight 属性
  • 8).增加或者移除样式表

影响重绘的因素很多,这里列举了部分在前端开发的过程中常见的操作:

1、应该尽量避免重绘,并且尽可能的使绘制区域最小,以提升页面性能。

就上面拍拍网的例子,一头一尾加上fixed定位导致整个页面重绘,是不可取的。也许你分析完后以后都不敢用fixed,但是可能在实际工作中这种情况无法避免(设计师或产品经理要求)。何东西都有它适用的地方,重要的是作为前端人员,你应该能够测量并知道你写的代码所带来的性能损耗及所造成的影响。

2、同时避免组合触发,如滚动的时候同时执行hover效果操作,一个例子(Expensive Scrolls),
在滚动的时候同时也有可能触发页面模块的hover效果,而hover效果用了box-shadow 、border-radius等耗性能大的样式。从而可能导致丢帧现象。

如何去优化:技巧在于滚动时,关闭模块的hover效果,然后设定一个计时器,时间到了再把hover打开。意思是我们保证在滚动时不去执行昂贵的互动事件重绘。当你停止动作一段时间后,我们再将动画开启。

2.show composited layer borders

/

中文可翻译为:显示层的组合边界。

我们知道,在页面最终是由多个“图层”渲染而成。勾上这个选项,页面上的“layer(层)”会加上一个黄色的边框显示出来,如下图的天猫首页头部所示:

/

其中:

  • 黄色边框:用于显示页面上的layer
  • 蓝色栅格线:表示的是分块,这些分块可以看作是比层更低一级的单位
    当然,还有其他颜色的边框线,比如图片如果单独有个layer的话,边框线是蓝色的。

使用这个工具,可以查看当前页面的layer情况,更好的发现页面不需要的layer将之清除。

layer存在的意义

在弄明白这个问题之前,我们需要先了解一个dom元素最终是如何转变为我们屏幕上可视的图像。在概念上讲,可简单的分为四个步骤:

  • 获取 DOM 并将其分割为多个层
  • 将每个层独立的绘制进位图中
  • 将层作为纹理上传至 GPU
  • 复合多个层来生成最终的屏幕图像。

可以将这个过程理解为设计师的Photoshop文件。在ps源文件里,一个图像是由若干个图层相互叠加而展示出来的。分成多个图层的好处就是每个图层相对独立,修改方便,对单个图层的修改不会影响到页面上的其他图层。

基于photoshop的图层理念来理解web端的层,那么就很容易理解了。layer存在的意义在于:用最小的代价来改变某个页面元素。

我们可以将某个css动画或某个js交互效果把它抽离到一个单独的渲染层,这样可以加快渲染的效率。

如何创建layer

  • 3D 或透视变换(perspective transform) CSS 属性
  • 使用加速视频解码的 <video> 元素
  • 拥有 3D (WebGL) 上下文或加速的 2D 上下文的 <canvas> 元素
  • 混合插件(如 Flash)
  • 对自己的 opacity 做 CSS 动画或使用一个动画 webkit 变换的元素
  • 拥有加速 CSS 过滤器的元素
  • 元素有一个包含复合层的后代节点(换句话说,就是一个元素拥有一个子元素,该子元素在自己的层里)
  • 元素有一个 z-index 较低且包含一个复合层的兄弟元素(换句话说就是该元素在复合层上面渲染)
  • 在webkit内核的浏览器中,如果有上述情况,则会创建一个独立的layer。

在webkit内核的浏览器中,如果有上述情况,则会创建一个独立的layer。

其中第一点是最常用的手段,比如我们有时候给一个css效果加上transform: translateZ(0);,目的就是为了创建一个独立的layer。

另外还有另外一个css属性:will-change也能实现同样的效果。

layer 过多带来的问题

还是拿photoshop来做比喻,一个ps文件如果有非常多的图层,那么这个文件肯定是非常大的。那对于web端也是一样,创建一个新的渲染层,它得消耗额外的内存和管理资源。当在内存资源有限的设备,比如手机上,由于过多的渲染层来带的开销而对页面渲染性能产生的影响,甚至远远超过了它在性能改善上带来的好处。

举个栗子,我们在天猫首页上加入css:* {-webkit-transform: translateZ(0);}。 然后使用timeline可以看到,天猫的渲染耗时非常严重。

/

其影响的是页面渲染的最后一个环节:Composite Layers

那么,一个合理的策略是:当且仅当需要的时候才为元素创建渲染层。

更直观的查看页面layer

除了rendering 里提供的show composited layer borders选项外,还有一个更为直观的3d图像展示:

先选中timeline的某一帧,然后选择下面的layer标签tab,在右侧的区域就可以看到整个页面的3d图层了。

/

在这个视图中,你可以对这一帧中的所有渲染层进行扫描、缩放等操作,同时还能看到每个渲染层被创建的原因。

3.show FPS meter

show fps meter可以理解为显示FPS帧频/帧数。开启这个选项后,右上角会实时显示当前页面的FPS。

先简单科普一下啥是FPS。FPS全称叫 Frames Per Second (每秒帧数)。帧数越高,动画显示的越流畅。一般的液晶显示器的刷新频率也就是 60HZ。也就是说,要想页面上的交互效果及动画流畅。那么FPS稳定在60左右,是最佳的体验。。据悉 ios上的交互效果都是60FPS呢。

记得以前做Flash游戏的时候,FPS帧数是游戏流畅度的一个重要指标。在web端,道理也是一样。

科普完毕,回到正题。chrome提供的show FPS meter选项,在我们制作测试页面交互及动画性能时非常有用。同时它也提供了当前页面的GPU占有率给我们。

/

参考:

http://www.html5rocks.com/en/tutorials/speed/unnecessary-paints/

https://developers.google.com/web/fundamentals/performance/rendering/stick-to-compositor-only-properties-and-manage-layer-count

http://www.html5rocks.com/en/tutorials/speed/layers/

https://developer.chrome.com/devtools/docs/rendering-settings

javascript中constructor的作用

这里其实并不是要讲 constructor 的作用。 
而是为了要分析这句代码的含义:

f.prototype.constructor = f

经常会在别人写的类里面看到这句代码(其中f为function名称)。

为了搞清楚这句代码的含义,首先要大概先了解constructor的作用。 
在上一篇文章 《javascript中关于new的理解》 ,中,我们知道了如何创建一个构造函数。 
文章重点主要是侧重new的用法,而省去了很多其他相关联的知识点。

那么在创建构造函数的时候,会同时创建这个构造函数的 prototype 属性,(更准确的说应该是每个函数都有一个默认的prototype 属性),而prototype里的constructer 则指向构造函数。 
也就是说 constructor始终指向创建当前对象的构造函数 。记住这个点。 
如下面代码:

function Person(name) {
	 this.name = name;
 };

Person.prototype.getName = function() {
	return this.name;
};

//实例化对象
var p = new Person("ZhangSan");
//查看结果:Person的constructor始终是指向Person的
console.log(p.constructor === Person);  // true
console.log(Person.prototype.constructor === Person); // true

那么也就是说

f.prototype.constructor = f

这句代码是多余的,因为默认情况下就是这样。

但是 ,当时当我们重新定义函数的prototype时(注意:和上例的区别,这里不是修改而是 覆盖 ), constructor就指向Object里。

看下面的代码:

function Person(name) {
	this.name = name;
};
Person.prototype = {
	getName: function() {
		return this.name;
	}
};
var p = new Person("ZhangSan");
console.log(p.constructor === Person);  // false
console.log(Person.prototype.constructor === Person); // false
console.log(p.constructor.prototype.constructor === Person); // false

注意这里是直接修改了prototype,而不是在prototype上加方法。

为什么会发生这种情况?因为 constructor始终指向创建自身的构造函数 ,那上面那段代码实际等价为:

Person.prototype = new Object({
    getName: function() {
        return this.name;
    }
});

这样的话,就易于理解了。为什么prototype={}之后,constructor指向就发生了变化。

为了使构造函数的实例的创建者保持正确的引用,就要用这句代码来修正引用

f.prototype.constructor == f

再引用网上的一张图,也许理解起来更直观:

图片来源: http://www.nowamagic.net/librarys/veda/detail/1642

最后总结下:

f.prototype.constructor = f,这句代码只有这样写 f.prototype ={} 的情况下才使用。 
也许你会问,我不加这句好像也没什么影响啊。。 
确实,这种“高级代码”对于我等普通的P民几乎没作用,因为我们写不出那些高上大的代码。一般写框架、写类库的时候也许会用到。

但是为了保持良好的编码习惯,还是加一下比较好,呵呵。

CentOS VPS手工安装apache、php流程记录

apache安装步骤

1、操作系统更新,先将系统内核更新到最新版,这步可以省略。

yum -y update

2、CentOS默认有了apache的,直接运行安装:

yum -y install httpd

3、安装apache扩展

yum -y install httpd-manual mod_ssl mod_perl mod_auth_mysql

4、默认安装的话,中文是有乱码问题的,需要修改配置文件

#用VI命令修改
vi /etc/httpd/conf/httpd.conf

找到 AddDefaultCharset UTF-8 并改为 AddDefaultCharset Off 
PS:vi的查找可以输入:/AddDefaultCharset 然后按回车。

修改完后,紧接着下一行添加以下代码:

AddCharset us-ascii.ascii .us-ascii

AddCharset ISO-8859-1  .iso8859-1  .latin1

AddCharset ISO-8859-2  .iso8859-2  .latin2 .cen

AddCharset ISO-8859-3  .iso8859-3  .latin3

AddCharset ISO-8859-4  .iso8859-4  .latin4

AddCharset ISO-8859-5  .iso8859-5  .cyr .iso-ru

AddCharset ISO-8859-6  .iso8859-6  .arb .arabic

AddCharset ISO-8859-7  .iso8859-7  .grk .greek

AddCharset ISO-8859-8  .iso8859-8  .heb .hebrew

AddCharset ISO-8859-9  .iso8859-9  .latin5 .trk

AddCharset ISO-8859-10  .iso8859-10  .latin6

AddCharset ISO-8859-13  .iso8859-13

AddCharset ISO-8859-14  .iso8859-14  .latin8

AddCharset ISO-8859-15  .iso8859-15  .latin9

AddCharset ISO-8859-16  .iso8859-16  .latin10

AddCharset ISO-2022-JP .iso2022-jp .jis

AddCharset ISO-2022-KR .iso2022-kr .kis

AddCharset ISO-2022-CN .iso2022-cn .cis

AddCharset Big5.Big5   .big5 .b5

AddCharset cn-Big5 .cn-big5

# For russian, more than one charset is used (depends on client, mostly):

AddCharset WINDOWS-1251 .cp-1251   .win-1251

AddCharset CP866   .cp866

AddCharset KOI8  .koi8

AddCharset KOI8-E  .koi8-e

AddCharset KOI8-r  .koi8-r .koi8-ru

AddCharset KOI8-U  .koi8-u

AddCharset KOI8-ru .koi8-uk .ua

AddCharset ISO-10646-UCS-2 .ucs2

AddCharset ISO-10646-UCS-4 .ucs4

AddCharset UTF-7   .utf7

AddCharset UTF-8   .utf8

AddCharset UTF-16  .utf16

AddCharset UTF-16BE .utf16be

AddCharset UTF-16LE .utf16le

AddCharset UTF-32  .utf32

AddCharset UTF-32BE .utf32be

AddCharset UTF-32LE .utf32le

AddCharset euc-cn  .euc-cn

AddCharset euc-gb  .euc-gb

AddCharset euc-jp  .euc-jp

AddCharset euc-kr  .euc-kr

#Not sure how euc-tw got in - IANA doesn't list it???

AddCharset EUC-TW  .euc-tw

AddCharset gb2312  .gb2312 .gb

AddCharset iso-10646-ucs-2 .ucs-2 .iso-10646-ucs-2

AddCharset iso-10646-ucs-4 .ucs-4 .iso-10646-ucs-4

AddCharset shift_jis   .shift_jis .sjis

5、修改hosts配置文件,需要在127.0.0.1这个ip上加入对应的主机名,

#查看vps主机名
hostname
#然后将本机的真实hostname输入到hosts文件
#vi /etc/hosts
#然后在这里加入127.0.0.1   localhost.localdomain   localhost   <strong>XX(主机名)</strong>
#如我的hostname是MyVPS
#则是127.0.0.1   localhost.localdomain   localhost   MyVPS

6、配置虚拟站点 
CentOS 默认没有这个文件,要手动添加

vi /etc/httpd/conf.d/vhost.conf

然后输入你的域名等信息,如果有多个的话,也是加在这个文件

NameVirtualHost *:80

<VirtualHost *:80>

	ServerAdmin webmaster@www.ghugo.com

	DocumentRoot /var/www/html/ghugo.com

	ServerName www.ghugo.com

	<Directory "/var/www/html/ghugo.com">

		 #  AllowOverride AuthConfig

		 #  Options Indexes

		 AllowOverride all

		 Order Deny,Allow

		 Deny from all

		 Allow from all

	</Directory>

	DirectoryIndex index.php

	ErrorLog logs/test.testweb.com-error_log

	CustomLog logs/test.testweb.com-access_log common

</VirtualHost>

然后保存并退出

:wq

apache已经安装完毕,接下来安装php。

php安装步骤 
1、输入安装命令:

yum -y install httpd php

2、安装php扩展

yum -y install php-gd php-xml php-mbstring php-ldap php-pear

3、启动apache 完成所有安装

/etc/init.d/httpd start

至此,所有安装已经完毕,不出意外的话,应该可以正常运行了。

可能遇到的问题: 
关于httpd 启动的问题no listening sockets available, shutting down

参考资料: 
http://blog.csdn.net/zqlee1216/article/details/6578841

javascript中关于new的理解

Javascript中,实例化一个对象,会用到new关键字。

经常有人会问我,对于一个函数,什么时候该使用new关键字。

在回答这个问题之前,需要先了解清楚new的本质,在调用new Function的时候,new做了什么操作。

先看如下代码:

// 定义类 类名字是 classA
function classA(){
	this.name=1;
}
classA.prototype.show = function(){
	alert(this.name);
};
// 用new实例化
var b = new classA();
b.show();

var b = new classA();

这句中,new做了以下几件事情。 
1、创建一个新的对象,这个对象的类型是object; 
2、查找class的prototype上的所有方法、属性,复制一份给创建的Object 
3、将构造函数classA内部的this指向创建的Object 
4、创建的Object的__proto__指向class的prototype 
5、执行构造函数class 
6、返回新创建的对象给变量b

这个流程应该比较好理解的。这里再解释一下: 
1、构造函数:我们一般把new 后面的函数称为构造函数,如new classA(),其中classA就为构造函数 
2、第四点的__proto__,可能比较难理解。 
每个对象都会在其内部初始化一个属性,就是__proto__,可以在chrome中的调试器里写个对象查看下。 当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会去__proto__里找这个属性 ,这个__proto__又会有自己的__proto__,于是就这样一直找下去,也就是我们平时所说的原型链的概念。

当我们调用b.show()时,首先b中没有show这个属性,于是,它就需要到它的__proto__中去找,也就是ClassA.prototype, 
而我们在上面定义了ClassA.prototype.show=function(){}; 于是,就找到了这个方法。

再用下面的代码来理解

var b = {}
b.__proto__ =  ClassA.prototype
ClassA.call(b)

最后再用一句话总结:new关键字以ClassA()为模板创建了一个新的对象,它复制了ClassA构造器中的所有成员变量,同时this指向新创建的对象。

有2点需要注意: 
1、如果构造函数内没有返回值,则默认是返回this(当前上下文),要不然就返回 任意非原始类型值 。 
2、如果不用new关键字,如

var b = classA();

则classA值会返回undefined,并且this(执行上下文)是window对象。 
也就是说如果你不new的话,this指的就是window全局对象了。 
如下面代码:

// 定义类 类名字是 classA
function classA(){
	this.name=1;
}
//执行classA
classA();
//看下name是undefined还是1
name //返回1

看到这里,相信绝大多数人应该都理解了new的用法了。

mongodb 入门:安装

mongodb 之前听说过很久,一直没去试试。这几天正好有空,就随手搭了一个。

MongoDB的官网是: http://www.mongodb.org/

介绍啥的客套话也不多说了,网上一搜一大把。

先说下如何安装:

1、MongoDB最新版本下载在官网的DownLoad菜单下:http://www.mongodb.org/downloads ,找到对应的电脑版本下载。

2、解压mongodb-win32-i386-1.8.1.zip (下载后的压缩包,可能名称会不一样),创建路径C:\Program Files\mongodb ,将解压后的Bin文件Copy to 此文件夹下

3、C:\Program Files\mongodb 下建立Data文件夹 C:\Program Files\mongodb\data ,然后分别建立db,log两个文件夹,至此mongodb下有以下文件夹

C:\Program Files\mongodb\bin

C:\Program Files\mongodb\data\db

C:\Program Files\mongodb\data\log

在log文件夹下创建一个日志文件MongoDB.log,即C:\Program Files\mongodb\data\log\MongoDB.log

完成以上工作后,你为奇怪为什么要建立这些文件夹(因为,Mongodb安装需要这些文件夹,默认安装是不用创建,但是文件都为安装到C:\data\下)

4、以上方式做好后,接下来就开始启动MongoDB了。启动的方式很多,这里只介绍 windows service 的方式进行启动。因为这个比较方便哈!

运行cmd.exe

cd C:\Program Files\mongodb\bin

> C:\Program Files\mongodb\bin> mongod –dbpath “C:\Program Files\mongodb\data\db” –logpath “C:\Program Files\mongodb\data\log\MongoDB.log” –install –serviceName “MongoDB”

这里MongoDB.log就是开始建立的日志文件,–serviceName “MongoDB” 服务名为MongoDB

运行命令成功为如下图:

引时服务已经安装成功,运行

>NET START MongoDB   (开启服务)

>NET stop MongoDB   (关闭服务)

这时,MongoDB就成功启动了。

5、测试一下效果。

还是继续那个cmd界面

> cd C:\Program Files\mongodb\bin> mongo

会出现如下界面,说明已经启动成功了。

1

也可以直接在浏览器上输入以下地址: http://localhost:27017/ ,可以看到如下提示: 
You are trying to access MongoDB on the native driver port. For http diagnostic access, add 1000 to the port number

说明成功启动了。

6、接下来输入几段代码测试下数据库:

>db.foo.insert({a:1})    //(往foo表插入a,1字段值,foo表为默认表)

>db.foo.find()                //(查看foo表数据)

如下图:

2

7、可视化工具

以上都是操作命令行代码,不像mysql、SqlServer那些有可视化的客户端工具可以查看数据库内容。

在mongoDB官网也推荐了几款可视化的工具: http://docs.mongodb.org/ecosystem/tools/administration-interfaces/

大家可以选择自己感兴趣的下载使用就行。我这里下载了 mongovue 来体验,下载地址: http://www.mongovue.com/downloads/

下载后解压安装,然后运行 mongovue ,首次使用,需要创建用户,及连接数据库。(PS:貌似这款还是收费的,呵呵,不管了,先体验,晚点找个破解版)

3

8、最后体验完了,停止MongoDB

最稳妥的方式,处理完当前所有操作并将缓存的数据保存到磁盘上才停止

>user admin

>db.shutdownServer();

当然我们也可以直接关闭进程,但这种方式会导致缓存中的数据未急时刷新保存到磁盘上而丢失。

jquery插件及zepto插件 写法异同

jquery插件及zepto插件,写法上有些区别。

区别点: 
1、自定义事件的命名空间 
jq的时间命名空间是用点“.”,而zepto是用冒号“:” 

//jquery
$(this).trigger('cusevent.pluginname');

//zepto
$(this).trigger('cusevent:pluginname');

2、data() 方法 
jq的data方法非常强大,可以存储字符串、对象、函数等一切js数据 
而zepto的data方法则非常简陋,只能纯一下字符串。 
由于写插件时,常用data方法来缓存插件实例化后的内容,所以这里需要做一下兼容修改。

// i is simply a counter, the rest 
// of what is stored will be instances
$.waiting.lookup = {
  i: 0
};

// store the new instance.. $t=$(this)
$.waiting.lookup[++$.waiting.lookup.i] = new $.waiting($t, o);
$t.data('waiting', $.waiting.lookup.i);

// retrieve the instance
var inst = $.waiting.lookup[$(this).data('waiting')];

最后附上,JQ插件的编写模板,写插件的时候就不用考虑代码组织结构了。

/**
 * Created by hugohua on 14-4-1.
 * jQuery plugin template
 */

/**
 * 将插件封装在一个闭包里面,防止外部代码污染  冲突
 */
(function ($) {
    /**
     * 定义一个插件 Plugin
     */
    var Plugin,
        privateMethod;  //插件的私有方法,也可以看做是插件的工具方法集

    /**
     * 这里是插件的主体部分
     * 这里是一个自运行的单例模式。
     * 这里之所以用一个 Plugin 的单例模式 包含一个 Plugin的类,主要是为了封装性,更好的划分代码块
     * 同时 也 方便区分私有方法及公共方法
     * PS:但有时私有方法为了方便还是写在了Plugin类里,这时建议私有方法前加上"_"
     */
    Plugin = (function () {

        /**
         * 插件实例化部分,初始化时调用的代码可以放这里
         * @param element 传入jq对象的选择器,如 $("#J_plugin").plugin() ,其中 $("#J_plugin") 即是 element
         * @param options 插件的一些参数神马的
         * @constructor
         */
        function Plugin(element, options) {
            //将dom jquery对象赋值给插件,方便后续调用
            this.$element = $(element);

            //将插件的默认参数及用户定义的参数合并到一个新的obj里
            this.settings = $.extend({}, $.fn.plugin.defaults,options);
            //如果将参数设置在dom的自定义属性里,也可以这样写
            this.settings = $.extend({}, $.fn.plugin.defaults, this.$element.data(), options);

            //初始化调用一下
            this.init();
        }

        /**
         * 写法一
         * 插件的公共方法,相当于接口函数,用于给外部调用
         */
        Plugin.prototype.doSomething = function () {
            /**
             * 方法内容
             */
        };

        /**
         * 写法二
         * 将插件所有函数放在prototype的大对象里
         * @type {{}}
         */
        Plugin.prototype = {

            init:function(){
                console.log('init');
            },

            doSomething2:function(){

            }
        };

        return Plugin;

    })();

    /**
     * 插件的私有方法
     */
    privateMethod = function () {

    };

    /**
     * 这里是将Plugin对象 转为jq插件的形式进行调用
     * 定义一个插件 plugin
     */
    $.fn.plugin = function (options) {
        return this.each(function () {
            var $me = $(this),
                instance = $me.data('plugin');
            if(!instance){
                //将实例化后的插件缓存在dom结构里(内存里)
                $me.data('plugin', new Plugin(this, options));
            }

            /**
             * 优雅处: 如果插件的参数是一个字符串,则 调用 插件的 字符串方法。
             * 如 $('#id').plugin('doSomething') 则实际调用的是 $('#id).plugin.doSomething();
             * doSomething是刚才定义的接口。
             * 这种方法 在 juqery ui 的插件里 很常见。
             */
            if ($.type(options) === 'string') instance[options]();
        });
    };

    /**
     * 插件的默认值
     */
    $.fn.plugin.defaults = {
        property1: 'value',
        property2: 'value'
    };

    /**
     * 优雅处: 通过data-xxx 的方式 实例化插件。
     * 这样的话 在页面上就不需要显示调用了。
     * 可以查看bootstrap 里面的JS插件写法
     */
    $(function () {
        return new Plugin($('[data-plugin]'));
    });
})(JQuery);