wanderyt的博客

会踢足球的程序猿


  • 首页

  • 归档

  • 标签

  • 搜索

ES6 Learning - 正则表达式扩展

发表于 2016-03-24 | 分类于 UI Development

RegExp构造函数

new RegExp(pattern, attributes);

attributes中:

i - 执行对大小写不敏感的匹配
g - 执行全局匹配(而非在找到第一个匹配后停止)
m - 执行多行匹配

ES5中如果pattern是正则表达式,而不是字符串,则必须省略该参数。而在ES6中,pattern是正则表达式时,第二个参数指定的新修饰符会覆盖原有正则表达式的修饰符。

1
2
new RegExp(/abc/ig, 'i').flags
// "i"
阅读全文 »

ES6 Learning - 字符串扩展

发表于 2016-03-24 | 分类于 UI Development

字符串这边似乎没有什么大的变动,新加了一些原生的函数支持,不过项目中经常会用到underscore或者lodash这样的类库,这些方法看上去更像是官方的一个补充。

includes()

ES5中经常用indexOf判断字符串中是否包含某一字符或字符串片段。如今ES6新加了includes/startsWith/endsWith来进行辅助。

同时,还提供了第二个参数,提供开始搜索的位置。

1
2
3
4
var s = "Hello world";
s.startsWith("world", 6); // true
s.endsWith("Hello", 5); // true
s.includes("Hello", 1); // false
阅读全文 »

ES6 Learning - 变量声明与解构赋值

发表于 2016-03-23 | 分类于 UI Development

最近开始学习ES6,话说ES6出来快一年了,中间其实已经间断学习了一些,今天开始总结一下吧。

这次学习还是基于ruanyf的ES6教程。想要学习比较深入还是看看这个教程或者ES6官方文档吧。

首先,还是先附加一个网站,自动检测当前浏览器以及主流浏览器支持ES6的程度。感觉还是很有用的。

测试链接

阅读全文 »

CSS之margin:auto

发表于 2016-03-22 | 分类于 UI Development

css中常用的居中方法就是margin:auto。

首先要搞清楚一点,auto的含义可能有两种:自动距离或者是0。

水平居中

先举一个例子:

在这个例子中,margin:auto起到了自动居中的作用,但是这种设置对于浮动元素和内联元素不支持,同时对于绝对定位和固定定位的元素也不支持。

下面的这个例子是一个绝对定位的margin:auto的效果。

另外,如果width为0情况下,auto代表元素拥有0px的margin。不过暂时我还没想到width为0还要元素居中的例子,这不是无中生有么。

不过,看上去水平情况下还比较好用。

垂直居中

W3C标准上有句话:

"If "margin-top" or "margin-bottom" is "auto", their used value is 0"

至于具体原因,可能是因为页面的滑动功能,高度的居中需要根据页面位置大小随时计算过于复杂,所以对于margin:auto的元素不做自动垂直居中。

但是,W3C开了一个例外,对于绝对定位的元素,需要满足下面一个公式:

'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block

因此,有两个准则:

If all three of 'top', 'height', and 'bottom' are auto, set 'top' to the static position.
(Tip: the term "static position" (of an element) refers, roughly, to the position an element would have had in the normal flow)

If none of the three are 'auto': If both 'margin-top' and 'margin-bottom' are 'auto', solve the equation under the extra constraint that the two margins get equal values.

因此,我们将一个绝对定位的div放到相对定位的div中,设置top, bottom和height的值之后,垂直居中就产生了。

作为对比,我把内层的绝对定位去掉,或者将top / bottom的值设置成auto,这时候margin:auto全部失效。

原文链接: CSS – margin:auto – How it Works

Precompile Less With Express.js

发表于 2016-03-15 | 分类于 UI Development

最近学习了一下Express.js,正好之前看到Less的预编译,所以做了一把实践。

先说一下正常的Less样式文件加载方式。

首先定义less文件的引用:

<link rel="stylesheet/less" type="text/css" href="./less/style.less" />

样式文件中定义了一些基本的less语法。

#header {
    .button {
        display: block;
        border: 1px solid black;
        background-color: blue;
        &:hover {
            background-color: white
        }
    }
}

之后定义less.js的引用:

<script type="text/javascript" src="./script/less.min.js" />

但是这样加载页面的效率对于生产环境来说是一种灾难,每次都需要根据less.js首先对引用的less文件进行一次编译,转化成html文件可读的css文件。因此在less官方说明中也提倡预编译方式。

