Backbone源码研究 – Backbone.Model

前言

都因为 IE8 不支持 Object.defineProperty,但是业务还不能脱离 IE7 和 IE8,故研究下 Backbone.Model 的实现机制,找机会给主流的 MVVM 框架补丁

伪代码

先来看看 Model 的构造函数

很简单的代码,做了一些初始化赋值的事情。

用到了一个小技巧  attrs = _.defaults(_.extend({}, defaults, attrs), defaults);  来防止误传入的 undefined 覆盖掉默认的 defaults 值。

Backbone 的精粹都在 set(){} 这个函数里面。

整个 set 里面,实际干活的就是 unset ? delete current[attr] : current[attr] = val;  。

没看明白 this._changing 和 this._pending 的使用场景,感觉是一个当多个 set 同时执行时候的一个标记位,但是 JS 是单线程执行,里面又都是 for 语句,按理说可以不用这两个标记位。又或者是我的理解有误。

more

看到这,给各种Observer打补丁就有了可行性,支持 Object.defineProperty 就用 Object.defineProperty,不支持的则降级到走 Backbone 的这种 for in 方式。

JS常用库解密-FastClick

众所周知,移动端在处理点击事件的时候,会有300毫秒的延迟。恰恰是这300毫秒的延迟,会让人有一种卡顿的体验。

这300毫秒的原因,在于早期浏览器的实现中,浏览器不知道用户触摸后,到底想做什么,所以故意等待300毫秒,再触发click事件。

既然我们已经知道了原因了,怎么解决呢?

方案1-粗暴治标法

因为浏览器对click事件的处理,有300ms的延迟,而touchstart几乎是立即执行的,估将所有click事件的监听,改为touchstart事件的监听,即可消除这300ms的延迟。

但这样副作用也很大,移动端的交互体验全靠触摸,touchstart将会干扰其他交互行为的处理,例如滚动、拖拽等。

方案2-模拟修复法

既然浏览器有这300ms的延迟,那么我们来代替浏览器判断,手动触发click事件,这也是fastClick的解决方案。

fastClick的核心代码

这里可以看到,FastClick在touchEnd的时候,在符合条件的情况下,主动触发了click事件,这样避免了浏览器默认的300毫秒等待判断。为了防止原生的click被触发,这里还通过event.preventDefault()屏蔽了原生的click事件。

我们来看看他是怎么模拟click事件的

我们在网上搜索fastClick,大部分都在说他解决了zepto的点击穿透问题,他是怎么解决的呢?就是上面最后一句,他模拟的click事件是在touchEnd获取的真实元素上触发的,而不是通过坐标计算出来的元素。

最后,原理虽简单,但还是建议大家直接用FastClick而不是自己再实现一个。因为,你看他源码里面的注释,有很多特殊情况的补丁的,自己实现一个精简版难免会漏这漏那。

getBoundingClientRect

今天fix一个拖拽库的IE8bug,发现DOM元素有一个getBoundingClientRect的方法。

  • 这一个JS原生方法
  • 这是一个从IE私有API演变过来的标准API
  • 这个方法可以获取矩形目标元素四条边相对于文档视图(DocumentView)左上角的距离

也就是说,可以很简单的通过这个方法,获取元素相对于浏览器的坐标、元素自身宽高尺寸等

参考:

Framework7源码学习-1-概览

源码打包地址:

https://raw.githubusercontent.com/qq286735628/Framework7/master/dist/js/framework7.js

整个Framework7框架,由Framework7核心代码、jQuery风格的DOM操作库、DOM选择器、DOM操作辅助工具、Ajax这五部分组成。

纵观

整个库文件,通过最外层的匿名函数 (function(){})() 进行封装,防止内部变量污染全局。

使用 window.Framework7 = function(){} 方式暴露Framework7这个构造函数给外部使用。

其DOM操作和Ajax部分,采用仿jQuery的风格,最大程度减少开发者学习成本。

通过上面的代码片段,可以看到,一个JS框架,主要由框架核心代码,DOM操作,Ajax操作这三部分组成。由于jQuery的占有率非常高,很多人的JS操作习惯,实际上是jQuery操作习惯,故大部分的框架,其DOM操作和Ajax操作都会去模仿jQuery的风格。

Framework7核心

上面代码,可以看到一个简单的JS构造函数的写法。

通过 var app = this 这种别名方式,来保存this。

通过 for in 循环,来实现带参数初始化。

通过结尾的 return app ,来返回一个对象实例,供外部采用 new Framework7() 初始化的时候使用。

JS中的attribute和property

每一个dom节点,都有各自的attributes和properties。这两者很容易用混,尤其是在表单元素上面。

Property

每一个DOM节点,都是一个对象。像其他JS对象一样,DOM节点这类型HTMLElement对象,也可以添加一些方法或者属性。这些自定义添加的属性,就是property。它只能被JS所读取,并不会影响HTML的展示。(它能被JS的for-in方法遍历出来,但innerHTML里面不会显示)

properties

Attribute

与Property不同,Attribute会DOM节点上显示出来,但不会在DOM对象中被for-in遍历出来。

attribute

例如上图的input标签,他的Attributies包括value,type,name,id。

attributies

想操作DOM元素的的attribute,得依靠下列的JS接口

需要注意的是

  • 由于Attribute会显示在DOM上面,所以它的键名不区分大小写
  • 它的值只可以是字符串

Attribute与Property之间的同步

继续阅读“JS中的attribute和property”

《Node.js开发指南》翻阅笔记

