realazy


Bookmarklet

按照维基的定义,A bookmarklet is an applet, a small computer application, stored as the URL of a bookmark in a web browser or as a hyperlink on a web page. 最近,它在一些新兴的网站中比较流行,比如 facebook, friendfeed. 从技术角度来看,它通常是一段来自提供方的可执行 JavaScript, 用以捕获当前网页的某些元素如标题、图片等以加强当前网页与提供方网站之间的交互。

那么,从技术角度来说,bookmarklet 有什么需要注意的呢?我个人意见如下:

首先,因为它是一段 JavaScript, 所以应该遵循普世的 JavaScript 编程原则。最重要的一点是,不要污染当前网页的命名空间,否则可能会破坏当前网页的 JavaScript. 通常,可以使用闭包来隐藏你所有的变量。同样,如果您的 bookmarklet 的 CSS 可能会入侵当前网页(很遗憾,CSS 没有命名空间,也没有类似闭包的东西,很容易就会冲突),那么请考虑将 bookmarklet 的内容放到 iframe 中去。

其次,防止函数执行后不经意的副作用,一个比较好用的贴士是,使用不返回值始终返回 undefinedvoid, 它可以接受任何参数,因此,把你的闭包放到 void 中是个不错的主意:

javascript:void((function(){...})());

最后,有一个比较恼火的问题也需要加以注意。目前世界上最流行的浏览器,IE6, 它对 bookmarklet 所能容忍的长度仅为 508!

11 Responses to “Bookmarklet”

  1. 家儒 Says:

    希望了解更多 ^^

  2. Lunatic Sun Says:

    许多bookmarklet都使用void操作符,将可能的表达式返回值设置为undefined。如

    javascript: void ( var i = 0 ) ;

    但是在我测试时发现除了显性的使用return语句返回值以外的情况都不会产生返回值的情况,我不知道是不是因为我测试使用的浏览器都是21世纪的浏览器的关系。

  3. realazy Says:

    @Lunatic Sun 比如 window.open,如果不使用 void, 就得到返回的 window 对象。

    另外,你所举的例子有语法错误。

  4. Lunatic Sun Says:

    @realazy – 那句代码应该是javascript : void(i = 0),谢谢!

    另外我的意思是当你使用闭包的时候,如

    javascript : (function(){
    window.open();
    })();

    并不会产生返回值,因为在函数中除非你使用return语句,否则函数都将返回undefined。因此只要匿名函数没有返回值,就不需要使用void操作符。

    使用void操作符的正确原因在于那些会直接返回值的语句,如

    javascript : i = 0;

    这条代码将在document中写下0

  5. sv Says:

    其实这种也很常见,把它bookmark起来的想法倒是很新颖。在你的blog上潜了N久的水,都没怎么留言过,不好意思。特推荐个bookmarklet—-Javascrip Dom Inspector: javascript:void(z=document.body.appendChild(document.createElement(‘script’)));void(z.language=’javascript’);void(z.type=’text/javascript’);void(z.src=’http://slayeroffice.com/tools/modi/modi.js’);void(z.id=’modi’);
    Check it out & bookmark it ;-)

  6. FLY Says:

    对于这方面了解的倒是不多。
    只是在互联网上这种应该算是web2.0类型的吧
    只知道概念,对于技术层面还不是很了解。

  7. hax Says:

    使用void的原因除了保持一致(即使对于不返回值的function也用void)之外,还有一个原因是void会强制function成为function表达式而不是function声明。例如:
    function(){}()
    这个语法是错误的。你必须写成:
    (function(){})()
    即用括号来强制得到一个function表达式,而:
    void function(){}()
    这个语法是正确的(虽然有极少数引擎会报错,那是它们的实现bug)。
    所以realazy同志给出的格式太过繁琐了,可以去掉两对括号。我们应该更lazy一点呵呵。
    这也是为什么有些人喜欢用new function(){…},因为它连后面的一对括号也可以省略掉。如果我们使用function的唯一目的是为了建立一个封闭的Scope以便控制对全局命名空间的污染,那么我们总会倾向于最简单,最少视觉干扰的方案。
    最后关于ie的长度限制,我给个稍有点无赖的解决方案,那就是在bookmarklet中给文档插入新的标签,loading你的网站的脚本,呵呵。

  8. hax Says:

    最后那个,我是指插入script标签。反正script标签没有domain的限制。不过这也说明bookmarklet是可以用来干坏事的,所以安装bookmarklet的时候也要小心。

  9. lone Says:

    看了realazy给的文档,觉得恰当的写法应该是:
    javascript:void(function(){}());
    还有,关于hax的”例如:
    function(){}()
    这个语法是错误的。你必须写成:
    (function(){})()”
    写成(function(){}())”是一样的,只要得到的是表达式就可以了~

  10. fdcn Says:

    lone,你沒有仔細看hax寫的東西,他從來沒用function(){}(),他寫的是:
    void function(){}()

  11. Bookmarklet - 小书签,实用浏览器小工具补完 — 绿色软件联盟 Says:

    [...] 另外 realazy 的文章在讨论写 bookmarklet 的注意点。 [...]

Leave a Reply


realazy (懒到死) is proudly powered by WordPress | Entries (RSS) and Comments (RSS)