浏览模式: 标准 | 列表

 用过 gulp 的用户可能都知道 gulp-concat 和 gulp-uglify 这两个插件,一个用于合并文件,另一个用于对 js 进行语法压缩。虽然通过文件合并和语法压缩可以有效的减小 js 文件的体积,但是对于比较大的 js 文件仍然还有很大的空间可以继续进行压缩。为了达到这个目的,我做了这个 gulp-lzmajs 插件,并在实际应用中将仅使用 gulp-concat 和 gulp-uglify 压缩之后有 60 KB左右的 js 文件通过 gulp-lzmajs 进一步压缩到只有 20KB 左右。对于更大的文件,当然效果会更好。

» 阅读全文

最近要给 PHPRPC 站做文档,打算使用 Wiki 系统,为了便于网站搬家和方便用户下载文档,所以选择了 TiddlyWiki,TiddlyWiki 是一个纯 HTML 的 Wiki 系统,而且支持插件,超级棒!不过从网上找了 2 天,也没有找到合适的代码加亮插件,有一个 Plugin: Syntaxify 只支持 css,js 和 xml,而且效果还不是很理想。正好想到有个 dp.SyntaxHighlighter 项目是纯 js 实现的代码加亮库,于是就决定用它来做一个 TiddlyWiki 的代码加亮插件了。我搜集了目前我能找到的所有支持用 dp.SyntaxHighlighter 加亮的语言文件(shBrush*.js),所以这个插件支持的语言比 dp.SyntaxHighlighter官方提供的还要多,支持的语言(包含别名)有:

as, as3, actionscript, bash, sh, batch, dos, coldfusion, cf, cpp, c, c++, c#, c-sharp, csharp, css, delphi, pascal, java, js, jscript, javascript, lua, mxml, perl, php, py, python, ruby, rails, ror, sql, vb, vb.net, xml, xhtml, xslt, html

» 阅读全文

这两天做基于 Flash9(ActionScript 3.0)的 JavaScript PHPRPC 3.0 客户端时遇到了一些 JavaScript 与 ActionScript 3.0 交互的一些问题,这些问题在网上基本上都没有找到答案,最后通过不断的尝试才得以解决,因此在这里总结出来,希望能给遇到同样问题的同志们一些帮助。

JavaScript 跟 ActionScript 3.0 交互也是通过 flash.external.ExternalInterface 这个类,不过与跟 Flash 8 中跟 ActionScript 2.0 交互所使用的 flash.external.ExternalInterface 还是有所不同的。最大的不同就是 ExternalInterface.addCallback 方法在 ActionScript 3.0 中只有 2 个参数了,而不再有 instance 这个参数。下面要讨论的这些问题都是关于 Flash 9 中 ActionScript 3.0 的。

先来说最常遇到的问题,就是在 JavaScript 调用 Flash 中的 ActionScript 方法时报告该方法不存在。这个问题是跟 Flash 中执行 ExternalInterface.addCallback 的时间有关的,ExternalInterface.addCallback 必须要在 HTML 的完全载入之后也就是 window.onload 事件执行后才可以执行,否则,它所发布的方法都无法在 JavaScript 中调用。

解决这个问题的方法在 Flash 9 的 ActionScript 3.0 帮助中有个例子,里面包含了这个解决方法,就是首先在 js 中设置两个标志,例如 jsReady 和 swfReady 这两个变量作为标志,开始都设置为 false,当 window.onload 时,设置 jsReady 为 true,在 Flash 中一开始检查 JavaScript 中的这个 jsReady 标志是否是 true(通过 ExternalInterface.call 方法调用 JavaScript 中的返回这个标志的一个函数),如果不为 true,就设置一个定时器,经过一段时间后(例如 50 或 100 毫秒)重复这个检查这个标志,一旦为 true,则执行 ExternalInterface.addCallback 来发布 ActionScript 要提供给 JavaScript 调用的函数或方法,执行完所有的 ExternalInterface.addCallback 后,通过 ExternalInterface.call 方法调用 JavaScript 中的设置 swfReady 标志的函数设置 swfReady 为 true。之后,当 JavaScript 检测到 swfReady 为 true 后,再调用 ActionScript 中的方法就不会遇到上的说的这个问题了。

