最短的javascript:地址栏载入脚本代码

不过脚本比较长的时候,需要复制密密麻麻一大段到地址栏里,显得很不美观,而且脚本修改起来也很不容易。因此一般先把脚本写在单独一个文件里,然后用javascript: 的形式动态载入脚本到页面中。不少网页插件都是用这个方法载入。

  平时,我们用最简单的代码实现动态载入:


代码如下:

javascript:var o=document.createElement('script');o.src='...';document.body.appendChild(o);void(0)

  当然,这对于载入插件来说足够OK了。但是不久前看到一个稍有修改的方法,让我开始琢磨这段代码究竟可以压缩到多短!
  他的代码大致相同,只是更严谨:


代码如下:

javascript:(function(o){o.src='...';document.body.appendChild(o)})(document.createElement('script'));void(0)

  虽然代码比先前的还长,但是将变量置于闭包中,避免潜在的冲突。并且将 document.createElement作为闭包的参数,巧妙的节省了一个var单词。
  闲来无事,于是考虑起这代码能否精简再精简。顺便复习下js里面的各种特性。
 当然,首先默认了几个地址栏载入脚本要遵循的规则:
  1. 不引入全局变量
  2. 兼容主流浏览器
  3. 载入过程不影响页面
  > 不影响全局变量,我们需要使用闭包来隐藏我们的私有变量;
  > 兼容主流浏览器,就必须使用标准的方法,兼容性判断只会增加代码长度;
  > 如果简单的使用innerHTML添加元素,就有可能导致存在的元素刷新;
  于是我们开始逐步分析。
  显然,最先想到的就是匿名闭包的调用。
  通常我们都是用: (function(){})() 的形式调用一个匿名闭包。注意红色的优先级括号是必不可缺的,否则就是一个错误的语法。
  但也可以使用另一种形式:+function(){}() 前面的+号可以换成-!~等等一元操作符。不过这仅仅是1字节之差。

  另一个显然的,就是可以把void(0)的参数替换成闭包调用的表达式。void虽然只是个关键字,但有类似函数的功能,对于任何参数都返回undefined。如果没有void,在地址栏执行了javascript:后,页面就变成了脚本表达式返回值,大家应该都见过。
  
  于是经过显而易见的观察,略微减少了3个字符。


代码如下:

javascript:void(+function(o){o.src='...';document.body.appendChild(o)}(document.createElement('script')))

  不过上面都是浅层次的观察。现在我们来仔细的分析。
  
  我们为什么要使用闭包,就是为了防止我们的变量和页面里的冲突。那么可以不使用变量吗?想要不出现变量,唯一办法就是使用链式的连等操作:利用上个操作的返回值作为下个操作的参数。这段代码共有3个操作:创建脚本元素/脚本元素src赋值/添加脚本元素。仔细参考下W3C的手册,DOM.appendChild不仅可以添加元素,并且返回值也是此元素。而src赋值和元素添加的顺序可以互换。因此我们可以用链式操作,从而彻底告别闭包和变量:


代码如下:

javascript:void(document.body.appendChild(document.createElement('script')).src='...')

  这一步,我们精简了19个字符!
  
  我们继续观察。上面的代码里出现了2个document。我们如果用一个短变量代替的话又可以减少字数。但使用了变量的话又会出现冲突的问题,于是又要用到闭包。。。仔细的回忆下,js里有个我们平时不推荐使用的东西:with。没错,使用他就可以解决这个问题。我是只需with(document){...}即可。因为只有一行代码,所以那对大括号也可以去掉。于是又减少了4个字符:


代码如下:

javascript:with(document)void(body.appendChild(createElement('script')).src='...')

  值得注意的是,void不再套在最外层了,因为with和if, for他们一样,不再是表达式,而是语句了。
  
  此时,代码里的每句都是各司其责,连重复的单词都找不到了。我们还能否再精简?如果硬要找,那也只得从void这家伙身上找了。如果去掉它,那地址栏执行后,页面就变成了脚本元素的src字符了。显然删不得。但我们可以尝试换个,比如alert。在对话框过后,页面仍保留着。
  先前说了,void的功能仅仅是返回一个undefined,而alert没有返回值。这里就不得不说javascript与其他语言的不同之处了。在其他的语言里,几乎都有函数/过程这么两概念,过程就是没有返回值的函数。不过js可不同,在js里任何函数都有一个返回值,即使“ 没有返回值 ”也是一种返回值,他就是undefined。所以alert和void有着相同的返回值:undefined。只要地址栏执行后结果是它,页面就不会转跳,而其他诸如false,0,null,NaN等等都不行。
  
  于是我们只需让表达式返回的是undefined就可以了,但必须比void()这几个字符短。要产生一个undefined,除了它字面常量外,另外就是调用没有返回值的函数,或者访问一个对象不存在的属性。我们要尽可能简短。如果页面里使用了jQuery的话,我们用$.X就可以得到一个undefined。但没用jq的话,就不能保证是否存在变量$了。既然找不到足够简短的全局变量,我们可以用json创造个匿名的,比如[]或{},然后访问他的不存在属性,比如[].X。于是,我们可以告别void了:


代码如下:

javascript:with(document)body.appendChild(createElement('script')).src='...';[].X

  这样就减少了1个字节。我们还可以合并下代码,用表达式替换X:


代码如下:

