1. Do not make any assumptions
(JavaScript is an unreliable Assistant)
One of the most important features of JavaScript that may not be abrupt is-you have to stop any assumptions:
* Do not assume that JavaScript is available. You 'd better think it is probably unavailable, rather than relying on it directly.
* Before you test and confirm that some methods and attributes can be used, do not assume that the browser supports them.
* Do not assume that HTMLCodeAs you can imagine, check every time and do nothing when it is unavailable.
* Make JavaScript Functions independent from input devices
* Remember that other scripts may affect your JavaScript Functions, so ensure that your script scope is as secure as possible.
Before designing your script, the first thing to consider is to check the HTML code for which you want to write the script and see what can help you achieve your goal.
2. Find the hook and node relationship
(HTML is the cornerstone of scripts)
Before writing a script, you should first look at the HTML for which you want to write JavaScript. If HTML is unorganized or unknown, it is almost impossible for you to have a good scripting solution-it is likely that the following situation will occur: either too many tags will be created using JavaScript, or the application is too dependent on JavaScript.
There are some things to consider in HTML, that is, the relationship between hooks and nodes.
<1>. html hook
The first and most important hooks of HTML are ID, and Id can be accessed through the fastest DOM method -- getelementbyid. If all the IDs in a valid HTML document are unique (there is a bug about name and ID in IE, but some good class libraries solve this problem ), using ID is safe, reliable, and easy to test.
Some other hooks are HTML elements and CSS classes. HTML elements can be accessed using the getelementsbytagname method. In most browsers, CSS classes cannot be accessed using the native DOM method. However, many external class libraries provide methods to access CSS class names (similar to getelementsbyclassname.
<2>. html node relationship
Another interesting thing about HTML is the relationship between tags. Consider the following question:
* How can we easily reach the target node through the least Dom traversal?
* By modifying the tags, you can access as many subnodes as possible?
* What attributes or information can a given element be used to reach another element?
Traversing the Dom is resource-consuming and slow, which is why we should try to use the technology already in use in the browser to do this.
3. Hand over traversal to experts
(CSS, faster Dom traversal)
It seems interesting that many people are confused to traverse Dom scripts and usage methods or attributes (getelementsbytagname, nextsibling, previussibling, parentnode, and others. Interestingly, we have already done these things through another technology, CSS.
CSS is a technology that uses CSS selectors to traverse the Dom to access target elements and change their visual attributes. A complex JavaScript using Dom can be replaced by a CSS selector: Java code
-
- VaR n = Document. getelementbyid ('Nav');
-
- If(N ){
-
- VaR as = n. getelementsbytagname ('A');
-
- If(As. length>0){
-
- For(VAR I =0; As [I]; I ++ ){
- As [I]. style. Color = '#369′;
-
- As [I]. style. textdecoration = 'none ';
-
- }
-
- }
-
- }
-
-
- /* The following code is the same as the above function */
-
-
- # Nav {
-
- Color :#369;
-
- Text-Decoration: none;
-
- }
VaR n = document. getelementbyid ('nav'); If (n) {VaR as = n. getelementsbytagname ('A'); if (. length> 0) {for (VAR I = 0; as [I]; I ++) {as [I]. style. color = '#369'; as [I]. style. textdecoration = 'none' ;}}/ * The code below is the same as the above function */# nav A {color: #369; text-Decoration: none ;}
This is a very powerful technique that can be used well. You can do this by dynamically adding a class to a high-level element in the Dom or changing the element ID. If you use Dom to add a CSS class to the document body, the designer can easily define the static and dynamic versions of the document.
Java code
-
- Javascript:
-
-
- VaR dynamicclass ='Js';
-
- VaR B = Document. Body;
- B. classname = B. classname? B. classname +'Js':'Js';
-
-
- CSS:
-
-
- /* Static version */
-
-
- # Nav {
-
- ....
-
- }
-
-
- /* Dynamic version */
-
-
- Body. js # nav {
- ....
-
- }
Javascript: var dynamicclass = 'js'; var B = Document. Body; B. classname = B. classname? B. classname + 'js': 'js'; CSS:/* static version */# nav {....} /* dynamic version */body. JS # nav {....}
4. Understand browsers and users
(Create what you need in the existing usage mode)
An important part of Non-abrupt Javascript is understanding how the browser works (especially how the browser crashes) and what the user expects. Without considering the browser, you can easily use JavaScript to create a completely different interface. You can drag the interface, fold the area, scroll bar, and slide block to create them using JavaScript. However, this is not a simple technical problem. You need to consider the following questions:
* Can this new interface be independent of the input device? If not, what can be relied on?
* Does the new interface I created follow the principles of browsers or other rich interfaces (Can you switch between them directly through the mouse in the multi-level menu? Or do I need to use the tab key ?)
* What functions do I need to provide, but does this function depend on JavaScript?
The last problem is actually not a problem, because you can use Dom to Create HTML out of thin air if needed. An example of this is the "print" link. Because the browser does not provide a non-JavaScript document printing function, you need to use Dom to create such links. Similarly, a title bar that enables the content module to expand and contract can also be clicked. The title bar cannot be activated by the keyboard, but the link is acceptable. To create a title bar that can be clicked, you need to use JavaScript to add the link. Then, all users who use the keyboard can contract and expand the content module.
An excellent resource for solving such problems is the design mode library. To know which items in the browser are independent from input devices, it is necessary to accumulate experience. The first thing you need to understand is the event processing mechanism.
5. Understand events
(Event processing will cause changes)
Event processing is the second step towards non-abrupt JavaScript. The focus is not to make everything drag, click, or add inline processing for them, but to understand that event processing is a completely isolated thing. We have separated HTML, CSS, and JavaScript, but we have not gone far in the separation of event processing.
The event processor monitors the changes in elements in the document. If an event occurs, the processor will find a wonderful object (usually a parameter named E ), this object will tell the element what happened and what it can do.
What really interesting about most event processing is that it not only happens to the elements you want to access, it also occurs on all elements at a higher level in the DOM (but not all events are like this, and the focus and blur events are exceptions ). For example, you can add only one event processor to a navigation list and use the event processor method to obtain the elements that actually trigger the event. This technology is called event delegation, which has the following advantages:
* You only need to check whether an element exists, instead of checking each element.
* You can dynamically add or delete subnodes without deleting the corresponding event processor.
* You can respond to the same event on different elements.
Another thing to remember is that when an event is propagated to a parent element, you can stop it and overwrite the default behavior of HTML elements (such as links. However, sometimes this is not a good idea, because browsers give HTML elements the behavior for a reason. For example, a link may point to a target on the page. without modifying them, you can add the current Script status of the page to the bookmarks.
6. Think for others
(Namespace, scope, and mode)
Your code is almost never the only script code in the document. Therefore, it is especially important to ensure that no other scripts can overwrite global functions or global variables in your code. There are some available modes to avoid this problem. The most basic point is to use the VaR keyword to initialize all variables. Suppose we have written the following script:
Java code
- VaR nav = Document. getelementbyid ('Nav');
- Function Init (){
- // Do stuff
- }
- Function show (){
- // Do stuff
- }
- Function reset (){
- // Do stuff
- }
VaR nav = document. getelementbyid ('nav'); function Init () {// do stuff} function show () {// do stuff} function reset () {// do stuff}
The above code contains a global variable named nav and three functions named init, show, and reset respectively. All these functions can access the nav variable and access each other using the function name:
Java code
-
- VaR nav = Document. getelementbyid ('Nav');
-
- Function Init (){
-
- Show ();
-
- If(NAV. classname ='Show'){
-
- Reset ();
-
- }
-
- // Do stuff
-
- }
-
- Function show (){
-
- VaR c = nav. classname;
- // Do stuff
-
- }
-
- Function reset (){
-
- // Do stuff
-
- }
VaR nav = document. getelementbyid ('nav'); function Init () {Show (); If (NAV. classname = 'show') {reset ();} // do stuff} function show () {var c = nav. classname; // do stuff} function reset () {// do stuff}
You can encapsulate the code into an object to avoid the above type of global encoding, so that you can convert the function into a method in the object and change the global variable into an attribute in the object. You need to use the "name + colon" method to define methods and attributes, and add a comma after each attribute or method as the delimiter.
Java code
- var myscript ={
- NAV: document. getelementbyid ( 'nav' ),
- init: function () {
- // do stuff
- },
- show: function () {
- // do stuff
- },
- Reset: function () {
- // do stuff
- }
- }
VaR myscript = {NAV: document. getelementbyid ('nav'), init: function () {// do stuff}, show: function () {// do stuff}, reset: function () {// do stuff }}
All methods and attributes can be accessed from the outside and inside by using the class name + dot operator. Java code
-
- VaR myscript = {
-
- NAV: Document. getelementbyid ('Nav'),
-
- Init: function (){
-
- Myscript. Show ();
-
- If(Myscript. Nav. classname ='Show'){
-
- Myscript. Reset ();
-
- }
- // Do stuff
-
- },
-
- Show: function (){
-
- VaR c = myscript. Nav. classname;
-
- // Do stuff
-
- },
-
- Reset: function (){
-
- // Do stuff
-
- }
-
- }
VaR myscript = {NAV: document. getelementbyid ('nav'), init: function () {myscript. show (); If (myscript. nav. classname = 'show') {myscript. reset ();} // do stuff}, show: function () {var c = myscript. nav. classname; // do stuff}, reset: function () {// do stuff }}
The disadvantage of this mode is that every time you access other methods or attributes from a method, you must add the object name in front, and everything in the object can be accessed from the outside. If you only want some code to be accessed by other scripts in the document, consider the following module mode: Java code
-
- VaR myscript = function (){
-
- // These are private methods and attributes.
-
- VaR nav = Document. getelementbyid ('Nav');
-
- Function Init (){
-
- // Do stuff
- }
-
- Function show (){
-
- // Do stuff
-
- }
-
- Function reset (){
-
- // Do stuff
-
- }
-
- // The public methods and attributes are wrapped in the return statement using the object syntax.
-
- Return{
-
- Public: Function (){
-
-
- },
- Foo:'Bar'
-
- }
-
- }();
VaR myscript = function () {// These are private methods and attributes var nav = document. getelementbyid ('nav'); function Init () {// do stuff} function show () {// do stuff} function reset () {// do stuff} // The public methods and attributes are wrapped in the return {public: function () {}, FOO: 'bar '}}();
You can access the returned public attributes and methods in the same way as the previous Code. In this example, you can access: myscript. Public () and myscript. Foo. But there is another uncomfortable point: when you want to access a public method from the external or from a private method inside, write a lengthy name (the object name can be very long ). To avoid this, you need to define them as private and return only one alias in the return statement: Java code
-
- VaR myscript = function (){
-
- // These are private methods and attributes.
- VaR nav = Document. getelementbyid ('Nav');
-
- Function Init (){
-
- // Do stuff
-
- }
-
- Function show (){
-
- // Do stuff
-
- // Do stuff
-
- }
-
- Function reset (){
-
- // Do stuff
-
- }
- VaR Foo ='Bar';
-
- FunctionPublic(){
-
-
- }
VaR myscript = function () {// These are private methods and attributes var nav = document. getelementbyid ('nav'); function Init () {// do stuff} function show () {// do stuff} function reset () {// do stuff} var Foo = 'bar'; function public (){}
// Return only the Java code pointing to the private methods and attributes you want to access.
- Return{
- Public:Public,
- Foo: foo
- }
- }();
Return {public: public, foo: Foo }}();
This ensures code style consistency, and you can use a shorter alias to access the methods or attributes.
If you do not want to expose any external methods or attributes, You can encapsulate all the code into an anonymous method and execute it immediately after its definition ends:
Java code
-
- (Function (){
-
- // These are all private methods and Properties
- VaR nav = Document. getelementbyid ('Nav');
-
- Function Init (){
-
- // Do stuff
-
- Show ();// The class name prefix is not required here
-
- }
-
- Function show (){
-
- // Do stuff
-
- }
-
- Function reset (){
-
- // Do stuff
-
- }
- })();
(Function () {// These are all private methods and propertiesvar nav = document. getelementbyid ('nav'); function Init () {// do stuffshow (); // The class name prefix is not required here} function show () {// do stuff} function reset () {// do stuff }})();
This mode is good for code modules that only execute once and are not dependent on other functions.
By following the rules above, your code can better work for users, and make your code run better on the machine and get along with the code of other developers. However, there is another group to consider.
7. For the developer to take over
(Make maintenance easier)
The last step to truly unobtrusive your script is to carefully check the code after writing it, and take care of the developers who will take over your code once the script goes online. Consider the following questions:
* Are all variables and function names reasonable and easy to understand?
* Is the code properly organized? Is it smooth from start to end?
* Are all dependencies obvious?
* Are comments added to any areas that may cause confusion?
The most important thing is to realize that HTML and CSS code in the document is more likely to be changed than JavaScript (because they are responsible for visual effects ). Therefore, do not include any class and ID that can be seen by end users in the script code, but separate them into an object that saves configuration information.
Java code
-
- Myscript = function (){
-
- VaR Config = {
-
- Navigationid:'Nav',
-
- Visibleclass:'Show'
-
- };
-
- VaR nav = Document. getelementbyid (config. navigationid );
-
- Function Init (){
-
- Show ();
-
- If(NAV. classname === config. visibleclass ){
- Reset ();
-
- };
-
- // Do stuff
-
- };
-
- Function show (){
-
- VaR c = nav. classname;
-
- // Do stuff
-
- };
-
- Function reset (){
-
- // Do stuff
-
- };
-
- }();
Myscript = function () {var Config = {navigationid: 'nav', visibleclass: 'show'}; var nav = document. getelementbyid (config. navigationid); function Init () {Show (); If (NAV. classname = config. visibleclass) {reset () ;}; // do stuff}; function show () {var c = nav. classname; // do stuff}; function reset () {// do stuff };}();
In this way, the maintainer knows where to modify these attributes without modifying other code.