SourceTree 完全使用指南

SourceTree简介

SourceTree是强大的Git/Mercurial桌面客户端,支持Windows和Mac操作系统。通过SourceTree美观简单的界面,你可以放弃命令行了。

安装

首先我们需要来安装SourceTree, 前往SourceTree官网
Windows的话下载exe安装包,按照我们安装软件的一般步骤进行,SourceTree是一款免费软件,但是需要自己注册个atlassian账户才能安装完成,安装步骤中会提示你需要注册账户来获取许可证,atlassian官网也可以使用谷歌账户登陆,这里我直接用的谷歌账户登陆的,然后按照步骤完善账号信息,直到网页上出现许可证信息就完成了。
qq%e5%9b%be%e7%89%8720161128122303
但是SourceTree的安装指引此时并没有跳转到下一步,这时你需要直接在安装界面上有个直接登陆选项,再登陆一次,我是尝试了好几次,才顺利进入安装的下一步。
到下一步之后的过程中可能会看到这个界面,
2016-11-28_120430
Mercurial是一个跨平台的分布式版本控制软件,和Git类似,咱们一般使用Git,所以这个窗口可以选择第一个选项或最后一个不安装Mercuial。选好之后安装就完成了,先来熟悉一下吧,使用后续补充。
补充: 还是喜欢用命令行,不折腾SourceTree啦。

{转载博客园}JavaScript事件代理和委托(Delegation)

在javasript中delegate这个词经常出现,看字面的意思,代理、委托。那么它究竟在什么样的情况下使用?它的原理又是什么?在各种框架中,也经常能看到delegate相关的接口。这些接口又有什么特殊的用法呢?这篇文章就主要介绍一下javascript delegate的用法和原理,以及jQuery等框架中delegate的接口。

JavaScript事件代理

首先介绍一下JavaScript的事件代理。事件代理在JS世界中一个非常有用也很有趣的功能。当我们需要对很多元素添加事件的时候,可以通过将事件添加到它们的父节点而将事件委托给父节点来触发处理函数。这主要得益于浏览器的事件冒泡机制,后面会详细介绍。下面我们具体举个例子来解释如何使用这个特性。

假设有一个 UL 的父节点,包含了很多个 Li 的子节点:

<ul id="parent-list">
  <li id="post-1">Item 1</li>
  <li id="post-2">Item 2</li>
  <li id="post-3">Item 3</li>
  <li id="post-4">Item 4</li>
  <li id="post-5">Item 5</li>
  <li id="post-6">Item 6</li>
</ul>

当我们的鼠标移到Li上的时候,需要获取此Li的相关信息并飘出悬浮窗以显示详细信息,或者当某个Li被点击的时候需要触发相应的处理事件。我们通常的写法,是为每个Li都添加一些类似onMouseOver或者onClick之类的事件监听。

function addListeners4Li(liNode){
    liNode.onclick = function clickHandler(){...};
    liNode.onmouseover = function mouseOverHandler(){...}
}

window.onload = function(){
    var ulNode = document.getElementById("parent-list");
    var liNodes = ulNode.getElementByTagName("Li");
    for(var i=0, l = liNodes.length; i < l; i++){
        addListeners4Li(liNodes[i]);
    }   
}

如果这个UL中的Li子元素会频繁地添加或者删除,我们就需要在每次添加Li的时候都调用这个addListeners4Li方法来为每个Li节点添加事件处理函数。这就添加的复杂度和出错的可能性。

更简单的方法是使用事件代理机制,当事件被抛到更上层的父节点的时候,我们通过检查事件的目标对象(target)来判断并获取事件源Li。下面的代码可以完成我们想要的效果:

// 获取父节点,并为它添加一个click事件
document.getElementById("parent-list").addEventListener("click",function(e) {
  // 检查事件源e.targe是否为Li
  if(e.target && e.target.nodeName.toUpperCase == "LI") {
    // 真正的处理过程在这里
    console.log("List item ",e.target.id.replace("post-")," was clicked!");
  }
});

为父节点添加一个click事件,当子节点被点击的时候,click事件会从子节点开始向上冒泡。父节点捕获到事件之后,通过判断e.target.nodeName来判断是否为我们需要处理的节点。并且通过e.target拿到了被点击的Li节点。从而可以获取到相应的信息,并作处理。

事件冒泡及捕获

之前的介绍中已经说到了浏览器的事件冒泡机制。这里再详细介绍一下浏览器处理DOM事件的过程。对于事件的捕获和处理,不同的浏览器厂商有不同的处理机制,这里我们主要介绍W3C对DOM2.0定义的标准事件。

DOM2.0模型将事件处理流程分为三个阶段:一、事件捕获阶段,二、事件目标阶段,三、事件起泡阶段。如图:

JavaScript事件代理和委托(Delegation)

事件捕获:当某个元素触发某个事件(如onclick),顶层对象document就会发出一个事件流,随着DOM树的节点向目标元素节点流去,直到到达事件真正发生的目标元素。在这个过程中,事件相应的监听函数是不会被触发的。

