Home > Article > Web Front-end > A collection of seven principles for unobtrusive JavaScript_javascript skills
Before you start designing your script, the first thing to consider is to check the HTML code you are going to script for and see if there is anything that can help you achieve your goal.
1. Don’t make any assumptions
(JavaScript is an unreliable assistant)
Perhaps the most important feature of unobtrusive JavaScript is that - you have to stop Any assumptions:
* Don't assume that JavaScript is available, you're better off assuming that there's a good chance it's not available, rather than relying on it directly.
* Don’t assume that the browser supports methods and properties until you’ve tested them and confirmed that they work.
* Don’t assume that HTML code is as correct as you think, check it every time, and do nothing if it’s not available.
* Make JavaScript function independent of input devices
* Remember that other scripts may affect the functionality of your JavaScript, so make sure your script's scope is as safe as possible.
Before you start designing your script, the first thing to consider is to check the HTML code you are going to script for and see if there is anything that can help you achieve your goal.
2. Find hooks and node relationships
(HTML is the cornerstone of scripting)
Before you start writing scripts, take a look at the HTML you are going to write JavaScript for. If the HTML is unorganized or unknown, it's almost impossible to have a good scripting solution - it's likely that you'll either create too much markup in JavaScript, or the application will be too dependent on JavaScript.
There are some things to consider in HTML, and that is hooks and node relationships.
<1>.HTML hook
The original and most important hook of HTML is ID, and ID can be accessed through the fastest DOM method - getElementById. If all IDs in a valid HTML document are unique (there is a bug in IE regarding name and ID, but some good libraries solve this problem), using IDs is safe, reliable, and easy to test.
Some other hooks are HTML elements and CSS classes. HTML elements can be accessed through the getElementsByTagName method, but CSS classes cannot be accessed through native DOM methods in most browsers. However, there are many external libraries that provide methods to access CSS class names (similar to getElementsByClassName).
<2>.HTML node relationship
Another interesting point about HTML is the relationship between tags. Think about the following questions:
* How can we pass the least amount of DOM most easily? Traverse to reach target node?
* By modifying what tag, we can access as many child nodes as possible that need to be modified?
* What attributes or information does a given element have that can be used to reach another element?
Traversing the DOM is resource-intensive and slow, which is why you should try to use technologies already used in browsers to do it.
3. Leave traversal to the experts
(CSS, traverse DOM faster)
Scripts and usage methods or properties about DOM (getElementsByTagName, nextSibling, previousSibling, parentNode and others) to traverse the DOM seems to confuse a lot of people, which is interesting. The interesting thing is that we have already done these things through another technology-CSS.
CSS is a technology that uses CSS selectors to access target elements and change their visual properties by traversing the DOM. A complex piece of JavaScript using the DOM can be replaced with a CSS selector:
Copy code The code is as follows:
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 has the same function as the above*/
#nav a{
color:#369;
text-decoration:none;
}
This is a very powerful technique that can be put to good use. You can achieve this by dynamically adding classes to high-level elements in the DOM or changing the element ID. If you use the DOM to add a CSS class to the document's body, designers can easily define static and dynamic versions of the document.
JavaScript:
Copy code The code is as follows:
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 based on existing usage patterns)
An important part of unobtrusive JavaScript is Understand how browsers work (especially how browsers crash) and what users expect. Regardless of the browser you can easily create a completely different interface using JavaScript. Drag-and-drop interfaces, folding areas, scroll bars and sliders can all be created using JavaScript, but this problem is not a simple technical issue. You need to think about the following questions:
* Can this new interface be independent of input devices? If not, what can you rely on?
* Does the new interface I create follow the guidelines of browsers or other rich interfaces (can you switch directly between multi-level menus with the mouse? Or do you need to use the tab key?)
* What do I need to provide? Function But does this function rely on JavaScript?
The last question is actually not a problem, because you can use the DOM to create HTML out of thin air if needed. An example of this is a "print" link. Since browsers don't provide a non-JavaScript functionality to print a document, you need to use the DOM to create this type of link. The same is true for a clickable title bar that implements expand and collapse content modules. The title bar cannot be activated by the keyboard, but the links can. So in order to create a clickable title bar you need to add the link using JavaScript, and then any user with a keyboard can collapse and expand the content module.
A great resource for solving these types of problems is the Design Pattern Library. As for knowing which things in the browser are independent of input devices, it depends on the accumulation of experience. The first thing you need to understand is the event handling mechanism.
5. Understand events
(event handling will cause changes)
Event handling is the second step towards unobtrusive JavaScript. The point is not to make everything draggable, clickable, or add inline handling to them, but to understand that event handling is something that can be completely separated. We've separated HTML, CSS, and JavaScript, but we haven't gone very far in separating event handling.
The event processor will monitor changes that occur on elements in the document. If an event occurs, the processor will find a wonderful object (usually a parameter named e), which will tell the element to What it is and what can be done with it.
What’s really interesting about most event handling is that it doesn’t just happen on the element you want to access, but also on all elements higher up in the DOM (but not all events are like this , focus and blur events are exceptions). For example, you can use this feature to add only one event handler to a navigation list, and use the event handler method to get the element that actually triggered the event. This technique is called event delegation, and it has several advantages:
* You only need to check whether an element exists, instead of checking every element
* You can dynamically add or remove child nodes without Remove the corresponding event handler
* You can respond to the same event on different elements
Another thing to remember is that you can stop the event while it is propagating to the parent element and You can override the default behavior of HTML elements (such as links). However, sometimes this is not a good idea because browsers give HTML elements the behaviors they do for a reason. For example, links might point to a target within the page, and leaving them unmodified ensures that the user can also bookmark the page's current script state.
6. Think of others
(namespaces, scopes and patterns)
Your code will almost never be the only script code in a document. So it is particularly important to ensure that there are no global functions or global variables in your code that other scripts can override. There are several patterns available to avoid this problem, the most basic of which is to use the var keyword to initialize all variables. Suppose we write the following script:
Copy code The code is as follows:
var nav = document.getElementById('nav');
function init(){
// do stuff
}
function show(){
// do stuff
}
function reset(){
// do stuff
}
The above code contains a global variable called nav and three functions named init, show and reset. These functions can access the nav variable and can access each other through the function name:
Copy code The code is as follows:
var nav = document .getElementById('nav');
function init(){
show();
if(nav.className === 'show'){
reset();
}
// do
}
function show(){
var c = nav.className;
// do stuff
}
function reset(){
// do stuff
}
You can encapsulate the code into an object to avoid the above global coding, so that functions can be turned into methods in the object, and global variables can be turned into properties in the object. You need to use the "name colon" method to define methods and properties, and you need to add a comma as a separator after each property or method.
Copy code The code is as follows:
var myScript = {
nav:document.getElementById('nav'),
init:function(){
// do stuff
},
show:function(){
// do stuff
},
reset:function(){
// do stuff
}
}
All methods and properties are available externally and internally by using the "class name dot operator" Visited.
Copy code The code is as follows:
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 pattern is that every time you access other methods or properties from a method, you must go in front Add the name of the object, and everything in the object is accessible from the outside. If you just want part of the code to be accessible to other scripts in the document, consider the following module pattern:
Copy the code The code is as follows:
var myScript = function(){
//These are private methods and properties
var nav = document.getElementById('nav');
function init(){
// do stuff
}
function show(){
// do stuff
}
function reset(){
// do stuff
}
/ /Public methods and properties are wrapped in return statements using object syntax
return {
public:function(){
},
foo:'bar'
}
} ();
You can access the returned public properties and methods in the same way as the previous code, in this example: myScript.public() and myScript. foo. But there is another uncomfortable point here: when you want to access a public method from the outside or from a private method inside, you still have to write a lengthy name (the name of the object can be very long). To avoid this, you need to define them as private and only return an alias in the return statement:
Copy code The code is as follows:
var myScript = function(){
// These are private methods and properties
var nav = document.getElementById('nav');
function init(){
// do stuff
}
function show(){
// do stuff
// do stuff
}
function reset(){
// do stuff
}
var foo = 'bar';
function public(){
}
return {
public:public,
foo:foo
}
}() ;
This ensures code style consistency, and you can use shorter aliases to access methods or properties.
If you don’t want to expose any methods or properties to the outside world, you can encapsulate all the code into an anonymous method and execute it immediately after its definition:
Copy code The code is as follows:
(function(){
// these are all private methods and properties
var nav = document.getElementById('nav');
function init(){
// do stuff
show(); // No class name prefix required here
}
function show(){
// do stuff
}
function reset(){
// do stuff
}
})();
This pattern is great for code modules that are executed only once and have no dependencies on other functions.
By following the rules above, your code will work better for users, and it will also make your code run better on machines and get along better with other developers' code. However, there is one group that needs to be taken into consideration.
7. Consider for developers who take over
(makes maintenance easier)
The final step in making your script truly unobtrusive is to double-check it after you've written it, and Take care of the developers who will take over your code once the script goes live. Consider the following questions:
* Are all variable and function names sensible and easy to understand?
* Is the code well organized? Does it flow smoothly from start to finish?
* Are all dependencies obvious?
* Have comments been added where possible that may cause confusion?
The most important thing to note is: realize that the HTML and CSS code in the document are more likely to be changed than the JavaScript (because they are responsible for the visual effect). So don't include any classes and IDs that can be seen by end users in the script code, but separate them into an object that holds configuration information.
Copy code The code is as follows:
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
};
}();
This way the maintainer knows where to modify these properties without changing other code.