nodePPT使用nodejs写的,可以手机端控制pc端的演示文档框架。nodePPT是在webSlide基础上二次开发的,使用nodejs做服务器,通过websocket来实现手机端和PC的通信,主要功能是手机端可以控制pc端PPT播放进度,并且手机端可以给每张PPT做备注。
第一次做个程序的nodejs作品,并且测试时间比较短,肯定会有很多问题和bug,希望大家一起斧正。另外页面样式css高手可以自己写,包括动画自定义都可以在css文件中直接修改添加。
说明
因为是PPT演示文档,所以需要投影仪分辨率,所以演示页面的最佳分辨率为全屏模式下的 1024*768 ,如果在自己电脑上查看,可以通过 ctrl + - 和 ctrl + + 缩放到合适的比例查看效果。
建议浏览器chrome 16+,全屏模式(F11),以达到最佳动画效果。在Firefox下会出现拖尾现象,个人认为是Firefox 8下对CSS3动画效果渲染太慢导致,其他浏览器未测试。

nodePPT iphone手机端截图
使用说明
- 配置route.json
- 配置ppt的文件
- 启动node:node server.js
- PC访问:如127.0.0.1:3000/demo.ppt
- 手机端访问:127.0.0.1:3000/ctrl
- 手机端setup,选择控制用户后,开始控制
具体使用方法启动node server.js之后访问127.0.0.1:3000/index.ppt,里面有详细的介绍
快捷键
- 空格/→/↓/Tab/pageDown:下一页
- ←/↑/pageUp:上一页
- P:开画板
- C:清除画板
版本库地址
继续阅读全文……
昨天无意中看到一篇老外的文章,文章提到了addEventListener第二个参数可以传入object,并且对象中handleEvent为事件处理函数。例如下面的javascript代码:
var obj = {
handleEvent: function() {
alert('body clicked');
}
};
document.body.addEventListener('click',obj,false);
测试发现这段代码在IE9+,chrome,FF,opera等浏览器是正确的(测试范围可能不够宽),而且可以成功的绑定click事件。在Qwrap群里一问才知道是DOM2中接口,很有意思的一个发现,@貘大大 也发微博说自己先入为主了,我相信很多人跟@貘大大 一样都先入为主了。
addEventListener的handleEvent应用
发现了这个“新大陆”有什么用法呢?哈哈~首先想到的是对象引用。看下面的javascript代码:
<script type="text/javascript">
var obj = {
handleEvent: function() {
alert('body clicked');
}
};
document.body.addEventListener('click',obj,false);
function fn2(){
obj.handleEvent = function(){
alert('fn2');
};
}
</script>
<button onclick="fn2();">change</button>
因为对象的引用关系,点击下button就可以切换绑定事件的处理函数,而不需要remove之前的事件,然后重新绑定一个新的处理函数。
继续阅读全文……
互联网公司内部难免会有些技术分享之类的活动,需要用到PPT,前端开发工程师都喜欢自己的PPT帅一点,当然我也一样。于是开始用impress.js做PPT,所以有了上一篇PPT《XSS注入和防范》。不过在用的过程中发现impress.js性能有问题,假如页面太多,或者图片太多,就会出现卡的现象。于是开始琢磨自己写个javascript演示文档框架。嗯,于是webSlide就诞生了!
webSlide是用于在线PPT演示文档的javascript框架
鸣谢
webSlide的想法来自于impress.js,但是本人在使用过程中发现impress.js经常卡,尤其是当演示文档页面和图片比较多之时,经常出现动画效果不流畅。
写webSlide代码过程中,研究过impress.js和reveal.js,向两位作者表示感谢。
演示页面
演示页面地址http://ksky521.github.com/webSlide/,由于页面比较多,所以需要一定的加载时间。
国内可以访问SAE上的演示页面:http://qdemo.sinaapp.com/ppt/udc.htm。
演示页面内容为给公司UDC部门同事进行javascript入门培训的内容~
说明
因为是PPT演示文档,所以需要投影仪分辨率,所以演示页面的最佳分辨率为全屏模式下的 1024*768 ,如果在自己电脑上查看,可以通过 ctrl + - 和 ctrl + + 缩放到合适的比例查看效果。
建议浏览器chrome 16+,全屏模式(F11),以达到最佳动画效果。在Firefox下会出现拖尾现象,个人认为是Firefox 8下对CSS3动画效果渲染太慢导致,其他浏览器未测试。
继续阅读全文……
IE中的contains方法可以判断A元素是否包含B元素,如果包含则返回true,否则返回false,在开发中会在事件代理处理上面用到。W3C的方法是compareDocumentPosition,所以综上来说:JS通过contains和compareDocumentPosition方法来确定DOM节点间的关系,判断一个元素(对象)是否为另一个元素的子元素。
IE的contains方法很简单,但是W3C的DOMElement.contains(DOMNode)方法会返回却是一个数值。
DOMElement.contains(DOMNode)
link:https://developer.mozilla.org/En/DOM/Node.compareDocumentPosition。
DOMElement.contains(DOMNode)返回的不是一个布尔值,而是一个很奇怪的数值,它是通过如下方式累加计算出来的:
| Bits |
Number |
Meaning |
| 000000 |
0 |
元素一致 |
| 000001 |
1 |
节点在不同的文档(或者一个在文档之外) |
| 000010 |
2 |
节点 B 在节点 A 之前 |
| 000100 |
4 |
节点 A 在节点 B 之前 |
| 001000 |
8 |
节点 B 包含节点 A |
| 010000 |
16 |
节点 A 包含节点 B |
| 100000 |
32 |
浏览器的私有使用 |
继续阅读全文……
你尝试过写javascript不用字母和数字吗?最近准备个xss的分享,记起了之前看到过老外一篇文章,内容是关于non-alpha javascript的,拿到代码分析下。
先看这段猥琐的javascript代码:
_=+[];$=_++;__=(_< <_);___=(_<<_)+_;____=__+__;_____=__+___;$$=({}+"")[_____]+({}+"")[_]+({}[$]+"")[_]+(($!=$)+"")[___]+(($==$)+"")[$]+(($==$)+"")[_]+(($==$)+"")[__]+({}+"")[_____]+(($==$)+"")[$]+({}+"")[_]+(($==$)+"")[_];$$$=(($!=$)+"")[_]+(($!=$)+"")[__]+(($==$)+"")[___]+(($==$)+"")[_]+(($==$)+"")[$];$_$=({}+"")[_____]+({}+"")[_]+({}+"")[_]+(($!=$)+"")[__]+({}+"")[__+_____]+({}+"")[_____]+ ({}+"")[_]+({}[$]+"")[__]+(($==$)+"")[___]; ($)[$$][$$]($$$+"('"+$_$+"')")();
看到这里你肯定抓狂了,但是这段代码是可以运行的,运行的结果是 alert('cool code'); 。
javascript分析
这段代码能够运行,原因是javascript是弱类型的脚本语言,而且语法相对松散。例如下面的javascript是正确的,而且是有出乎意料结果的:
继续阅读全文……
前几天看到国外人在github总结的javascript的奇巧淫技(http://t.cn/herRcq),里面对位运算提到的很多,所以来科普一下javascript的位运算。于是找到了w3cschool的这篇教程,很好很强大啊,于是就忍不住转载了……
ECMAScript 整数有两种类型,即有符号整数(允许用正数和负数)和无符号整数(只允许用正数)。在 ECMAScript 中,所有整数字面量默认都是有符号整数,这意味着什么呢?
有符号整数使用 31 位表示整数的数值,用第 32 位表示整数的符号,0 表示正数,1 表示负数。数值范围从 -2147483648 到 2147483647。
可以以两种不同的方式存储二进制形式的有符号整数,一种用于存储正数,一种用于存储负数。正数是以真二进制形式存储的,前 31 位中的每一位都表示 2 的幂,从第 1 位(位 0)开始,表示 20,第 2 位(位 1)表示 21。没用到的位用 0 填充,即忽略不计。例如,下图展示的是数 18 的表示法。

18 的二进制版本只用了前 5 位,它们是这个数字的有效位。把数字转换成二进制字符串,就能看到有效位:
var iNum = 18;
alert(iNum.toString(2)); //输出 "10010"
这段代码只输出 “10010″,而不是 18 的 32 位表示。其他的数位并不重要,因为仅使用前 5 位即可确定这个十进制数值。如下图所示:

负数也存储为二进制代码,不过采用的形式是二进制补码。计算数字二进制补码的步骤有三步:
- 确定该数字的非负版本的二进制表示(例如,要计算 -18的二进制补码,首先要确定 18 的二进制表示)
- 求得二进制反码,即要把 0 替换为 1,把 1 替换为 0
- 在二进制反码上加 1
要确定 -18 的二进制表示,首先必须得到 18 的二进制表示,如下所示:
0000 0000 0000 0000 0000 0000 0001 0010
接下来,计算二进制反码,如下所示:
1111 1111 1111 1111 1111 1111 1110 1101
最后,在二进制反码上加 1,如下所示:
1111 1111 1111 1111 1111 1111 1110 1101
1
---------------------------------------
1111 1111 1111 1111 1111 1111 1110 1110
因此,-18 的二进制表示即 1111 1111 1111 1111 1111 1111 1110 1110。记住,在处理有符号整数时,开发者不能访问 31 位。
有趣的是,把负整数转换成二进制字符串后,ECMAScript 并不以二进制补码的形式显示,而是用数字绝对值的标准二进制代码前面加负号的形式输出。例如:
var iNum = -18;
alert(iNum.toString(2)); //输出 "-10010"
这段代码输出的是 “-10010″,而非二进制补码,这是为避免访问位 31。为了简便,ECMAScript 用一种简单的方式处理整数,使得开发者不必关心它们的用法。
另一方面,无符号整数把最后一位作为另一个数位处理。在这种模式中,第 32 位不表示数字的符号,而是值 231。由于这个额外的位,无符号整数的数值范围为 0 到 4294967295。对于小于 2147483647 的整数来说,无符号整数看来与有符号整数一样,而大于 2147483647 的整数则要使用位 31(在有符号整数中,这一位总是 0)。
把无符号整数转换成字符串后,只返回它们的有效位。
注意:所有整数字面量都默认存储为有符号整数。只有 ECMAScript 的位运算符才能创建无符号整数。
继续阅读全文……
今天处理IE6下的一个bug,经过调试才发现是javascript文件文件总是执行不了,后来中午吃完饭回来才想起以前同事遇见的html中的javascript不可以执行的问题,怀疑是gzip的原因,此次的问题就是因为动态加载javascript文件导致代码不执行,经过研究发现gzip压缩过的javascript文件,如果header里Cache-Control 数据有no-cache, no-store,就会出现IE6中js代码不执行的问题。下面是转发的文章内容:
IE6下面调用开启了gzip压缩Javascript的时候,时常会碰到无法执行的情况,有可能是src调用,有可能是ajax调用,其它的浏览器工作正常,唯独IE6不能正常工作。
出现这个BUG的状况如下:
- 用户使用IE6浏览器
- 服务器没有设置 被请求文件(javascript) expires, cache-control.
- 服务器端开启了chunked encoding模式
- 通过javascrip的src调用方式或者ajax请求javascript文件
- 有可能是通过php生成的javascript文件
- 服务器端开启了gzip压缩
解决这个问题,我们要在服务器的cache-control和expires 头信息上做点工作。
经过测试,header头信息如下的gzip压缩过的javascript调用可以正常工作。
Cache-Control:maxage=1
Connection:keep-alive
Content-Encoding:gzip
Content-Type:application/x-javascript;charset=GBK
Date:Wed, 01 Dec 2010 01:24:07 GMT
Expires:Wed, 01 Dec 2010 01:24:08 GMT
Pragma:public
Server:nginx
Transfer-Encoding:chunked
分析上面的头信息,我们可以注意到:
- cache-control必须要设置成maxage=time的格式,maxage是指定缓存生效时间,1为1秒
- Expires必须要设置,它的时间稍大于Date即可,Date是页面请求时间,Expires是过期时间
- Pragma设置为public
继续阅读全文……
作为前端开发人员,总会有点自己的奇技淫巧,毕竟前端开发不同于后端,代码全部暴漏给用户不说,代码冗余了少则影响带宽,多则效率降低。所以今天我也来爆个自己的奇技淫巧。
javascript的String.replace方法应该javascript前端开发工程师都了解,可是你掌握了吗?replace有接受两个参数,第一个参数可以是字符串,也可以是正则表达式,第二个参数除支持字符串之外,还支持$1形式正则匹配的文本,除此之外还支持传入一个处理函数,这个函数的return值就是要替换成的内容。
了解更多javascript的String.replace用法,访问:http://www.w3school.com.cn/js/jsref_replace.asp
String.replace的妙用
在《javascript获取隐藏dom的宽高》中,我就使用了replace,使用replace做一些重复性的操作,减少不必要的代码。
其实这里说的重复性的工作就是循环!例如,我们要获取假如我要求id为div1和div2的两个元素的宽高,一部分人会一点一点的做,先算完div1的,然后做div2的,这样你是否觉得有部分是充分的操作呢,于是可以将取宽高的函数独立出来,这样多了一个函数,而且函数只用这两次,似乎有点浪费。
于是一部分人想到了使用split切分字符串,然后用Array.forEach做循环。例如下面的代码:
"div1 div2".split(' ').forEach(function(a,i){
console.log(a);
//do something
})
继续阅读全文……
javascript的作用域是一个重要的知识点,javascript作用域(scope)是通过javascript的作用域链(scope chain)来实现的。
javascript作用域
javascript作用域(scope):简单的说,就是创建一个函数时在什么环境下创建的,它控制了javascript代码运行时变量和函数的访问范围。在JavaScript中,变量的作用域有全局作用域和局部作用域两种。
全局作用域(Global Scope)
在代码中任何地方都能访问到的对象拥有全局作用域,注意:全局变量是魔鬼!因为它效率低(后面讲到),污染全局环境!一般有一下三种方式获取全局作用域。
代码最外层定义的函数和变量拥有全局作用域
在代码的最外层,定义的函数、变量,都是拥有全局作用域的。
var a = 1;
function b(){
var a = 2;
}
b();
alert(a);//1
函数内部不使用var定义的拥有全局作用域
在函数内部,不使用var定义的变量拥有全局作用域,这是个坑!要注意,很多前端开发工程师不习惯写var,其实这时候你已经污染了全局作用域!
var a = 1;
function b(){
a = 2;
c = 3;
}
b();
alert(a);//2
alert(c);//3
继续阅读全文……