第一天上班,配套的电脑居然没有到货,无聊了一天,就把《Node.js开发指南》拿出来翻了一下。

下面是今天的一些笔记,Node.js自身的特性对我来说暂时意义不大,所以讨论的不多,主要是记录一些开发流程这些外围的信息。

javascript规范

CommonJS:该规范涉及模块、包、系统、二进制、控制台、编码、文件系统、套接字、单元测试。拟补了ECMAScript没有约定的领域。

平台支持

win、mac、linux全平台支持。win平台cmd通过Node命令进入Node.js的交互模式。

npm

Node.js的包管理工具。通过包管理可以安装一些例如express这样的轻量级的web application框架。

Web服务方式

传统的LAMP方式是浏览器发起http请求,由Apache对其作出响应,并把请求交给php解析器来处理。

而Node.js则是启动一个进程,独占一个端口,所有指向该端口的请求都有这个Node.js进程处理。

因为端口是被进程独占的,想使用虚拟主机服务,还是得使用Apache/Nginx这类软件来统一处理请求,然后根据虚拟主机的规则,再分发到各个Node.js的进程中。

在这个方面,Node.js和PHP差不多,PHP现在也支持内置Web服务。也许未来,npm里面会出现一款包是专门管理虚拟主机的,这样就省掉了Apache/Nginx。

结语

Node.js让前端工程师手伸向了后端和客户端,给有理想的开发者们多了一把有利的扳手。

《Node.js开发指南》

最近弄HybridApp的一些心得

SDK的项目折腾了一个月,终于快到收获的时候,把这过程中的一些心得体会记录一下吧~

manifest并不是很好用

资源文件的更新,是在浏览器下次刷新的时候才会生效。

包含manifest的Html主文件默认会被缓存,类型是Master Explicit。

在测试的时候,我还发现,Master Explicit的更新机制,和其他资源文件并不完全相同,有时候修改manifest文件,浏览器不更新主Html文件。所以我平时都干脆把主Html文件,也放入到manifest的cache列表中,保证最多两次刷新浏览器,主Html文件可以得到更新。

建议:

如果想用好manifest机制来做离线缓存功能,最好手动把applicationCache对象中的缓存更新、刷新浏览器的功能实现,便于日后文件更新,相关信息可以看以前的文章

Hybrid App的离线功能,还可以配合localStorage、WebViewCache等搭配实现,可控性更佳。

Hybrid App测试不容易

因为我没做个原生App的开发,对Eclipse不熟练,App底层的那套测试方法我都不懂,就自己琢磨出一种测试的方法。

JS解耦测试:

把JS流程中的很多判断条件,统统写在js的公共变量里面,这样的话,js脱离native环境,可以通过浏览器来修改每个公共变量,来模拟App的各种事件。

善用浏览器中的中端、单步、Profiles等测试功能,做到在与Native整合的之前,就测试好大部分的js代码。

20120903215940.png

JavaScript,一切皆对象

估计说出来也没多少人相信,在项目开始之前,我几乎没有写原生JS的经验。不过,人的潜能总是被逼出来的,一个月下来,我从最简单的写过程JS,到现在掌握了对象的继承等。

在JavaScript的世界中,一切皆对象(请允许我装13一下),但是,这里的对象,并不是我们平常所说的类的实例化后的对象。

20120903220537.png

从上面的截图可以看到,定义一个空对象obj,它的prototype是Object。JavaScript的继承都是通过对象的prototype来实现的。

Private Methods的实现:

在一个闭包空间里面,通过 function __privateFunc() {}来定义私有方法。公共方法使用上面的方法暴露给window。

对于JavaScript的感触,还有很多很多,下次再开篇文章来写写吧。

小项目里面的大内涵

最近一直在用PHP来做东西~

一个很简单的应用:用户系统~

知识储备:

1、PHP基础(语法规则)

2、PHP与MySQL连接函数

3、SQL语句

4、前端工程师所需的一些技能

5、系统安全问题

看上去好像很高深,其实也不是特别高深,一点一点的说吧~

 

PHP基础这部分,没什么说的

文件格式*.php,

<?php 把程序写在这里面,写法和CC++差不多 ;?>

 

PHP与MySQL连接这一部分,主要就几个PHP函数而已

mysql_connect() – 连接数据库

mysql_select_db() – 选择数据库

mysql_query() – 执行SQL查询

mysql_fetch_array() – 抓取查询结果,生成数组

 

SQL语句

额~因为我从没系统的看过,所以实施的时候总是出这样那样的语法问题,尤其是对 ‘ “ . ` 这些个符号的使用,非常混乱~

要用的时候,可以使用PhpMyAdmin里面,看看别人的SQL语句是怎样用的~

还是不在这误人子弟了~

 

为什么说要有一些前端工程师的技能呢?

首先嘛,这个用户注册,登录界面可是用户对整个站点的第一印象~

其次,我们来看看twitter的界面、Tumblr的界面等,里面用到某些行为,非常形象生动,给人很好的感觉,让整个站点马上体现出一种“炫”~

 

万事都说安全第一,网站也不例外~

做任何系统,都不要相信用户的输入(@http://rockux.com 还教我们不要相信javascript,具体该怎么做自己想吧)~

必须要对用户的输入进行处理,才可以执行、或者存储,否则,神马跨站攻击、神马SQL注入攻击,烂摊子不好收拾~

一个比较基本的处理,PHP的魔术引号,详情请看:传送门

 

做人做事要“眼高手低”,万丈高楼平地起,just do it~