Javascript继承的一些废话(Mixin)
之前在Prototype库面向对象的实现原理一文里面写过一些关于Javascript实现OO的方法。一些主流的库的OO也都是这么实现的:
不过这种模式有些缺点: Continue reading
果壳网招聘前端工程师
果壳网 guokr.com 是一个新兴的泛科技主题网站。
我们在寻找掌握“正确”的技术与理念的前端开发工程师,负责果壳
我们希望你能大致符合如下描述:
1. 透彻掌握HTML、CSS,对网页标准有成熟的理解 ;
2. 精通JS语法特性和运行机制,乐于探索高级web应用的最佳实践 ;
3. 充分理解前端开发对界面体验、交互设计、可访问性和网站性能的重
工作中我们需要你能:
1. 负责果壳网网页前端开发、前端架构设计与技术性能优化;
2. 与后端开发工程师配合完成产品开发项目,与设计师配合实现产品的
拥有以下任意特点会让你离这份工作更进一步:
1. 对code有一份执着的心态,并有自己喜欢的浏览器bug;
2. 一些著名的JS库,对你来说不只是开发工具,更是你学习架构、风
3. 持续关注业界最新发展,对HTML5、NodeJS等前沿技术与
4. 熟悉或精通前端之外的一或多项技术;
5. 喜欢写博客,分享和记录你的思考或实践;
6. 有自己的开源项目,并不断学习实践新技术。
这些都不是必需的,但如果你全部符合,我们很希望你能给我们一次
对了,我们使用Python、Django、JQuery,如果
模块化CSS
原来写过一篇:更好的组织CSS,里面有一些我当初对于CSS写法的想法。现在这篇文章有些旧了。当初的想法虽然依旧可用,但是有了些改变。于是决定再写一篇。
CSS是完全没有逻辑的语言,可以说它不适合于团队开发。但是我们可以通过一个好的写法避免团队之间的命名冲突、相互依赖等等问题。
注:为了尽量避免js和css之间的开发关联,js的钩子基本采用id,且使用驼峰命名,不得已才会用class。CSS全部使用class作为选择符(不用id),且不适用驼峰命名方式,下面会详细解释class的命名方式。 Continue reading
网页行内排版二三事
《CSS权威指南》是一本好书,不下看了三遍了,每次翻阅依然能有收获。本文只是简单介绍一下网页中的行内样式排版的一些要点。先抛出一些关键字:
- 内容框
- 行内框
- 行框
- 基线
- 行内非替换元素
- 行内替换元素
非IE浏览器的灰阶化
最近网上疯传:“XXX死了”。所以难免过几天又要网站变黑白了。IE下面做到这点很容易,
使用滤镜就可以做到:
javascript代码:
elem.style.filter = 'progid:DXImageTransform.Microsoft.BasicImage(grayscale=1)';
CSS代码:
elem {
filter: progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);
/* Element must "hasLayout"! */
zoom: 1;
}
但是其他浏览器就比较困难了。这需要对图片和其他元素分别处理。对于其他元素比较简单,只要获取他们的color、backgroundColor、borderBottomColor,borderTopColor,borderLeftColor,borderRightColor属性值并且转换成灰阶化之后的值即可。注意这里说的是灰阶化不是去色,两者稍有不同:
// 去色 Desaturate:
function RGBtoDesat(r,g,b) {
var average = (r + g + b) / 3;
return {
r: average,
g: average,
b: average
};
}
// 灰阶化 Grayscale:
function RGBtoGrayscale(r,g,b) {
var mono = parseInt( (0.2125 * r) + (0.7154 * g) + (0.0721 * b), 10 );
return {
r: mono,
g: mono,
b: mono
};
}
所以只要遍历所有的元素,并修改他们的颜色相关属性,原颜色保留方便恢复。
但是图片元素能否被转换依赖于两件事情:
- 浏览器是否支持canvas,以及它的getImageData方法;
- 并且图片是同源的(不跨域)
接下来就需要依次遍历图片所有像素点的颜色值,将其灰阶化。这一过程非常的耗内存,即使是飞速的js引擎遇到了大图片也会消耗不少cpu。
这一切的工作都已经有人做好了:http://james.padolsey.com/demos/grayscale/
grayScal API
grayscale函数支持的参数不仅仅是dom,还可以是jquery对象:
var el = document.getElementById( 'myEl' );
grayscale( el );
// Alternatively, pass a DOM collection
// (all elements will get "grayscaled")
grayscale( document.getElementsByTagName('div') );
// Even works with jQuery collections:
grayscale( $('div') );
重置颜色:
grayscale.reset( el );
// reset() also accepts DOM/jQuery collections
grayscale.reset( $('div') );
prepare函数是用于处理大图片或多张小图片时候的情况,它使用了分时计算的方法防止页面UI卡死。注意图片越大需要的计算时间越多,一个300×300大小的PNG图片在prepare模式下就需要大概3秒时间。所以如果你的图片比较大那么这个方法的生效时间会相当的慢。优点是浏览器不会卡死!
The ‘prepare’ function, as discussed earlier, should be called when there’s a large image to process or even if there are several smaller images. Be aware that larger images will take quite a while to process (just a 300×300 PNG takes about 3 seconds in ‘prepare’ mode).
grayscale.prepare( document.getElementById('myEl') );
// Also accepts DOM/jQuery collections
grayscale.prepare( $('.gall_img') );
另外值得注意一点的是ie下面的灰阶化滤镜会对元素或子元素的其他滤镜产生影响。如果你使用了例如渐变这样的ie滤镜就会被影响:
elem {
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f9fcf7', endColorstr='#e6f4de');
}
所以如果你使用了其他滤镜,那么需要修改下样式。
动画主循环
今天看了下cocos2d-javascript的源代码,说实话代码好乱,可能是和它特殊的打包方式有关。以至于一般的前端代码的读法有些不管用。花了一段时间才发现它的主要动画循环的js:Direct.js。
结果发现cocos2d-javascript里面动画循环代码如下:
/**
* The main loop is triggered again. Call this function only if
* cocos.Directory#stopAnimation was called earlier.
*/
startAnimation: function () {
var animationInterval = 1.0 / this.get('maxFrameRate');
this._animationTimer = setInterval(util.callback(this, 'drawScene'), animationInterval * 1000);
},
它使用了setInterval这个定时器执行动画循环。因为javascript是单线程的,所以如果js的执行时间过长会导致页面卡死,如果是用setInterval,并且间隔时间小于每次计算的时间(js执行时间)那么会导致浏览器没有空隙去渲染ui,也就是界面卡死的情况。
用setInterval的优点是间隔时间是确定的,方便计算位置等参数。
不过这个优点可以忽略不计,毕竟用setTimeout可以防止卡死情况的出现。
当然setTimeout也是由缺陷的。当用户最小化窗口,或者进入另外一个tab的时候,setTimeout和setInterval还是会照样运行!这样会白白消耗内存和cpu。
虽然有些浏览器有优化,比如firefox 5的新特性:后台不活动标签页的 setTimeout 和 setInterval 限定为 1000ms。但是依旧还是在运行!所以我们希望由浏览器来决定什么时候去运行动画,这样即可以减少多余消耗,也可以让动画更刘畅。于是出现 了:requestAnimFrame。它是接受一个回调函数来执行绘制代码。但是由于各个浏览器的支持不一样,所以需要一些优雅降级。
// see http://paulirish.com/2011/requestanimationframe-for-smart-animating/
// shim layer with setTimeout fallback
(function(){
// chrome shipped without the time arg in m10
var timeundefined = false;
if (window.webkitRequestAnimationFrame){
webkitRequestAnimationFrame(function(time){
timeundefined = (time == undefined);
});
}
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
(!timeundefined && window.webkitRequestAnimationFrame) ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback, element){
return window.setTimeout(function(){
callback(+new Date);
}, 1000 / 60);
};
})();
})();
2012年3月28日修改过
不过requestAnimeFrame也有个缺点:就是没有clearTimeout这样对应的函数,所以如果是用于游戏这样的循环代码是没办法从外部打断的。必须是在循环函数内部取消循环。
标准提供了cancelAnimationFrame函数,用于外部打断(感谢mdmeo的提示)。
于是我们可以把游戏里面的主循环代码写成:
window.clearRequestTimeout = function(id) {
window.cancelAnimationFrame ? window.cancelAnimationFrame(id) :
window.webkitCancelAnimationFrame ? window.webkitCancelAnimationFrame(id) :
window.webkitCancelRequestAnimationFrame ? window.webkitCancelRequestAnimationFrame(id) : /* Support for legacy API */
window.mozCancelRequestAnimationFrame ? window.mozCancelRequestAnimationFrame(id) :
window.oCancelRequestAnimationFrame ? window.oCancelRequestAnimationFrame(id) :
window.msCancelRequestAnimationFrame ? window.msCancelRequestAnimationFrame(id) :
clearTimeout(id);
};
function Animation() {
this.animeId;
this.startAnimation = function() {
var self = this;
self.lastTime = +new Date();
self.animeId = requestAnimFrame(function( time ) {
var delayTime = time - self.lastTime;
// doSomething( delayTime ); // do some paint and calculate
console.log( delayTime );
self.startAnimation();
});
},
this.stopAnimation = function() {
clearRequestTimeout( this.animeId );
}
}
参考:
「译」Geolocation HTML5地理定位
参考自:http://html5doctor.com/finding-your-position-with-geolocation/
Geolocation API提供了开发者获取用户位置的功能。接下来介绍下此API的相关信息。
浏览器兼容性
目前(2011-6-22)如下浏览器支持Geolocation API:
- Firefox 3.5+
- Chrome 5.0+
- Safari 5.0+
- Opera 10.60+
- Internet Explorer 9.0+
- Android 2.0+
- iPhone 3.0+
- Opera Mobile 10.1+
- Symbian (S60 3rd & 5th generation)
- Blackberry OS 6
- Maemo
数据保护
此规范会将用户的位置暴露出去,所以需要用户的授权才能够使用。当你使用Geolocation api时,浏览器会提示用户“是否授权”。

