js

webstrom 使用技巧合集

最近玩了一下SASS,感觉不错,不过CSS3在不同平台兼容性代码一直是个头痛的问题,手写处理费时费力又容易出错。
曾经一直用sublime text写html和css,这些问题都有相应的插件。用Webstorm写js,但是来回切换编辑器也比较麻烦。
虽然Webstorm内置了css3自动补全功能,当输入user-select时,Webstorm会自动补全:

  1. -webkit-user-select: none;

  2. -moz-user-select: none;

  3. -ms-user-select: none;

  4. user-select: none;

但是很多情况下,这种自动补全并不令人满意,比如当我输入display:flex;时,Webstorm并不会自动补全为:

display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;

关于Autoprefixer

Autoprefixer是一个后处理程序,不象Sass以及Stylus之类的预处理器。它适用于普通的CSS,可以实现css3代码自动补全。也可以轻松跟Sass,LESS及Stylus集成,在CSS编译前或编译后运行。详情见,https://github.com/postcss/autoprefixer

当Autoprefixer添加前缀到你的CSS,还不会忘记修复语法差异。这种方式,CSS是基于最新W3C规范产生:

a {background : linear-gradient(to top, black, white);display : flex}::placeholder {color : #ccc}

编译成:

a {background : -webkit-linear-gradient(bottom, black, white);background : linear-gradient(to top, black, white);display : -webkit-box;display : -webkit-flex;display : -moz-box;display : -ms-flexbox;display : flex}:-ms-input-placeholder {color : #ccc}::-moz-placeholder {color : #ccc}::-webkit-input-placeholder {color : #ccc}::placeholder {color : #ccc}

Autoprefixer 同样会清理过期的前缀,因此下面的代码:

a {-webkit-border-radius : 5px;border-radius : 5px}

编译成:

a {border-radius : 5px}

因为经过Autoprefixer处理,CSS将仅包含实际的浏览器前缀。

具体安装和配置:

所以尝试在Webstorm下搜索autoprefixer插件,无果。那就自己手动配置了一个。首先我考虑配置File Watchers,但是不习惯,原来在sublime text下用autoprefixer都是手动触发的,所以后面我配置了External Tools。

1.首先当然是安装node.js;

(略)

2.安装Autoprefixer,

见https://github.com/postcss/autoprefixer:

sudo npm install autoprefixer -g

要不要加sudo,或者是不是全局安装(-g)那就看你自己的环境了。

npm太慢,我是用淘宝的 NPM 镜像的https://npm.taobao.org/

3.安装postcss-cli

Autoprefixer其实是postcss的插件,见https://github.com/code42day/postcss-cli

sudo npm install postcss-cli -g

4.配置External Tools

打开Webstorm设置,Preferences -> Tools -> External Tools ;点击新增按钮,如图:

769EDD8B-6AF0-4D6B-B73B-DF2DC25FAA1F

填写具体配置,例如我的配置,如图:

0C4975D0-6531-432B-8812-46D56164B817

  1. Program:填入你的postcss-cli 的PATH;

  2. Parameters: -u autoprefixer -o $FileDir$/$FileName$  $FileDir$/$FileName$ ,你可以根据你自己的需要配置,具体参见https://github.com/code42day/postcss-cli

  3. Working directory :$ProjectFileDir$

配置好后,你可以在css,或sass文件中右键,就可以在右键菜单中看到External Tools – autoprefixer,点击搞定,嘎嘎。

5.设置快捷键

右键太麻烦的话,可以设置个快捷键,打开Webstorm设置,Preferences -> Keymap , 搜索External Tools , 配置 autoprefixer即可。 不要和原来的冲突就可以了。

ps:windows下可以直接用autoprefixer的PATH,具体配置

414473-5caba82f3555f590 (1)


windows 找不到autoprefixer.cmd,webstrom无法用执行autoprefixer 这个问题,
可以配置
Program:C:\Users\gaojun-pd\AppData\Roaming\npm\postcss.cmd
Parameters:-u autoprefixer -o $FileDir$\$FileName$ $FileDir$\$FileName$
Working directory :$ProjectFileDir$


caspejs 中文乱码解决方案

在文件头部加入

  1. phantom.outputEncoding="GBK";

就能解决 比如

phantom.outputEncoding="GBK";

var casper = require('casper').create();


casper.start('http://www.baidu.com/', function() {

    this.echo(this.getTitle());

});


casper.thenOpen('http://www.luqidong.com', function() {

    this.echo(this.getTitle());

});


casper.run();



CasperJS needs PhantomJS v1.x 解决方案

问题出现原因:phantomjs 2.0.0 不稳定用1.9.8 就没问题

 解决方案:

1、换1.9.8版本的phantomjs

2、打开casperjs 里面的bootstrap.js  地址在 \bin\里面 

然后找到 判断phantomjs 版本的地方

替换成一下代码

(function (version) {
    // required version check
    if (version.major === 1) {
        if (version.minor < 8) {
            return __die('CasperJS needs at least PhantomJS v1.8 or later.');
        }
        if (version.minor === 8 && version.patch < 1) {
            return __die('CasperJS needs at least PhantomJS v1.8.1 or later.');
        }
    } else if (version.major === 2) {
        console.log("Warning PhantomJS v2.0 not yet released. There will not be any official support for any bugs until stable version is released!");
    }
    else return __die('CasperJS needs PhantomJS v1.x or v2.x');
})(phantom.version);



深入理解 javascript 中的 this 指向

   别指望看几篇讲解就能看懂js里面的this。我也是前后翻阅了很多资料最后稍微有点懂的。

javascript里面的this跟大多数语言类似,总是指的一个对象,而具体的指向哪个对象是在运行时基于函数的执行环境动态绑定的,二不是函数被声明时的环境。

  基本 this的指向大致分为以下四种

  • 作为对象的方法调用

  • 作为普通函数调用

  • 构造器调用

  • Function.prototype.call或Function.prototype.apply调用

  下面详细讲解下

1、作为对象的方法调用

当函数作为对象的方法调用的时候,this指向该对象

var obj = {
    a: 1,
    getA: function () {
        alert(this === obj);//true
        alert(this.a);//1
    }
};
obj.getA();

2、作为普通函数调用

当函数不作为对象的属性被调用的时候,也就是我们常说的普通函数方式,此时this总是指向全局对象,在浏览器的javascript里,这个全局对象就是window对象。

window.name ='globalName';
var getName = function(){
    return this.name;
};
console.log(getName()); //globalName

//or

window.name ='globalName';
var myobj ={
    name:'sven',
    getName:function(){
        return this.name;
    }
};
myobj.getName() ;//sven
var getName = myobj.getName;
console.log(getName());// globalName

  但是有时候我们会遇到一些困扰,比如在div节点的时间函数内部,有一个局部的callback方法,callback被作为普通函数调用时,callback内部的this指向了window,但是我们往往想让他指向该div节点,代码:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<div id="div1">我是一个div</div>
<script>
    window.id = "window";
    document.getElementById("div1").onclick = function () {
        alert(this.id);
        var callback = function () {
            alert(this.id);
        };
        callback();
    }
</script>
</body>
</html>

此时有一个简单的解决方案,可以用一个变量保存div节点的引用。

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<div id="div1">我是一个div</div>
<script>
    window.id = "window";
    document.getElementById("div1").onclick = function () {
        var that =this;
        alert(this.id);
        var callback = function () {
            alert(that.id);
        };
        callback();
    }
</script>
</body>
</html>

在ECMAScript 5的 严格模式下,这种情况的this已经被规定为不会指向全局对象,而是undefined。

3、构造器调用

  javascript中没有类,但是可以从构造器中创建对象,同事也提供了new的运算符,使得构造器看起来更像一个类。

  除了宿主提供一些内置函数,大部分的javascript函数都可以当做构造器使用。构造器的外表跟普通函数一模一样,他们的区别在于被调用的方式,当用new运算符调用函数时,该函数总是会返回一个对象,通常情况下,构造器里的this就指向返回的这个对象,如下代码:

var MyClass = function () {
    this.name = 'sven';
};
var obj = new MyClass();
alert(obj.name); //sven


但用new 调用构造器时,还要注意一个问题,如果构造器显式地返回一个object类型的对象,那么此次运算结果最终会返回这个对象,而不是我们期待的this:

var MyClass = function () {
    this.name = 'sven';
    return { //显式滴返回了一个对象
        name: 'anne'
    }
};
var obj = new MyClass();
alert(obj.name); //anne

如果构造器不显式地返回任何数据,或者是返回一个非对象类型的数据,就不会造成以上的问题:

var MyClass = function () {
    this.name = 'sven';
    return 'anne';
};
var obj = new MyClass();
alert(obj.name); //sven

4、Function.prototype.call或Function.prototype.apply调用

  跟普通的函数调用想必,用Function.prototype.call或Function.prototype.apply可以动态第改变传入函数的this:

var obj1 = {
    name: 'sven',
    getName: function () {
        return this.name;
    }
};
var onj2 = {
    name: 'anne'
};

console.log(obj1.getName());//sven
console.log(obj1.getName.call(obj2));//anne

call 和 apply的方法能很好滴体验javascript的函数式编程特性,在javascript中,几乎每一次编写函数式风格的代码,都离不开call和apply。


fiddler使用教程(二) 断点调试

fiddler的断点功能可以截获发送或者接收到的请求,然后更改信息方便我们的调试。对于前端开发工程师来说对发送或者对接受的请求做处理是再正常不过的了下面用fiddler做一个例子来讲解下如何用fiddler做断点调试。

1、断点的位置在界面的底部

点击一下会出现一个箭头朝上的标记,在点击下就会有抄下的标记

第一个是断点的发送请求出去之前,第二个是数据返回的时候截取。

2、我们以www.ly.com为例子:

点击这几个tab标签会请求异步替换掉下面的内容。

我们点击海岛的时候请求的异步里面有2个核心参数一个是method 一个是 typeName 。先断点断在发送求情的时候 

然后点击一个tab标签 比如欧洲:如下图

第一个是断点到返回状态,第二个是直接走完,第三个是传到服务器的一些值,我们在这里可以进行更改,然后点击Run to Completion 来完成这个请求,或者点击工具栏上的go按钮来走完全部的请求。当然我们还可以修改请求的头部信息,比如传过去的cookies等。

3、截断请求返回的内容进行修改

由于我们这是返回之后的信息修改,所以返回之前的头信息是无法修改的,点击右侧Texview 就是查看返回的内容,然后在这里是可以修改的. 还有点击右下角在 notepad里面查看这样看起来更方便,修改完之后点击 Run to Completion 走完整个请求的过程,然后查看下状态.


这只是个简单的例子,大家可以举一反三。


未完待续


PhantomJS 入门(一)

Urna Semper
陆启东
2015年6月21日


PhantomJS 入门
PhantomJS is a headless WebKit with JavaScript API.


     我想我不需要说服你测试你的javascript代码是一个好习惯,但是有时候在dom里面测试你得javascript实在很乏味,也就是说你必须在浏览器里面测试你得代码而非命终端里面。这样真的对么?显然不对,请看这里PhantomJS


     那么PhantomJS到底是什么呢?这里我们引用下官网的一句话
PhantomJS is a headless WebKit with JavaScript API.
    你懂的,Webkit是Chrome,Safari和一些小众浏览器的引擎,所以说PhantomJS是一个浏览器但是又不是浏览器,也就是说通过它可以实现一个也没一个网页但是你并不需要打开它,或者这个让你听起来很困扰,所以你只要记住它类似于一个浏览器但是在控制台中使用就行了,哦了那我们来简单看下一个例子,当然首先你需要安装好PhantomJS。
     安装PhantomJS
     安装PhantomJS这实在是太简单了,只需要吧程序下载下来放到你的控制台环境变量路径里面,下载页面是PhantomJS download page。进去选择你当前系统的包,然后把文件复制到你得控制台系统路径里面。
     如果你是Mac OS X的话那更简单啦,直接运行:
    brew update && brew install phantomjs
     查看你是否已经安装好了PhantomJS
    phantomjs --version


简单的例子

    让我们来看一个简单的例子

    simple.js

console.log("we can log stuff out.");
 
function add(a, b) {
    return a + b;
}
 
conslole.log("We can execute regular JS too:", add(1, 2));
 
phantom.exit();


我们来用下面的命名来运行它

phantomjs simple.js

运行结果

我们在控制台看到了两行输出。当然这个非常简单,但是它反映出一点:PhantomJS可以像一个浏览器那也处理javascript,然而这段代码并没有PhantomJS-specific 代码,但是看最后一行,这个很重要,因为所有的phantomjs执行完之后都要退出,比如我们想再关闭里面写个回调。


加载页面

phantomjs可以帮助我们打开一个页面,并且执行javascript。

例如: script.js

var page = require('webpage').create();
 
page.open('http://www.ly.com', function (s) {
    console.log(s);
    phantom.exit();
});


这里我们利用webpage模块来创建一个webpage对象,然后使用open的方法打开它,里面有2个参数第一个是url,然后就是回调函数,回调函数里面,里面可以输出返回的状态,如上代码执行之后我们在控制台里面看到的应该是"success"。

    让我们来做些更有趣的事情,我们打开页面然后执行一段脚本看看:

page.open('http://www.ly.com', function () {
    var title = page.evaluate(function () {
        var posts = document.getElementsByClassName("logo");
        posts[0].style.backgroundColor = "#000000";
        return document.title;
    });
    page.clipRect = { top: 0, left: 0, width: 600, height: 700 };

    page.render(title + ".png");

  未完待续



gulp入门教程

   

一、什么是gulp。

 gulp和grunt是基于Node.js创建,是一个基于任务的命令行工具,它能够同构减少减少预先需要准备的资源来加速工作流。它将工作包裹进入任务之中,任务会随着你的工作进程自动编译。它与grunt的最大区别就是它充分借鉴了Unix操作系统的管道(pipe)思想,很多人认为,在操作上,它要比Grunt简单。

1、插件职能不够单一


2、插件完成了本不该由插件完成的事情(这个我有点迷糊,为什么说是 things don't need to be plugins?)


3、配置过于复杂


4、由于糟糕的流程控制导致的临时文件/目录


二、安装gulp

1、npm install -g gulp


2、npm install --save-dev gulp 注释:使用–save/–save-dev就可以自动更新package.json


三、使用方法

在项目目录直接新建gulpfile.js文件,gulp就5个方法:task(创建任务),run(跑任务),watch(观察一般文件改的自动运行任务),src(源文件),和dest(输出文件)。

一般前端任务都是一些sass编译、文件合并压缩重命名、制作雪碧图、和脚本检查这几个需要如下插件

gulp-jshint脚本检查 gulp-sass sass编译 gulp-concat 合并 gulp-uglify脚本压缩 gulp-rename重命名 gulp-minify-css css压缩

下面上代码:

/**
 * 组件安装
 * npm install gulp-util gulp-imagemin gulp-ruby-sass gulp-minify-css gulp-jshint gulp-uglify gulp-rename gulp-concat gulp-clean gulp-livereload tiny-lr --save-dev
 */

// 引入 gulp及组件
var gulp    = require('gulp'),                 //基础库
    imagemin = require('gulp-imagemin'),       //图片压缩
    sass = require('gulp-ruby-sass'),          //sass
    minifycss = require('gulp-minify-css'),    //css压缩
    jshint = require('gulp-jshint'),           //js检查
    uglify  = require('gulp-uglify'),          //js压缩
    rename = require('gulp-rename'),           //重命名
    concat  = require('gulp-concat'),          //合并文件
    clean = require('gulp-clean'),             //清空文件夹
    tinylr = require('tiny-lr'),               //livereload
    server = tinylr(),
    port = 35729,
    livereload = require('gulp-livereload');   //livereload

// HTML处理
gulp.task('html', function() {
    var htmlSrc = './src/*.html',
        htmlDst = './dist/';

    gulp.src(htmlSrc)
        .pipe(livereload(server))
        .pipe(gulp.dest(htmlDst))
});

// 样式处理
gulp.task('css', function () {
    var cssSrc = './src/scss/*.scss',
        cssDst = './dist/css';

    gulp.src(cssSrc)
        .pipe(sass({ style: 'expanded'}))
        .pipe(gulp.dest(cssDst))
        .pipe(rename({ suffix: '.min' }))
        .pipe(minifycss())
        .pipe(livereload(server))
        .pipe(gulp.dest(cssDst));
});

// 图片处理
gulp.task('images', function(){
    var imgSrc = './src/images/**/*',
        imgDst = './dist/images';
    gulp.src(imgSrc)
        .pipe(imagemin())
        .pipe(livereload(server))
        .pipe(gulp.dest(imgDst));
})

// js处理
gulp.task('js', function () {
    var jsSrc = './src/js/*.js',
        jsDst ='./dist/js';

    gulp.src(jsSrc)
        .pipe(jshint('.jshintrc'))
        .pipe(jshint.reporter('default'))
        .pipe(concat('main.js'))
        .pipe(gulp.dest(jsDst))
        .pipe(rename({ suffix: '.min' }))
        .pipe(uglify())
        .pipe(livereload(server))
        .pipe(gulp.dest(jsDst));
});

// 清空图片、样式、js
gulp.task('clean', function() {
    gulp.src(['./dist/css', './dist/js', './dist/images'], {read: false})
        .pipe(clean());
});

// 默认任务 清空图片、样式、js并重建 运行语句 gulp
gulp.task('default', ['clean'], function(){
    gulp.start('html','css','images','js');
});

// 监听任务 运行语句 gulp watch
gulp.task('watch',function(){

    server.listen(port, function(err){
        if (err) {
            return console.log(err);
        }

        // 监听html
        gulp.watch('./src/*.html', function(event){
            gulp.run('html');
        })

        // 监听css
        gulp.watch('./src/scss/*.scss', function(){
            gulp.run('css');
        });

        // 监听images
        gulp.watch('./src/images/**/*', function(){
            gulp.run('images');
        });

        // 监听js
        gulp.watch('./src/js/*.js', function(){
            gulp.run('js');
        });

    });
});

运行的话只需要在工程目录下 gulp yourtaskname  你的任务名就可以了


node connect logger报错无此方法

代码:

var http = require('http');var connect = require('connect');var app = connect()
  .use(connect.logger('dev'))
  .use(connect.static('public'))
  .use(connect.bodyParser())
  .use(function(req, res){
    res.end(JSON.stringify(req.body));
  })http.createServer(app).listen(2081);

报错图:

/home/carl/nodedev/test.js:5
  .use(connect.logger('dev'))
               ^TypeError: Object function createServer() {
  function app(req, res, next){ app.handle(req, res, next); }
  merge(app, proto);
  merge(app, EventEmitter.prototype);
  app.route = '/';
  app.stack = [];
  return app;} has no method 'logger'
    at Object.<anonymous> (/home/carl/nodedev/test.js:5:16)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:906:3


原因:

connect更新了 logger更换成了morgan 请看这里 https://www.npmjs.org/package/connect

现在错误日志记录需要用morgan ,引用下 morgan 就行

var logger = require('morgan');

var app = connect().use(logger());



判断ie11的js方法

if (Object.hasOwnProperty.call(window, "ActiveXObject") && !window.ActiveXObject) {
    // is IE11}



var ua = window.navigator.userAgent;var versionSplit = /[\/\.]/i;var versionRe = /(Version)\/([\w.\/]+)/i; // match for browser versionvar operaRe = /(Opera|OPR)[\/ ]([\w.\/]+)/i;var ieRe = /(?:(MSIE) |(Trident)\/.+rv:)([\w.]+)/i; // must not contain 'Opera'var match = ua.match(operaRe) || ua.match(ieRe);if (!match) {
    return false;}if (Array.prototype.filter) {
    match = match.filter(function(item) {
        return (item != null);
    });} else {
    // Hello, IE8!
    for (var j = 0; j < match.length; j++) {
        var matchGroup = match[j];
        if (matchGroup == null || matchGroup == '') {
            match.splice(j, 1);
            j--;
        }
    }}var name = match[1].replace('Trident', 'MSIE').replace('OPR', 'Opera');var versionMatch = ua.match(versionRe) || match;var version = versionMatch[2].split(versionSplit);


2种方法


很全面的javascript思维导图

   

阅读详细 »