Client-side is the easiest way to get started and good for developing with Less, but in production, when performance and reliability is important, we recommend pre-compiling using node.js or one of the many third party tools available.

首先借助express.js搭建工程,并在app.js文件中定义中间件。

这里使用的是Less-middleware。

var lessMiddleware = require("less-middleware");
var express = require("express");
var path = require("path");
var app = express();

app.use(lessMiddleware(path.join(__dirname, "ui"), {
    dest: path.join(__dirname, "ui"),
    force: true,       // Always re-compile less files on request
    once: true,        // Only compile once after server starts or restarts. Useful for reducing disk i/o consumption
    debug: true
}));
app.use(express.static(path.join(__dirname, "ui")));

var server = app.listen(3000, function() {
    var host = server.address().address;
    var port = server.address().port;

    console.log('Example app listening at http://%s:%s', host, port);
});

说明一下,__dirname变量会获取当前模块文件所在目录的完整绝对路径。

之后,在ui目录下定义index.html文件

<link rel="stylesheet" type="text/css" href="./less/style.css">

关于less-middleware中间件定义中的各个参数,我也是测试了多次之后才发现每个参数的用途。

src -- 匹配url中以此为开头的请求路径
dist -- 编译less文件,并将编译后的css文件生成到此路径下的文件夹中
force -- 每次请求都会重新编译生成一遍
once -- 仅仅服务器启动时编译生成css文件

所以,如果在html中定义less文件的href的值为xx.less,那么less-middleware会对应去匹配解析src\xx.less文件,并生成css文件到dist\xx.css。

至于force设置成为true的时候,每次请求页面会重新生成css文件。

app.js中最后那句app.use(express.static(path.join(__dirname, "ui")));定义才会将请求重定位到__dirname\ui下,所以如果需要访问ui\index.html文件,可以直接在地址栏中输入localhost:3000/index.html。这就是express.js的托管静态文件。

总结下来,这应该算是一种预编译,尤其是当force设置成为false的时候,使用less文件的效率会有提升。

但是思考一个问题,无论那种预编译方式,每次访问页面都会去发一次请求:

预编译模式下发一个http请求,获取对应的css文件(其实后台已经完成或需要完成解析less文件功能)
实时解析模式下发两个http请求,首先获取less文件,之后获取less解析器,并解析less文件

相对来说,预编译模式会好一些,但跟html文件直接饮用css文件比起来还是性能上要差一些。所以,大概这就是使用less的缺点之一吧,但是这个缺点应该不会影响到less的那些好的地方。尤其是它的编程风格更接近html的标签嵌套,因此可读性和可维护性方面是css完全无可比拟的。

npm config error

发表于 2016-03-07 | 分类于 UI Development , npm

When installing libraries through npm commands, an error occurs with much possibility.

Seems that it is caused by proxy.

npm install error

Basically, there are two ways to solve the problem.

According to stackoverflow

$ npm install <module> --registry http://165.225.128.50:8000

Tested, not work though.

Set the registry explicitly

$ npm config set registry http://registry.npmjs.org
$ npm install -g <module>

Tested, work.

Time Zone Applied in UI Format

发表于 2015-11-30 | 分类于 UI Development , Javascript

Talking about Date, it is meaningless without definition of timezone.
So, it is important to enable convert time between local and UTC.

Local Time -> UTC

// Create Date object for current location
var d = new Date();

// Get current time zone info
// Return offset unit by MINUTE
// For example: "UTC+8" = -480
var timeZoneOffset = d.getTimezoneOffset();

// Transform MINUTE to MILLISECOND
var offsetMsecs = timeZoneOffset * 60000;

// Obtain UTC time in msec
var utcTime = d.getTime() + offsetMsecs;

// Convert UTC time value to date string
var utcDate = new Date(utcTime);

UTC -> Local Time

// Input
var d,              // UTC Date Object
    timeZoneOffset; // Timezone Offset Minute (-480)

// Transform MINUTE to MILLISECOND
var offsetMsecs = timeZoneOffset * 60000;

// Obtain local time in msec
var localTime = d.getTime() - offsetMsecs;

// Convert local time value to date string
var localDate = new Date(localTime);

Git Standard Flow

发表于 2015-08-14 | 分类于 Git

ThoughtBot的Git使用规范流程。

Git Flow

新建分支

# 获取主干最新代码
$ git checkout master
$ git pull

# 新建一个开发分支myfeature
$ git checkout -b myfeature

提交分支commit

$ git add --all
$ git status
$ git commit [--verbose]

git commit 命令的verbose参数,会列出 diff 的结果。

撰写提交信息

提交信息的范本:

