However, when the script is relatively long, you need to copy a large section into the address bar, which looks very unsightly, and it is not easy to modify the script. Therefore, the script is generally written in a separate file first, and then the script is dynamically loaded into the page in the form of javascript:. Many web plug-ins are loaded using this method.
Usually, we use the simplest code to implement dynamic loading:
javascript:var o=document.createElement('script');o.src='...';document.body.appendChild(o);void(0)
Of course, this is OK enough for loading plugins. But not long ago I saw a slightly modified method, which got me wondering how short this code could be!
His code is roughly the same, just more rigorous:
javascript:(function(o){o.src='...';document.body.appendChild(o)})(document.createElement('script'));void(0)
Although the code is longer than before, the variables are placed in closures to avoid potential conflicts. And using document.createElement as a parameter of the closure cleverly saves a var word.
I had nothing to do, so I thought about whether the code could be streamlined and streamlined. By the way, review the various features in js.
Of course, first of all, there are several default rules for the address bar loading script to follow:
1. Do not introduce global variables
2. Compatible with mainstream browsers
3. The loading process does not affect the page
> Does not affect global variables, we need to use closures to hide our private variables;
> To be compatible with mainstream browsers, we must use standard methods, and compatibility judgment will only increase the code length;
> If you simply use innerHTML to add elements, it may cause existing elements to be refreshed;
So we started to analyze step by step.
Obviously, the first thing that comes to mind is the call to anonymous closure.
Usually we call an anonymous closure in the form of (function(){})(). Note that the red priority brackets are essential, otherwise it is an incorrect syntax.
But you can also use another form: function(){}() The number in front can be replaced by -!~ and other unary operators. But this is only a 1 byte difference.
Another obvious one is that you can replace the parameters of void(0) with the expression of the closure call. Although void is just a keyword, it has function-like functions and returns undefined for any parameter. If there is no void, after executing javascript: in the address bar, the page will become the script expression return value, which everyone should have seen.
So after obvious observation, 3 characters were slightly reduced.
javascript:void( function(o){o.src ='...';document.body.appendChild(o)}(document.createElement('script')))
However, the above are superficial observations. Now let's analyze it carefully.
Why we use closures is to prevent conflicts between our variables and the page. So is it possible not to use variables? The only way to avoid variables is to use chained operations: use the return value of the previous operation as the parameter of the next operation. This code has a total of 3 operations: create script element/script element src assignment/add script element. Please refer to the W3C manual carefully. DOM.appendChild can not only add elements, but the return value is also this element. The order of src assignment and element addition can be interchanged. Therefore, we can use chain operations to say goodbye to closures and variables completely:
javascript:void(document.body.appendChild(document.createElement('script')).src='...')
In this step, we have streamlined 19 characters!
Let’s continue to observe. Two documents appear in the above code. If we use a short variable instead, we can reduce the number of words. But if variables are used, conflicts will arise, so closures must be used again. . . If you recall carefully, there is something in js that we usually do not recommend: with. Yes, using him can solve this problem. All I need is with(document){...}. Since there is only one line of code, the pair of braces can also be removed. So another 4 characters were reduced:
javascript:with( document)void(body.appendChild(createElement('script')).src='...')
It is worth noting that void is no longer in the outermost layer, because with Like if and for, they are no longer expressions, but statements.
At this point, every sentence in the code has its own responsibility, and even repeated words can’t be found. Can we get any leaner? If you insist on looking for it, you have to look for it from this guy void. If you remove it, after the address bar is executed, the page will become the src character of the script element. Obviously it cannot be deleted. But we can try to change it, such as alert. After the dialog box, the page remains.
As mentioned before, the function of void is only to return an undefined, while alert has no return value. Here we have to talk about the differences between JavaScript and other languages. In other languages, there are almost two concepts of function/procedure. A procedure is a function without a return value. But js is different. In js, any function has a return value. Even "no return value" is a return value, which is undefined. So alert and void have the same return value: undefined. As long as the address bar is executed and the result is it, the page will not jump, but others such as false, 0, null, NaN, etc. will not work.
So we only need to let the expression return undefined, but it must be shorter than void(). To generate an undefined, in addition to its literal constant, you need to call a function that does not return a value, or access a property that does not exist in an object. We want to keep it as brief as possible. If jQuery is used in the page, we can get an undefined by using $.X. But without jq, there is no guarantee whether the variable $ exists. Since we can't find a short enough global variable, we can use json to create an anonymous one, such as [] or {}, and then access its non-existent attributes, such as [].X. So, we can say goodbye to void:
javascript:with( document)body.appendChild(createElement('script')).src='...';[].X
This reduces 1 byte. We can also merge the code and replace >javascript:with(document)[][body.appendChild(createElement('script')).src='...']
Copy code
The code is as follows:
javascript:with(document)0[body.appendChild(createElement('script')).src='...']
, we can shorten the URL of the script, for example:
Copy code
The code is as follows:
javascript:with(document)0[body.appendChild(createElement('script')).src='http://goo.gl/ QPp29']