事件目标:当到达目标元素之后,执行目标元素该事件相应的处理函数。如果没有绑定监听函数,那就不执行。

事件起泡:从目标元素开始,往顶层元素传播。途中如果有节点绑定了相应的事件处理函数,这些函数都会被一次触发。如果想阻止事件起泡,可以使用e.stopPropagation()(Firefox)或者e.cancelBubble=true(IE)来组织事件的冒泡传播。

jQuery中delegate函数

下面看一下jQuery中提供的事件代理接口的使用方法。

$("#link-list").delegate("a", "click", function(){
  // "$(this)" is the node that was clicked
  console.log("you clicked a link!",$(this));
});

jQuery的delegate的方法需要三个参数,一个选择器,一个时间名称,和事件处理函数。

优点

通过上面的介绍,大家应该能够体会到使用事件委托对于web应用程序带来的几个优点:

1.管理的函数变少了。不需要为每个元素都添加监听函数。对于同一个父节点下面类似的子元素,可以通过委托给父元素的监听函数来处理事件。

2.可以方便地动态添加和修改元素,不需要因为元素的改动而修改事件绑定。

3.JavaScript和DOM节点之间的关联变少了,这样也就减少了因循环引用而带来的内存泄漏发生的概率。

在JavaScript编程中使用代理

上面介绍的是对DOM事件处理时,利用浏览器冒泡机制为DOM元素添加事件代理。其实在纯JS编程中,我们也可以使用这样的编程模式,来创建代理对象来操作目标对象。这里引用司徒正美相关文章中的一个例子:

var delegate = function(client, clientMethod) {
    return function() {
        return clientMethod.apply(client, arguments);
    }
}
var ClassA = function() {
    var _color = "red";
    return {
        getColor: function() {
            console.log("Color: " + _color);
        },
        setColor: function(color) {
            _color = color;
        }
    };
};

var a = new ClassA();
a.getColor();
a.setColor("green");
a.getColor();
console.log("执行代理!");
var d = delegate(a, a.setColor);
d("blue");
console.log("执行完毕!");
a.getColor();

上面的例子中,通过调用delegate()函数创建的代理函数d来操作对a的修改。这种方式尽管是使用了apply(call也可以)来实现了调用对象的转移,但是从编程模式上实现了对某些对象的隐藏,可以保护这些对象不被随便访问和修改。

在很多框架中都引用了委托这个概念用来指定方法的运行作用域,主要也是js函数的apply方法来制定执行作用域。
本文来源: 博客园

{转载segmentfault}观察者模式在前端中的表现形式——事件机制

在构建前端应用的时候免不了要和事件打交道,有些同学可能觉得事件不就是鼠标点击执行特定的函数之类的吗?

此“事件”非彼“事件”。这里的“事件”,实际上是指“观察者模式(Observer Pattern)”在前端的一种呈现方式。所谓观察者模式可以类比博客“订阅/推送”,你通过RSS订阅了某个博客,那么这个博客有新的博文就会自动推送给你;当你退订阅这个博客,那么就不会再推送给你。

用JavaScript代码可以怎么表示这么一个场景?

var blog = new Blog; // 假设已有一个Blog类实现subscribe、publish、unsubscribe方法

var readerFunc1 = function(blogContent) { 
    console.log(blogContent + " will be shown here.");
}
var readerFunc2 = function(blogContent) { 
    console.log(blogContent + " will be shown here, too.");
}

blog.subscribe(readerFunc1); // 读者1订阅博客
blog.subscribe(readerFunc2); // 读者2订阅博客

blog.publish("This is blog content."); // 发布博客内容,上面的两个读者的函数都会被调用
blog.unsubscribe(readerFunc1); // 读者1取消订阅
blog.publish("This is another blog content."); // readerFunc1函数不再调用,readerFunc2继续调用

可以把上面的“新文章”看成是一个事件,“订阅文章”则是“监听”这个事件,“发布新文章”则是“触发”这个事件,“取消订阅文章”就是“取消监听”“新文章”这个事件。假如“监听”用on来表示,“触发”用emit来表示,“取消监听”用off来表示,那么上面的代码可以重新表示为:

var blog = new Blog; // 假设已有一个Blog类实现on、emit、off方法

var readerFunc1 = function(blogContent) { 
    console.log(blogContent + " will be shown here.");
}
var readerFunc2 = function(blogContent) { 
    console.log(blogContent + " will be shown here, too.");
}

blog.on("new post", readerFunc1); // 读者1监听事件
blog.on("new post", readerFunc2); // 读者2监听事件

blog.emit("new post", "This is blog content."); // 发布博客内容,触发事件,上面的两个读者的函数都会被调用
blog.off("new post", readerFunc1); // 读者1取消监听事件
blog.emit("new post", "This is another blog content."); // readerFunc1函数不再调用,readerFunc2继续调用

这就是前端中观察者模式的一种具体的表现,使用on来监听特定的事件,emit触发特定的事件,off取消监听特定的事件。再举一个场景“小猫听到小狗叫就会跑”:

var dog = new Dog;
var cat = new Cat;

