写写原生JavaScript系列(1)-使用CSS选择器选择元素

PS:基础决定一个人是否能够在技术路线上走的更远,不积跬步,无以至千里,越来越多的公司看中员工技术基础。那么我们在享受jQuery极大便利的时候,也需要记得返璞归真看看原生的JavaScript 能给我带来些什么,有些时候是有好处的例如移动端可以减少额外的库的加载。偶然发现 plainjs.com 的一系列文章,感觉非常不错,跟着学习的同时搬运到博客,不足之处还望指正。

querySelectorAll() 是一个原生javascript (需要注意兼容性)提供的一个类似jquery选择器的方法。

querySelectorAll() 方法根据你传入的选择字符串返回一组匹配的DOM元素列表。
如果你使用过JQuery操作过DOM元素,你可能对下面的写法不会感到意外:

var matches = document.querySelectorAll('div.foo');

for (i=0; i<matches.length; i++)
    console.log(matches[i].innerHTML);

more >>

使用HTML5创建超级马里奥游戏

原文作者在浏览器中实现一个可以玩的著名的跳跃游戏,作者介绍了动画、面向对象、位运算、图片精灵等诸多干货
下载本文项目源文件 - 0.99 MB

简介

article1.png

在历史上很多优秀的电脑游戏被创造出来,同时奠定了游戏行业发展的基础。这些游戏其中包括了超级马里奥。马里奥这个人物形象第一次出现是在大金刚,随后在1983年的马里奥系列中变得非常出名。现在出现了大量的围绕马里奥形象的衍生版本以及3D版本的游戏。在这篇文章中,我们将开发一个非常简单的超级马里奥山寨版本,为了适合讲解,我们设计得更具有拓展性,具有新的敌人、物品、英雄。

游戏的代码使用OOP的方式来组织。虽然目前JavaScript被认为是一种基于原型的脚本语言,面向对象可能有很多坑,但是我们还是可以尝试使用面向对象。我们将介绍一些关于面向对象的知识和约定,这种模式在整个编码过程会极其有用。

背景

youtube.png

最开始的代码是我的两个学生用我给他们提供的“HTML5编程开发Web应用,CSS3和JavaScript”课程代码为基础。他们开发的游戏包括一个关卡编辑器,声音和图形。游戏本身到没有什么BUG,但是性能比较差,并且代码不是很容易拓展,主要原因是使用了jQuery 的插件。主要是我的责任,因为开始我推荐使用最简单的方法去实现,在简单的情况下使用jQuery插件做动画并没啥问题,但是一旦动画多了就会导致性能问题。因为每一个新的动画(即使同时产生)将会占用CPU的时间片段。

more >>

通过单元测试写出高质量的前端代码

编写JavaScript有时候很痛苦。往往从一段简单而有趣的脚本,慢慢的就变得一团糟。我曾经发现我自己陷入到充满回调和耦合的大杂烩中。因此,我想必须寻找一种有效的方式解决这些问题。

简介

编写JavaScript有时候很痛苦。往往从一段简单而有趣的脚本,慢慢的就变得一团糟。我曾经发现我自己陷入到充满回调和耦合的大杂烩中。因此,我想必须寻找一种有效的方式解决这些问题。在这篇文章中,我想通过书写单元测试来探索这种更好的书写Javascript的方式。

我准备了一个demo来演示这种方式。通过精简不必要的逻辑,仅仅包含一个普通的带过滤功能的商品列表。没啥花哨的东西,但是能够表达出我了解到的这种产生高质量代码的解决方案的要点。

Download source code from Github

more >>

为什么我们需要TypeScript

ps:阅读文章前,先引用一段百度百科关于TypeScript的介绍,具体可以搜索TypeScript以及相关的CoffeeScript

TypeScript是一种由微软开发的自由和开源的编程语言。它是JavaScript的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程。

从1.0的发布开始,我已经对TypeScript项目关注了超过一年。它的理念吸引着我,但是正是因为具有了和大多数语言一样的习惯和特性,我还不能确定它最终是否可以发展起来。无论如何,最近的消息称TypeScript可能会被用于创建 AngularJS2.0,给我了相信TypeScript可以成为主流编程语言的可能以及值得去学习的信心。