Present-tense summary under 50 characters

* More information about commit (under 72 characters).
* More information about commit (under 72 characters).

http://project.management-system.com/ticket/123

与主干同步

$ git fetch origin
$ git rebase origin/master

合并commit

$ git rebase origin/master

此时如果还有未commit的代码,需要先stash,之后完成rebase,再stash pop。

推送到远程仓库

$ git push --force origin myfeature

git push命令要加上force参数,因为rebase以后,分支历史改变了,跟远程分支不一定兼容,有可能要强行推送

发出Pull Request

Install Package Error in Sublime Text 3

发表于 2015-08-12 | 分类于 UI Development

今天告别Sublime Text 2,彻底进入Sublime Text 3的时代。好像迟了点。。。

第一步就遇到了问题。

Ctrl + Shift + P,习惯性的通过内部安装插件,突然提示框弹出:

There are no packages available for installation.

Google一圈之后似乎满眼都是修改hosts文件,增加对sublime.wbond.net的IP访问。但是报错依旧。

后来在stackoverflow上有一个没有被采纳的建议却真正帮到了我。

下载最新的package contorl文件。

途径一: 到Github上的package control下载最新的文件。

途径二: 到package control的官网上直接下载最新的安装文件,上面有安装路径。

从单例模式看Javascript的闭包

发表于 2015-08-07 | 分类于 Javascript

Singleton - 单例模式

偶然间看到一篇讲解Javascript的单例模式的文章。
作为众多设计模式中的入门级模式,想必大家已经对单例模式已经烂熟于心了,可能也是众多程序猿面试时候的脱口而出的设计模式。

虽然不是本篇的重点,还是先回顾一下单例模式的各个样式吧。

var Singleton = function(name) {
    this.name = name;
    this.instance = null;
}

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

Singleton.getInstance = function(name) {
    if (!this.instance) {
        this.instance = new Singleton(name)
    }
    return this.instance;
}

// Have a test
var a = Singleton.getInstance("a");
var b = Singleton.getInstance("b");

这种是最常见的单例模式代码。

另外一种是这篇文章中提到的代理模式。

var CreateSomething = function(name) {
    this.name = name;
    this.init();
};

CreateSomething.prototype.init = function() {
    // Do something
};

var ProxyCreateSingleton = (function() {
    var instance = null;
    return function(name) {
        if (!instance) {
            instance = new CreateSomething(name);
        }
        return instance;
    }
})();

// Have a test
var a = new ProxyCreateSingleton("a");
var b = new ProxyCreateSingleton("b");

看到这里,不禁联想到最近做的项目中用到的这种写法:

var someFunction = (function() {
    var instance = null;
    return function() {
        // Do something with instance
        return instance;
    }
})();

// Some place else in global space
var oInstance = someFunction();

现在才发现这是单例模式的应用。

原理呢?

怪自己学艺不精了,只知道闭包(Closure)的用法,却没有真正理解闭包在垃圾回收方面的作用。

someFunction函数,返回值是另一个匿名函数。此时,将返回的这个匿名函数赋给一个全局变量,因此匿名函数就无法被回收。

重点来了,这个匿名函数其实是依靠其外部的父函数SomeFunction而存在的,因此,someFunction也无法被回收,其局部变量instance也会一直存活在内存中,这样,每次访问oInstance对象时,指向的都是内存中的那个局部变量instance。

单例就是这样产生的。

推广一下单例的构建方法,使用call / apply。

var CreateSomething() {
    // Do something
    return oInstance;
};

var getSingleton = function(fn) {
    var result;
    return function() {
        return result || (result = fn.apply(this, arguments);
    }
};

var createSingleSomething = getSingleton(CreateSomething);

var something = createSingleSomething(arguments);

new关键字原理

附带讲一下new的原理吧。

var a = new A();
  1. 创建一个新的object,命名为a;
  2. 将A.prototype赋给a.proto;
  3. 调用A.call(a),这时A中的this.name = “David”就被赋值过去到a中,成为a.name = “David”;
  4. 返回a。
1
2
3
4
5
6
7
var a = new Object();
a.__proto__ = A.prototype
var result = A.apply(a, arguments)
if (typeof(result) == "object"){
return result; // 如果有返回值,那么直接返回函数的返回值,此时new可以认为没有起到效果
}
return a;
1…345
wanderyt

wanderyt

wanderyt Blog

50 日志
12 分类
27 标签
RSS
github weibo twitter
© 2015 - 2019 wanderyt
由 Hexo 强力驱动
主题 - NexT.Muse