如果简单一点的调用这样还可以,如果是有好多这样的调用就比较麻烦了。我是通过建立两个执行队列:jsTaskQueue 和 swfTaskQueue,当在 jsReady 为 true 之前,如果有要调用 ActionScript 的操作,就把这个操作放到 jsTaskQueue 中,当 js 在 window.onload 中执行设置 jsReady 时,把这个队列中的任务取出来执行,当 jsReady 为 true 后 swfReady 为 true 之前,如果有要调用 ActionScript 的操作,就把这个操作放到 swfTaskQueue 中,当 ActionScript 通过 ExternalInterface.call 方法调用 JavaScript 中的设置 swfReady 标志的函数设置 swfReady 为 true 时,把这个队列中的任务取出来执行。当 jsReady 和 swfReady 都为 true 时,那么如果有要调用 ActionScript 的操作,直接运行就可以了。通过这种方法把这些任务封装后,使用这些封装之后的操作,在编写代码就可以按照顺序(而不是异步)来写了,执行时也是顺序执行啦。

除了这个最常遇到的问题之外,还有两个关于 IE 上的问题。

如果你是通过 JavaScript 动态创建的 Flash 标签然后插入到 html 中的话(例如通过 innerHTML 赋值的方法或者 appendChild 的方法),很可能你这个操作是在 window.onload 之后才进行,在这种情况下,其它浏览器可以正常进行 JavaScript 和 ActionScript 3.0 的交互,IE 就不行。所以,为了保险,最好的方法就是直接把 flash 标签的 html 写在 html 的 body 中,或者用 JavaScript 的 document.write 来写入 html 的 body 中,后面这种方法对于 IE 来说更合适一些,因为这样的话,可以不需要点击激活 Flash。

另一个问题是,不要在 ActionScript 中发布名字为 invoke 的方法,否则在 IE 中,JavaScript 调用该方法时会出错。

最后一个问题,网上可以查到的比较多了,就是不要把 flash 放到 form 中,否则在 IE 中,JavaScript 调用 ActionScript 时会出错。当然,网上也给出了一个解决这个问题的脚本,不过那个貌似是针对 Flash 8 的 ActionScript 2.0 的,我没有试过,不知道对 ActionScript 3.0 是否同样有效。


11 月 23 日补充:

今天又发现一个问题,如果在 ActionScript 中通过 ExternalInterface.call 调用 JavaScript 时,如果传递的参数有字符串,那么字符串中如果包含 \ 符号的话,那么将会调用失败。这个也是 ActionScript 和 JavaScript 交互的一个 bug,解决办法是,对传递的字符串先进行一下处理在传递,处理方法很简单,比如要传递的数据是 data,将它进行一次 data.replace(/\\/, “\\\\”) 替换之后,在传递给 JavaScript 就可以了。

» 阅读全文

前面我们讨论了如何在 JavaScript 语言中实现对私有实例成员、公有实例成员、私有静态成员、公有静态成员和静态类的封装。这次我们来讨论一下面向对象程序设计中的另外两个要素:继承与多态。 本次讨论中,主要涉及到定义和赋值,this 和执行上下文,原型继承和调用继承,以及重载和覆盖这么几个方面的内容。

» 阅读全文

JavaScript 是一种非常灵活的面向对象程序设计语言,它与传统的强类型的面向对象程序设计语言(如 C++,Java,C# 等)有很大不同,所以要实现如 C++、java、C# 当中的一些特性就需要换一种思考方式来解决。今天主要讨论如何在 JavaScript 脚本中实现数据的封装(encapsulation)。

数据封装说的简单点就是把不希望调用者看见的内容隐藏起来。它是面向对象程序设计的三要素之首,其它两个是继承和多态,关于它们的内容在后面再讨论。

本文主要讨论的是在 JavaScript 面向对象程序设计中,对私有实例成员、公有实例成员、公有静态成员、私有静态成员和静态类的封装办法。

» 阅读全文