javascript:with(document)[][body.appendChild(createElement('script')).src='...']

  这样又减少了1个字节。
  
  事实上,js里的任何一个变量都是继承于Object的,即使数字也不例外。所以,我们完全可以用一个数字替换[],这样更进一步减少1个字符:


代码如下:

javascript:with(document)0[body.appendChild(createElement('script')).src='...']

  到此,代码里除了src字符外,缩短到76字节。
  
  当然,最终的极限仍在探索中。。。
  
  配合Google的短域名服务Google URL Shortener,我们可以缩短脚本的URL,例如:


代码如下:

javascript:with(document)0[body.appendChild(createElement('script')).src='http://goo.gl/QPp29']

(0)

相关推荐

  • 最短的javascript:地址栏载入脚本代码

    不过脚本比较长的时候,需要复制密密麻麻一大段到地址栏里,显得很不美观,而且脚本修改起来也很不容易.因此一般先把脚本写在单独一个文件里,然后用javascript: 的形式动态载入脚本到页面中.不少网页插件都是用这个方法载入. 平时,我们用最简单的代码实现动态载入: 复制代码 代码如下: javascript:var o=document.createElement('script');o.src='...';document.body.appendChild(o);void(0) 当然,这对于载

  • 如何让动态插入的javascript脚本代码跑起来。

    首先,声明方法很多种,直接间接的方法都有,只罗列一般情况下的两种模式: 假设我们要装入的代码是a.js: var foo=function(){ document.write("I am a.js content foo() function by never-online"); }; 一.直接插入src,这种方法简单而直接,但有局限性, 1) <script> var x=document.createElement("SCRIPT"); x.src=

  • 10个实用的脚本代码工具

    下面介绍10个实用的 浏览辅助 Tidy Read 复制代码 代码如下: javascript:(function(){var s=document.createElement("script");s.charset="gb2312";s.language="javascript";s.type="text/javascript";s.src="http://tidyread.com/tidyread.js?u=&q

  • 基于JavaScript表单脚本(详解)

    什么是表单? 一个表单有三个基本组成部分: 表单标签:这里面包含了处理表单数据所用CGI程序的URL以及数据提交到服务器的方法. 表单域:包含了文本框.密码框.隐藏域.多行文本框.复选框.单选框.下拉选择框和文件上传框等. 表单按钮:包括提交按钮.复位按钮和一般按钮:用于将数据传送到服务器上的CGI脚本或者取消输入,还可以用表单按钮来控制其他定义了处理脚本的处理工作. JavaScript与表单间的关系:JS最初的应用就是用于分担服务器处理表单的责任,打破依赖服务器的局面,尽管目前web和jav

  • 跟我学习javascript的异步脚本加载

    先来看这行代码: <script src = "allMyClientSideCode.js"></script> 这有点儿--不怎么样."这该放在哪儿?"开发人员会奇怪,"靠上点,放到<head>标签里?还是靠下点,放到<body>标签里?"这两种做法都会让富脚本站点的下场很凄惨.<head>标签里的大脚本会滞压所有页面渲染工作,使得用户在脚本加载完毕之前一直处于"白屏死机&

  • 简洁短小的 JavaScript IE 浏览器判定代码

    这个目前世界上最短的 Javascript 判定 IE 浏览器的方法来自俄罗斯!它已经在各版本的 IE 以及目前其他流行的浏览器上经过测试,基于 IE 的 Bug,微软虽然已经意识到,但是从来没有纠正过. 复制代码 代码如下: <script type='text/javascript'> var ie = !-[1,]; alert(ie); </script> 以上代码运行结果:IE 下返回true,其他标准浏览器返回false.!-[1,],仅仅只有 6 bytes! 不过如

  • javascript伸缩菜单栏实现代码分享

    本文实现了点击标题时判断该标题下的菜单是否显示,如果是显示的则将其隐藏,如果是隐藏的则将其显示出来.具体代码如下 <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> *{margin:0; pad

  • JavaScript惰性载入函数实例分析

    本文实例讲述了JavaScript惰性载入函数.分享给大家供大家参考,具体如下: 惰性载入函数 惰性载入函数表示函数执行的分支仅会发生一次,有两种实现惰性载入函数的方式,第一种是在函数被调用时再处理,在第一次调用中,该函数会覆盖为另外一个按合适方式执行的函数,这样任何对函数的调用都不用再经过执行的分支了.第二种实现惰性载入的方式是在声明函数时就制定适当的函数,这样,第一次调用函数时就不会损失性能了,而在代码首次加载时会损失一点儿性能. 载入方式一 var flag = 1; function t

  • JavaScript编写棋盘覆盖代码详解

    一.前言 之前做了一个算法作业,叫做棋盘覆盖,本来需要用c语言来编写的,但是因为我的c语言是半桶水(哈哈),所以索性就把网上的c语言写法改成JavaScript写法,并且把它的覆盖效果显示出来 二.关键代码 <!DOCTYPE html> <html> <head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <titl

  • JavaScript 自动完成脚本整理(33个)

    如果你也正准备在这方面提升自己网站的用户体验,下面为你准备了33个JavaScript自动完成脚本,当然还包括用Jquery实现的.1. Proto!TextboxList (演示地址)=700) window.open('/upload/20091020155954866.jpg');" src="http://files.jb51.net/upload/20091020155954866.jpg" onload="if(this.offsetWidth>'

随机推荐