dog.on("park", function() { 
    cat.run(); 
});

dog.emit("park");

巧妙利用观察者模式可以让前端应用开发耦合性变得更加低,开发效率更高。可能说“变得更有趣”会显得有点不专业,但确实会变得有趣。
本来来源: [segmentfault] (https://segmentfault.com/a/1190000002640469)

详解通过命令行使用Git并把项目托管到Github上

生成一个新的 SSH key

首先你需要在电脑上生成一个新的 SSH key

$ ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
$ Enter a file in which to save the key (/Users/you/.ssh/id_rsa): [Press enter]

直接Enter, 我们用默认的目录就行。
然后输入passphrase密码

$ Enter passphrase (empty for no passphrase): 
$ Enter same passphrase again: 

把SSH key 加到 ssh-agent 中

确保 ssh-agent is enabled:

$ eval "$(ssh-agent -s)"
Agent pid 754

把SSH key 加到 ssh-agent 中

$ ssh-add ~/.ssh/id_rsa

18421136f1a3134980

把新 SSH key 加入到你的 Github 账户中

打开并且登录你的Github账户,然后点击头像,进入 Settings, 然后选择左栏 SSH and GPG keys 选项卡,点击New SSH key, 然后title自定义,填一个能标示你电脑的名称即可
2016-09-01_225636
然后

$ cd ~/.ssh/
$ ls
id_rsa      id_rsa.pub  known_hosts
$ cat id_rsa.pub

然后会出现一大段字符串,把这段字符串全部粘贴到Github网站我们刚才New SSH key时出现的Key文本框中。然后点击Add SSH key就完成啦。

在Github上建立项目仓库

在Github网站上点击加号,然后点击 New repository, 填上项目名称和描述,然后点击Create repository就完成创建了
2016-09-01_230203

如果你本地已经有这个项目

首先进入你本地的这个项目目录
然后
* 初始化git仓库

$ git init
  • 把项目中所有文件加到本地仓库,别忘了最后的小圆点
$ git add .
$ git commit -m "first commit"
  • 为版本库添加名为origin的远程版本库
$ git remote add origin https://github.com/cuidezhu/Node-Chat.git
  • 执行推送命令
$ git push -u origin master

如果当前分支与多个主机存在追踪关系,则可以使用-u选项指定一个默认主机,这样后面就可以不加任何参数使用git push

如果你本地一开始没有这个项目,你可以

$ git clone https://github.com/cuidezhu/Node-Chat.git

这里的Github用户名和仓库名都换成你自己的。
然后可以创建一个README.md文件,这个文件是Markdown语法来写,不过Markdown语法也兼容HTML,关于Markdown的具体语法,查看这个文档 Markdown 语法说明 (简体中文版)

好了,介绍地够详细啦,你学会啦吧。

一个fibonacci函数

/**
 *@desc: fibonacci
 *@param: count {Number}
 *@return: result {Number} 第count个fibonacci值,计数从0开始
  fibonacci数列为:[1, 1, 2, 3, 5, 8, 13, 21, 34 …]
  则getNthFibonacci(0)返回值为1
  则getNthFibonacci(4)返回值为5
 */
function getNthFibonacci(count) {

    if (count == 0 || count == 1) {
        return 1;
    }

    var first = 1;
    var second = 1;
    var result = 0;

    for (var i = 2; i <= count; i++) {
        result = first + second;
        first = second;
        second = result;
    }

    return result;
}

此题应避免使用递归,当count较大时,递归方法效率低下,递归次数过多容易造成栈溢出。

制作图片验证码

图片验证码是网站中常用的一个组件,今天我们讲一讲使用PHP制作图片验证码。

开启PHP的GD库

GD库是PHP图像生成和处理的函数,我们用PHP画图时需要首先开启PHP的GD库。到php.ini文件中找到extension=php_gd2.dll,如果这行配置代码被注释了,则取消注释。

继续阅读制作图片验证码

使用vundle安装vim插件emmet

Vundle是一款流行vim插件管理工具,也是代表了现在和以后vim插件管理的方式的革新。本文我们来讲解安装vundle和用vundle来安装vim的emmet插件。

首先安装 Vundle

$ git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim

修改.vimrc文件

cd ~/.vimrc
把下列代码加到.vimrc文件后面:

继续阅读使用vundle安装vim插件emmet

一个诡异的vim字体背景问题

刚刚在给vim调整配色方案的时候,无缘无故地vim的字体背景颜色就变为黄色啦,类似于这样。
定制网站
无论怎么调整vim配色字体的背景都是黄色,于是搜索一下,发现用vim打开这个文件/etc/virc,然后在文件中搜索一下syntax关键字: /syntax,一切就都正常啦,字体的黄色背景没有啦,很是诡异。。

再论WordPress文章ID不连续

我们之前的一篇文章谈谈wordpress的固定链接post_id的连续性谈到了怎样解决post id不连续的问题,但没有解决彻底,当通过后台上传文章所需图片时,图片还是会占用post id造成post id的不连续。这对于强迫症患者是不能忍受的。

继续阅读再论WordPress文章ID不连续