地理位置
有很多方法可以定位用户的地理位置,并且每种方法都有不同的精度。桌面浏览器一般会使用WiFi(精确到20m)或者IP定位(只能精确到城市级别,并且有可能是假地址)。移动装置一般会使用GPS(精确到10m并且只能在外部使用),WiFi或GSM/CDMA网络信号定位(精确到1000m)。
使用API
先判断是否有此功能,代码如下:
if (navigator.geolocation) {
// do fancy stuff
}
返回false则不支持此api。
getCurrentPosition 或 watchPosition
这两个方法都是立即返回的,使用的是异步回调的方式来使用api。它们有相同的参数:
successCallback– 成功后的回调函数[errorCallback]– 失败后的回调函数- [options] – 相关配置参数:
enableHighAccuracy– 确保应用会给出最佳结果。这有可能会让浏览器的反应时间变慢。如果是移动装置,还有可能因为使用GPS而消耗更多电量。接受参数类型为boolean,默认为false。timeout– 接受一个数字作为参数,默认为0微秒。设置浏览器的超时时间。maximumAge– 表示程序能接受的被缓存位置的最大过期时间。接受一个数字作为参数,默认为0微秒。这就意味这默认每次获取位置都必需重新获取一个新位置。
clearWatch
这个方法接受一个参数,需要清理的观察进程的id:watchID(这个参数由watchPosition方法返回)。
getCurrentPosition 和 watchPosition方法的主要区别是watchPosition方法会持续告诉你位置的改变,所以基本上它一直在更新用户的位置。当你在移动的时候,这个功能会非常有利于追踪用户的位置。这个函数还会返回一个watchID值被clearWatch使用来停止监控。
当用户的位置被返回,它包含了一个Position对象,它包含了如下属性:
| Property | Details |
|---|---|
| coords.latitude | 十进制表示的纬度值 |
| coords.longitude | 十进制表示的经度值 |
| coords.altitude | 以米为单位的海拔值(reference ellipsoid) |
| coords.accuracy | 以米为单位,告诉应用经纬度值的精确度。这个用于帮助开发者决定是否使用返回的经纬度值。 |
| coords.altitudeAccuracy | 海拔的精确度 |
| coords.heading | 装置的方向,从正北顺时针方向 |
| coords.speed | 装置的移动速度(米每秒) |
| timestamp | 获取位置时候的时间值 |
这些参数中只有coords.latitude, coords.longitude 和 coords.accuracy是保证会有的,其他的值则可能是null。
例子
if (navigator.geolocation) {
var timeoutVal = 10 * 1000 * 1000;
navigator.geolocation.getCurrentPosition(
displayPosition,
displayError,
{ enableHighAccuracy: true, timeout: timeoutVal, maximumAge: 0 }
);
} else {
alert("Geolocation is not supported by this browser");
}
function displayPosition(position) {
alert("Latitude: " + position.coords.latitude + ", Longitude: " + position.coords.longitude);
}
function displayError(error) {
var errors = {
1: 'Permission denied',
2: 'Position unavailable',
3: 'Request timeout'
};
alert("Error: " + errors[error.code]);
}
Demo样例
「译」Cocos2d-javascript入门教程三
我的唠叨:cocos2d-iphone是iOS平台上非常不错的2D游戏引擎,它是基于python版的cocos2d设计的,这里主要说的是它的javascript版。最近打算学习下这个游戏引擎,所以特来翻译下它的相关文档。
相关系列译文:
jQuery 1.6 prop and attr
jQuery 1.6有两个改动使得它不再完全兼容旧版本,虽然说这个改动本质上来说加快了性能,遵循了html5标准,更清晰的分离了API的职责,但是心理总有些不爽,这意味着很多网站不能轻易的升级。
先来看下是哪两个改动: Continue reading