我认为是时候开始一个小的项目(下面会贴出来)并且开始体验TypeScript的特性了。

当开始创建上面我说过的项目并且开始写这篇文章的时候,我浏览过大量的"介绍TypeScript"的文章。这里我不想写成和他们类似文章,这些文章有相应的定位,而且在事实上,我使用它们来开始我的TypeScript 旅程。无论如何,我想使用一个不同的视角——我想回到看这篇文章读者的位置,回答某些问题的答案和当我开始关注TypeScript项目的时候在我脑中的一些问题:

  1. 为什么你应该在下一个web或者移动项目中使用TypeScript ?
  2. 什么让TypeScript看起来如此美好——如何使你的工作更加简单并且使项目质量提高?
  3. 回到TypeScript本身,它是如何给javascript加上语法糖以及这些特性?

TypeScript可以比我自己创建更好的JavaScript

more >>

ajaxfileupload.js 原理、常见错误及注意事项

刚刚接到一个BUG任务,在IE8中使用ajaxfileupload组件无法上传文件到服务器,根据单步调试(IE的单步调试还是比较有用)并分析了ajaxfileupload组件。

问题
组件抛出错误为“拒绝访问”,使用控制台发现数据已经返回,服务器上已经成功上传,但是客户端无法获取到结果,因此提示上传失败。

QQ Photo20150513194835.jpg

使用该组件

下载该组件 点击下载

$.ajaxFileUpload({
    url: 'upload.php', //上传地址,需要注意跨域问题
    secureuri: false,
    data: data,
    fileElementId: 'fileToUpload', //该上传input 的ID
    dataType: 'json',
    success: function (data) {
        alert(data.msg);

    },
    error: function (data) {
        alert("error");
    }
});

more >>

nodejs 框架express重要接口思维导图

express() 程序入口,启动一个应用,返回application对象
Application 对象
    简介:app应用单例
    app.set(name, value) 设置应用
    app.get(name) 获取应用设置
    app.enable(name) 启用一项设置
    app.disable(name) 禁用一项设置
    app.use([path], function) 使用中间件方法
    settings 可配置项
        env 运行时环境,默认为 process.env.NODE_ENV 或者 "development"
        trust proxy 激活反向代理,默认未激活状态
        jsonp callback name 修改默认?callback=的jsonp回调的名字
        json replacer JSON replacer 替换时的回调, 默认为null
        json spaces JSON 响应的空格数量,开发环境下是2 , 生产环境是0
        case sensitive routing 路由的大小写敏感, 默认是关闭状态, "/Foo" 和"/foo" 是一样的
        strict routing 路由的严格格式, 默认情况下 "/foo" 和 "/foo/" 是被同样对待的
        view cache 模板缓存,在生产环境中是默认开启的
        view engine 模板引擎
        views 模板的目录, 默认是"process.cwd() + ./views"
    app.engine(ext, callback) 模板引擎
    app.param([name], callback) 实现路由方法
    app.VERB(path, [callback...], callback)  根据请求头部类型快捷实现路由方法
    app.all(path, [callback...], callback) 响应所有的路由请求
    app.locals 放置用于渲染给模板的变量对象
    app.render(view, [options], callback) 渲染模板
    app.routes 存放实现的路由方法列表
    app.listen() 启动http监听
Request 对象
    简介:用于存放客户端发起的请求信息
    req.params 例如路由/user/:name 相似的参数表
    req.query urlget 参数
    req.body 请求体参数
    req.files  bodyParser() 中间件提供 的文件上传后的参数体
    req.param(name) 获取参数通用方法
        请求优先级 req.params > req.body > req.query
    req.route 请求的路由信息
    req.cookies  请求的cookie
    req.get(field) 获取头部字段
    req.accepts(types) 获取客户端接收类型
    req.is(type)  头部类型
    req.ip  返回IP注意代理的情况
    req.ips 返回IP和代理IP数组
    req.path 请求路径
    req.host
    req.xhr 是否是ajax请求
    req.protocol 请求协议
    req.subdomains 获取子域
    req.originalUrl 获取url
    req.acceptedCharsets 获取请求字符集
Response 响应客户端对象
    res.status(code) 返回响应码
    res.set(field, [value]) 设置头部
    res.get(field) 获取响应头部信息
    res.cookie(name, value, [options]) 返回cookie
    res.clearCookie(name, [options]) 清除cookie
    res.redirect([status], url)  res.location  重定向
    res.charset 设置字符集
    res.send([body|status], [body]) 发送响应数据
    res.json([status|body], [body]) 
    res.jsonp([status|body], [body])
    res.attachment([filename]) 设置响应类型为附件,系统根据后缀名自动设置http类型
    res.sendfile(path, [options], [fn]]) 发送文件
    res.download(path, [filename], [fn]) 下载
    res.render(view, [locals], callback) 渲染模板
重要的几个中间中间件
    basicAuth()  用户验证
    bodyParser() 请求体解析 对几个常用的中间件再封装
        json()
         urlencoded()
        multipart() 
    compress() 压缩
    cookieParser() cookies解析
    cookieSession() 利用cookies实现的session
    csrf() CSRF 防护中间件
    directory() 目录解析中间件
其他常用模块
    path nodejs提供
    static-favicon icon模块
    morgan 日志模块
    connect-mongo mongodb 模块
    connect-flash 用户提示消息模块
    multer 比较重要的模块,用于文件上传

more >>

JavaScript作用域练习题总结

1、var的含义是什么?下面函数f1中两行代码有什么区别?

    function f1() {
        var a = 10; 
        b = 10;
    }

解析:var 是变量声明语句,=是赋值语句。第一行和第二行的区别为一个是变量声明和赋值,第二个缺省了变量申明的赋值,如果在严格模式下,为一个没有声明的变量赋值就会报错,而在非严格模式下解释器就会自动写入一个元素到window。

2、控制台输出什么内容?

    function f1() {
        var a ;
        function f2() {
            a = 5;
            b = 6;
        }
    }
    f2();
    console.log(a);
    console.log(b);

解析:抛出异常,6。根据作用域的原理。变量a 被申明但是在f1 内部,f2给a赋值的时候a能够找到于是a在f1作用域下被赋值,而在引用a的时候a在全局下没有被申明。b没有被声明过,因此在全局下被自动声明(非严格模式)。因此得出,不能说没有使用var 就是全局变量,使用了var 就是局部变量。

more >>

Angularjs学习笔记脑图

angularjs

angularjs.jpg
1、第一章 angularjs简介

客户端模板:html 模板

MVC:Model View Controller

数据绑定:模板和上的值和变量绑定

依赖注入:通过应用需要的东西,而不必再创建一次的一种模块化机制

指令:用户增加VIEW层功能的拓展html 标签

more >>

javascript 从去重到排序的考量

写这篇文章的原因是因为在某个简单的问题上翻船,往往高手和新手的区别就在于看似平常的地方,一直以来都在思考高手和新手的本质区别,高手绝非工作经验和工作时间的堆积造就的,10年工作经验的人也许是1年工作经验用了十年也不一定。

这里有一道题目,是这样:数组去重、并按倒数第二个字母排序

这个问题实在是非常简单
去重:定义一个新的数组,取出原数组的元素,依次放入新的数组,放入之前需要检查是否在新的数组已经存在即可。
排序:使用数组的sort()方法,javascript 默认使用冒泡排序,只需要传入2个元素的比较结果即可,按照题目,只需要取出字母,然后比较即可。
于是得到代码:

function uniqe(arr){
var tmp = {};
var result = [];
for(var i = 0,len = arr.length;i < len;i ++){
    var item = arr[i];
    if(item in tmp){
        continue;
    }
    result.push(item);
}
return result.sort(function(a,b){
    return a.charCodeAt(a.length-2) - b.charCodeAt(b.length-2);
});

}

var arr =['hello','world','nodejs','javascript',
'html','world','css','flash','adobe','java','hello'];
uniqe(arr)

那么我们把这个问题继续简化!!数字数组去重、并排序。
看这个问题是否更加简单?但是等等,这种基础函数,一般都需要承载丰富的业务逻辑,被大量引用,也许是在循环等复杂的逻辑中,因此要求足够健壮、高效。我们不仅需要检查输入还需要选择更好算法,解决这个问题的思路应该是:step1 排序 setp2 查找 step3 去重

more >>