Recently organized an HTML/CSS/JS coding specification for your reference. Contents: 1, HTML coding specification 2, CSS coding specification 3, JS coding specification
First, HTML coding specification
1. The IMG tag uses the Alt attribute
According to the W3C standard, the IMG tag writes an Alt attribute, or an empty one if none is present. But usually you want to write something with content, based on what the image is trying to say, because Alt is the text that shows up when the image doesn’t load. This is not a very good way to write it:
<img src="company-logo.svg" alt="ABC Company Logo">Copy the code
Better written:
<img src="chime-logo.svg" alt="ABC Company">Copy the code
Instead of telling the user that it’s a Logo, just tell them that it’s ABC Compay. Such as:
<img src="user-head.jpg" alt="User Portrait">Copy the code
Can be changed to:
<img src="user-head.jpg" alt="Bolynga Team">Copy the code
If the image doesn’t show up, just display the user’s name.
Some people are lazy and just write an empty Alt, that’s fine, but in some important places, it’s still good for SEO.
2. Do not write a closed label on a single label
Why is that? Because it’s useless and you don’t seem to understand the HTML specification. We’re not writing XHTML. Common single tags include img, link, input, HR, and br.
<img src="test.jpg"></img><br/>
<input type="email" value=""/>
Copy the code
Should be changed to:
<img src="test.jpg"><br>
<input type="email" value="">Copy the code
If you write a JSX template with React, it requires each tag to be closed, but it’s never native HTML.
3. Custom attributes must start with data-
Non-standard attributes that you add should start with data-, otherwise the W3C Validator will consider them non-canonical.
<div count="5"></div>Copy the code
Should be changed to:
<div data-count="5"></div>Copy the code
4. Td in TR, LI in UL/OL
The following is a bad way to write:
<div>
<li></li>
<li></li>
</div>
Copy the code
More commonly td is not written inside TR:
<table>
<td></td>
<td></td>
</table>
Copy the code
Some browsers will correct you if you don’t write properly, but others may not be so lucky. Since the standard doesn’t say what to do if it’s not written properly, each browser may have its own way of dealing with it.
5. The direct child element of ul/ OL can only be Li
Sometimes you might write a div or span inside ul, thinking it’s ok:
<ol>
<span>123</span>
<li>a</li>
<li>b</li>
</ol>
Copy the code
Ol is a list, and all of its children should be display: list-item, and all of a sudden a span pops up, and you tell the browser how to do it. So writing poorly will result in different performance in different browsers.
Similarly, the direct children of tr should all be TD, so if you write tr inside TD, you get messed up.
6. Have title tags in sections
If you use the section/value/article/nav this label, need to be in it to write a title tag h1 / h2, h3, because this tag can be divided into four chapters, they are all independent chapters, need to have the title, if there is no title in the UI? You can write a hidden title tag, if for SEO purposes, you can’t display: None directly, but use some special treatment, such as a hidden-text class:
<style>.hidden-text{position: absolute; left: -9999px; right: -9999px}</style>
<section>
<h1 class="hidden-text">Listing Detail</h1>
</section>
Copy the code
7. Use section tags to enhance SEO
The advantage of using section is that you can divide sections as follows:
<body>
<h1>Listing Detail</h1>
<section>
<h1>House Infomation</h1>
<section>
<h1>LOCATION</h1>
<p></p>
</section>
<section>
<h1>BUILDING</h1>
<p></p>
</section>
</section>
<section>
<h1>Listing Picture</h1>
</section>
</body>
Copy the code
The outline will look like this:
Listing Detail
- House Infomation
- LOCATION
- BUILDING
- Listing Picture
Using HTML5 Outliner, you can see that we arbitrarily used multiple H1 tags, which is illegal in HTML4.
8. Block level elements cannot be used inside inline elements
For example, it is illegal to write:
<a href="/listing? id=123">
<div></div>
</a>
Copy the code
The A tag is an inline element with a div tag inside it, which may cause the A tag to fail to click properly. Or a div inside a span, in which case inline elements are explicitly set to display block, as follows:
<a href="/listing? id=123" style="display: block">
<div></div>
</a>
Copy the code
That’s normal.
9. Write <! DOCType html>
Set the render mode of the page to standard mode, what happens if you forget to write? In weird mode, the default box model for input/ Textarea is changed to a border-box, the document height is changed to the height of the visual window, and the height of the window is not the desired document height. Another difference is that the parent container line height does not affect child elements in weird mode, as follows:
<div><img src="test.jpg" style="height:100px"></div>Copy the code
Div leaves a little space under it in standard mode, but in weird mode it does. This reminds us that we need to put <! At the top of our mail template. DOCType HTML >, because you’re writing HTML fragments when you’re developing your mail template locally, without this it goes into weird mode.
10. Use the Table layout to write the mail template
As there are various email clients, you do not know what users use to read emails. They may use webmail, gmail, Outlook, netease email master or other clients. These clients are diverse and have varying SUPPORT for HTML/CSS, so we can’t use advanced layouts and typography, such as Flex /float/ Absolute positioning. Using a rudimentary table layout is best for compatibility and scaling.
In addition, you can’t write media queries, you can’t write scripts, you can’t write inline styles, these are filtered out by the mail client, the styles have to be inline style, you can write inline first, and then use some tools to generate inline HTML for you.
After writing, you can actually test it. You can send it by QQ email, which supports sending HTML text. After sending it, you can open it in different clients to see if there is any problem, such as mobile phone client, computer client, and browser.
Since you don’t know if the user opened it on their phone or computer, you can’t write your email to the full width, but 100% is not a good idea. It might look too big on a PC screen, so you can write it like this:
<table style="border-collapse:collapse; font-family: Helvetica Neue,Helvetica,Arial; font-size:14px; width:100%; height:100%">
<tr><td align="center" valign="top"><table style="border:1px solid #ececec; border-top:none; max-width:600px; border-collapse:collapse">
<tr><td>The content of 1</td></tr>
<tr><td>Content of the 2</td></tr>
</table></td></tr></table>
Copy the code
< span style = “max-width:600px” style = “box-sizing: border-box; This gives a maximum width of 600px on a PC and 100% on a mobile client.
However, some clients, such as older Outlook, do not recognize the max-width property and are too wide on PCS. But there’s no way to do that, because we can’t just write the width to death or it’s going to slide left and right on the phone, and we can’t write script to determine ua or anything like that. Therefore, older versions of Outlook are not compatible.
11. Keep your HTML simple and don’t put too many layers on it
Need to set a lot of layers, generally there are two cases, one is not good at cutting the map, need to set a lot of layers to maintain typesetting, the second is to cut the map, but the UI is too fine. Like the following layout:
I would write:
<ul>
<li>
<div class="img-container">
<img>
</div>
<div class="text"></div>
</li>
</ul>
Copy the code
Since it is a list, it uses ul/li as the outer container, and has two divs inside, one image float: left, and one text container, and that’s it. You don’t have to cover a lot of layers, but some of them are necessary. If you write too simple, you don’t scale well. For example, if it’s a list then you should use UL/OL.
If you have a block that is a whole, and the whole is set to the right, then that block should also have a container. Sometimes you might want to have more than one container for some effect, such as float on the outside and display: table-cell on the inside. But you should have some value in all of these containers, and if you’re just trying to look uniform in terms of function, there’s not much point in distinguishing between them.
12. Write scripts and styles in HTML only for special situations
In general, it is a bad practice to write scripts and styles directly inside HTML, mixing style, structure, and logic. But sometimes, in order to avoid the flash screen problem, it is possible to directly follow the corresponding HTML with the adjusted script. This script looks a little ugly, but it is very useful, there is no way out.
13. Styles should be in the head tag
The style cannot be written in the body, which will result in rendering twice. Especially, the later the text is written, there may be a flash screen, for example, the above is already rendered, and suddenly a style tag is encountered, causing it to be re-rendered, which will flash for a moment, no matter from the pursuit of the coder or the user’s experience. Writing style inside a body is ultimately a bad idea.
Likewise, don’t write script inside the head tag, it will block page loading.
And CSS is also recommended to write style tags directly embedded in the page, because if you have an external chain, the browser needs to do domain name resolution first, and then establish a connection, and then download, this set down may have passed 0.5s/1s, or even 2~3 seconds. While the CSS written in the page can not be cached, but itself it is not very large, plus gzip compression, basically within 50K.
14. HTML should add the attribute of lang
If the page is in English, it should say:
<html lang="en">
<html lang="en-US">Copy the code
The first one means it is in English, the second one means it is in American English, plus this is good for SEO and screen reader users, he can quickly know what language the page is in, if it is In Chinese can write:
<html lang="zh-CN">Copy the code
15. Write the meta tag of Charset before the head tag
The meta tag of a charset should be the first tag after the head tag:
<head>
<meta charset="utf-8">
</head>Copy the code
One reason is to avoid garbled unicode symbols on web pages, written in the front because the W3C mandates that the language code be in the first 1024 bytes of an HTML document. If you do not write it in the old browser will have utF-7 attack hidden danger, specific can consult the information, but now the browser basically remove UTF-7 encoding support.
The charset tag should be written as html5, rather than html4:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">Copy the code
As FAR as I can see, even IE6 supports that short notation, even though it’s not an HTML5 browser.
16. Use HTML entities for special symbols
Instead of copying a Unicode special symbol directly into an HTML document, use its corresponding Entity, as shown in the following table:
symbol | The entity code |
© | © |
selections | ¥ |
® | ® |
> | > |
< | < |
& | & |
Especially for symbols like ©, do not copy a Unicode character directly from the UI. Copying a unicode character directly from the UI would be ugly. It takes the symbol from the font used.
17. Img empty SRC problem
Sometimes you need to write an empty img tag and dynamically assign SRC to it in JS, so you might write something like this:
<img src="" alt>Copy the code
The problem with this is that if you write an empty SRC, the browser will assume that SRC is the link to the current page and will request the current page again, similar to if you write an A tag with an empty href. A similar problem occurs if the image is background-image. What to do at this point? If you write a url that doesn’t exist, the browser will report a 404 error.
There are two solutions I know of. The first is to write SRC as about:blank, as follows:
<img src="about:blank" alt>Copy the code
This will load a blank page, which has no compatibility issues, will not load the current page, and will not report an error.
The second method is to write base64 with a transparent 1px pixel, as shown in the following code:
<img src="data:image/gif; base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">Copy the code
The second is probably more spec compliant, but the first is simpler and has no compatibility issues.
18. Effects of white space and line breaks on inline elements
Sometimes line breaks may introduce Spaces, as follows:
<form>
<label>Email: </label>
<input type="email">
</form>
Copy the code
There will be a space between label and input, which will cause the input to wrap when the sum of the width of the lable and the width of the input is equal to that of the form. Sometimes you will find that there is an extra space. And this space is caused by a newline. At this point you might ask why there are no Spaces in the newlines between <form> and <label> and between <input> and </form>. This is because blank text at the beginning of a block-level element is ignored, as shown in the Chrome source code:
// Whitespace at the start of a block just goes away. Don’t even
// make a layout object for this text.
Also, blank text nodes following block-level elements will not participate in rendering, i.e., something like this:
<div></div>
<div></div>
Copy the code
There is a textNode textNode between the two divs, but it does not participate in rendering.
Note that the comment tag is a normal page tag, and a node is created for it, but it does not participate in rendering.
19. Name classes using lowercase letters followed by an underscore
Use as follows – connect, do not use hump:
<div class="hello-world"></div>Copy the code
20. Custom labels are not recommended
Is it possible to use custom tags, as angular does with custom tags:
<my-cotnainer></my-container>Copy the code
Custom tags are generally not recommended, and Angular has a switch to use custom tags. While using custom tags is legal, as long as you give it display: block, it looks like a div, custom tags are still a bit of an alternative for both SEO and normalization reasons, although you might think they’re semantically better.
21. Heavy complex ids and duplicate attributes
We know that if we write two identical ids in the page, we will only fetch the first one when we look up the DOM. Similarly, we will only fetch the first one for duplicate attributes, as follows:
<input class="books" type="text" name="books" class="valid">Copy the code
The second class will be ignored. What if the className is repeated? Duplicate classnames are not valid, so you should avoid duplicate classnames if you operate on native classnames directly.
var input = form.books;
input.className += " valid";Copy the code
If executed repeatedly, className will have a duplicate valid class.
22. Property setting styles are not recommended
For example, if you want to set the width and height of an image, you might write:
<img src="test.jpg" alt width="400" height="300">Copy the code
This is not supported in Safari on ios, so you can experiment on your own.
Or table can also have some Settings:
<table border="1"></table>Copy the code
CSS is used for Settings that can be set with CSS, except that the width and height of canvas need to be written in HTML, as follows:
<canvas width="800" height="600"></canvas>Copy the code
If you set it up with CSS it becomes a stretch, it becomes a blur.
23. Use appropriate labels
Label use should not be too monotonous:
(1) If the content is a table, use table, table has the advantage of self-adaptation; If it is a list, use the OL/UL label, which is more scalable
(2) Use input for input fields instead of writing a P tag and setting contenteditable= True, as this can cause cursor positioning problems on IOS Safari. Except for special effects
(3) If bold, use b/strong instead of setting your own font weight
(4) If it is a form, use the form tag
(5) If it is a hop, use the A tag instead of writing onclick jump yourself. You can’t put an A tag inside an A tag
(6) Use HTML5 semantic tags, such as nav for navigation, aside for sidebar, header/footer for top and tail, and article for independent parts of the page, such as user comments.
(7) If it isa button, it should write a button or <input type= “button” > instead of writing an A tag to set the style, because using button can set disabled, then use CSS :disabled, and :active. For example, set the feeling of the button being pressed when :active
(8) Instead of writing a <p class= “title” ></p>, do not use the title tag if the content is not a title
(9) Use the select TAB on the phone, there will be native drop-down control, mobile phone native select drop-down effect experience is often better, whether IOS or Android, and use <input type= “tel” > on the phone will play a phone number keyboard, <input type= “number” > <input type= “email” > will play the corresponding keyboard
(10) If it is a border line, use HR tag instead of writing a border-bottom style. Hr is easy to check
(11) if is wrap text should use p tags, instead of writing br, because p tag line spacing can be set with margin, but if is long text use div, because p tags inside cannot have p, especially when the data is given by the backend might with a p tag, so when the container can’t use the p tag.
24. Do not include HTTP images in HTTPS links
If an HTTPS page requests an HTTP image, it will cause the small lock on the left side of the browser address bar to be missing.
<img src="/ / static.chimeroi.com/hello-world.jpg">Copy the code
2. CSS coding specifications
1. File name specification
You are advised to use lowercase letters followed by a line in the file name. Why is that? Because it is more readable and looks cleaner, links are also used in this way, such as stackOverflow urls:
https://stackoverflow.com/questions/25704650/disable-blue-highlight-when-touch-press-object-with-cursorpointer
Or the github address:
https://github.com/wangjeaf/ckstyle-node
So why not use lowercase and underlined names like family_tree instead of camelback familyTree? C likes to name variables this way, but because underlining is harder to type (shift + -), camelback variables are more common.
Type =”text/ CSS “;
<link rel="stylesheet" href="test.css">Copy the code
Because the most important attribute in link is rel, you can do without type, but you can’t do without rel.
The same is true for JS. You can use type as follows:
<script src="test.js"></script>Copy the code
There are no compatibility issues.
2. Writing sequence of attributes
The order in which attributes are written makes no difference to the browser, except for priority overrides. But if the order remains consistent, a quick glance will tell you what type of attributes the selector has that affect it, so the more important attributes are usually put first. The order in which suggestions are compared is this:
You may think I usually almost write like this, so you have a better accomplishment. And I don’t think rules are dead, sometimes they can be flexible, like you might center a transform and put left/top/transform next to each other, which I think is fine, because it makes it easy to see what you’re doing.
3. Do not use style features for naming
Some people may prefer to use style features, such as:
.red-font{
color: red;
}
.p1{
font-size: 18px;
}
.p2{
font-size: 16px;
}Copy the code
And then you’re going to see a bunch of p1/ P2 /bold-font/right-wrap class names in its HTML, and that’s not going to work, so if you have a red-font and the next time you change the color of your UI, you’re not going to be able to write that class name, Or if you’re in reactive mode, the type that’s on the right will go down to the bottom when you’re on a small screen, so you don’t have to use the right. Some people take a look at the UI and see that it has three sizes: 18px, 16px, 14px. They write three classes, p1, P2, and P3, with different sizes for different classes. At first glance, this might seem generic, but when you look at his HTML, you’ll lose your mind. These P1 / P2 / P3 classes add up to 20 or 30 of them, all very dense. I think it would be better to use the title tag:
.house-info h2{
font-size: 18px;
}
.house-info h3{
font-size: 16px;
}
Copy the code
Because it’s bigger, it’s probably a heading, so why not just use the heading tag, don’t worry about it because the heading tag will have a default style.
Classes should be named using the logical meaning they represent, such as signup-success-toast, request-demo, agent-Portrait, company-logo, and so on.
If there are some styles that you think are really generic, you can use them as a class, like Clearfix, or some animation effects that are used in several places, but I think this kind of complex and generic can be used as a class by itself. But there is still a tendency to use meaningful names.
4. Don’t hack
Some people use hack comments when writing CSS, like this:
.agent-name{
float: left;
_margin: 10px;
//padding: 20px;
}
Copy the code
A semicolon is the attribute terminator, and everything from // to semicolon is ignored by the browser. However, this kind of comment is not recommended. Either change the.css file to.less or.scss file, and you can use the // comment more pleasingly.
There are also browser-specific hacks, such as the property beginning with * that are IE6 hacks. Whatever you do, don’t use hacks.
5. Selector performance
Do not write more than 3 selectors. Some people like to write sass or less with many layers, as follows:
.listings-list{
ul{
li{
.bed-bath{
p{
color: #505050;
}
}
}
}
}
Copy the code
A container is a layer, layer by layer, set down the bottom set of seven or eight layer, such a long performance of the selector is poorer, because the Chrome is using a recursive from the last selector matches until the first, the selector, the matching of time is more long, so the time is not long, and the readability of the code is more bad, In order to see what the style of the p tag is at the bottom, I have to go up layer by layer to see where the P is. 7 or 8 levels of indentation in the code also looks tired.
It is usually good to write only two or three important selectors, not every container, but the important target element class or ID.
The last selector tag should be used less, because if you write a.container div{}, then all the divs on the page will match the first time, because it matches from right to left. The nice thing about this is that you don’t have to have a lot of classes in your HTML, but it doesn’t scale very well, so don’t use it lightly. It needs to be carefully considered and used if appropriate, at the very least not overused.
6. Avoid selector errors
Sometimes your style will be influenced by someone else’s style, or your style will accidentally affect someone else’s, either because the class name is the same as someone else’s, or because the selector is too broad, for example, someone wrote in his own page:
* {
box-sizing: border-box;
}Copy the code
As a result, the public popbox style on other pages failed. On the one hand, do not write a * global match selector, which is too large in terms of performance and scope, such as in a selector with three child selectors:
.house-info .key-detail .location{}Copy the code
In all three containers, * is applicable, and some attributes are inherited, such as font size, which causes all three containers to have font size and then layer upon layer.
Another case is the abuse of first-child and :nth-of-type selectors, which have the effect of poor extensibility. As soon as the HTML is changed, the style will not work, or other irrelevant elements will be affected. But is not to say that the selector can’t use, as long as well with very convenient, for example, in all the li to make the final margin of li – left a little bit small, you can wrote:
.listing-list li:last-child{
margin-left: 10px;
}
Copy the code
This is probably better than if you just nested a class. However, don’t overuse it. Use it when appropriate, not just to minimize class names.
7. Reduce coverage
Overwriting is a common strategy, and a less elegant way to do it, in order to have 20px space between each house, but no space between the first house:
.house{
margin-top: 20px;
}
.house:first-child{
margin-top: 0;
}
Copy the code
Instead, it could look like this:
.house + .house{
margin-top: 20px;
}
Copy the code
The only way to hit this selector is if you have a dot house in front of it, and because the first dot house doesn’t have a dot house in front of it, you don’t get a shot, so it looks a lot cleaner.
There is also the case, as shown in the following code:
.request-demo input{
border: 1px solid # 282828;
}
.request-demo input[type=submit]{
border: none;
}
Copy the code
Instead, there is a :not selector:
.request-demo input:not([type=sbumit]) {border: 1px solid # 282828;
}
Copy the code
This makes the code look much more elegant.
There is one type of coverage that is worthwhile, and that is the response inside the small screen style over the large screen, as follows:
.container{
width: 1080px;
margin: 0 auto;
}
@media (min-width: 1024px) {.container{
width: auto;
margin: 0 40px; }}Copy the code
The large screen style can also be written as:
@media (min-width: 1025px) {.container{
width: 1080px;
margin: 0auto; }}Copy the code
I wrote it this way at first, to follow the rule of reducing coverage, but it turns out that it’s a bad practice, the code is messy, and the nice thing about writing overlays is that you can obviously see in the browser that the smaller screen style overlays the larger screen style and how it looks on the larger screen.
8. Use CSS3 selector to complete some advanced functions
As mentioned above, not keeps code simple, and there are other useful ones. For example, if there are only two, the ratio of one is 50%, and if there are three, the ratio of one is 33%. This can be achieved with CSS, as follows:
.listing-list li{
width: 33%;
}
.listing-list li:first-child:nth-last-child(2)..listing-list li:first-child:nth-last-child(2) ~ li{
width: 50%;
}
Copy the code
When Li is the first element and the next-to-last element and its adjacent li is hit by the second set of selectors, its width is 50%, i.e., there are only two Li’s to satisfy this condition.
Also can borrow: hover/focus / : invalid / : disabled such as pseudo class selectors do simple interactions.
9. Use less! important
Important is used to override properties, especially CSS style properties, but should be minimized. Sometimes you write just to be lazy! Important, think this priority is the highest, often mantis chasing cicadas, yellow sparrow after, it may not be long before you have to write a higher priority to cover up, so slightly embarrassing. So use less if you can. If you want to overwrite, you should first add the weight of the selector.
10. Write lots of comments
“Two things annoy a programmer. The first thing is that he is asked to document his code. The second thing? Someone else’s program left no documentation.” The same goes for comments, which are more relaxed when you see lots of green comments, and more depressed when you see crumpled, uncommented code. Comments for CSS can include:
(1) Comments at the top of the file
/* * @description * @author yincheng.li */
Copy the code
(2) Module annotation
/* Details page loan calculator */Copy the code
(3) Simple comments
/* To remove the gray background of input fields and forms when clicked */
input.form{
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
}
Copy the code
(4) TODO notes
Sometimes when you look at the source code you’ll see some comments for TODO:
/* TODO(littledan): Computed properties don't work yet in nosnap. Rephrase when they do. */Copy the code
Indicates that the code needs to be improved or that some bugs need to be fixed later. The TODO comments are typically highlighted by the editor.
Be careful not to write some wrong and misleading comments or more nonsense comments, this is better not to write, as follows:
/* The size of the title should be larger */
.listings h2{
font-size: 20px;
}
Copy the code
11. Typesetting specifications
If you use sublime, there is a Tab Size in the lower right corner of the app. Select Tab Size 4 and then tick the Indent Using Spaces at the top. When you hit a TAB indent it automatically converts to 4 Spaces. If you are using vim, add or edit the ~/. Vimrc file to add a new line:
:set tabstop=4Copy the code
It also automatically changes the indentation to 4 Spaces, and other editors find the Settings themselves. Because \t displays different lengths in different editors, changing it to a space can be formatted consistently on different people’s computers.
Multiple selectors share a style set, each on a line, as follows:
.landing-pop..samll-pop-outer..signup-success{
display: none;
}
Copy the code
Each attribute name is preceded by a space after the colon, and the ~, >, and + selectors are preceded by a space:
.listings > li{
float: left;
}
Copy the code
12. Attribute value specification
(1) If the value is 0, it usually doesn’t have a unit
Such as:
.list{
border: 1px solid 0px;
margin: 0px;
}
Copy the code
Should be changed to:
.list{
border: 1px solid 0;
margin: 0;
}
Copy the code
There are exceptions, however, where the unit of time must be second s. Both of the following are illegal:
transition-duration: 0;
transition: transform 0 linear;
Copy the code
(2) Color value in hexadecimal, less RGB
As follows:
color: rgb(80, 80, 80);Copy the code
Should be changed to:
color: # 505050;Copy the code
Since using RGB is a function, it also computes the conversion. Use RGBA with transparency.
If the six numbers are the same, write three:
color: #ccc;Copy the code
(3) Notice the difference between border None and 0
The following two meanings are the same:
border: 0;
border-width: 0;
Copy the code
And these two are the same:
border: none;
border-style: none;
Copy the code
So 0 and None can get rid of borders.
You may say that packing tools will actually help me in the end, but it’s important to maintain good writing habits.
13. Font-family: arial, sans-serif
SFUIText font = -apple-system in Safari and BlinkMacSystemFont in Chrome; SFUIText font = -apple-system in Chrome
font-family{
font-family: -apple-system, BlinkMacSystemFont, sans-serif;
}
Copy the code
Another example is Microsoft Yahei, many Chinese websites use this font, to write:
font-family{
font-family: Microsoft YaHei;
}
Copy the code
In addition, font family cannot be arbitrarily set in code if a custom font is used. The following code:
.title{
font-family: Lato Bold;
}
Copy the code
Because if you write multiple font-families in your code, it will be very difficult to replace the entire font of the page. The correct way to do this is:
h1.strong.b{
font-family: Lato Bold;
font-weight: normal;
}
Copy the code
If you need to bold, use the title tag, or the B /strong tag, and change font weight back because that font is already bold. If font weight is bold again, the browser will use its own algorithm to bold it. If it is fine body how to do, on the one hand, the general fine body is used less, on the other hand, there is no fine body tag, you can pass the way of the set class.
14. Don’t set z-Index too large
Some people like to set z-index big:
z-index: 99999;Copy the code
He thought he was the eldest, and no one could be taller than him. But when mantises chase cicadas, the yellow sparrow is behind them.
z-index: 999999;Copy the code
In general, the z-index of your page’s business logic should be in single digits.
15. Merge attributes
The common saying is to merge properties to improve performance, but in Chrome each property is separate, even if you merge, it will help you to split out, such as left/right/top/bottom, but we still recommend the merge, because it makes the code look more concise. Less code, as follows:
.container{
margin-top: 20px;
margin-left: 10px;
margin-right: 10px;
}
Copy the code
It can be written as:
.container{
margin: 20px 10px 0;
}
Copy the code
Make sure not to overwrite other Settings, such as margin-bottom 0.
Such as:
.banner{
background-image: url(/test.jpg);
background-position: 0 0;
background-repeat: no-repeat;
}
Copy the code
Can be changed to:
.banner{
background: url(test.jpg) 0 0 no-repeat;
}
Copy the code
16. Note that float/absolute/fixed positions are forcibly set to blocks
The following code:
a.btn {
float: left;
display: block;
width: 100px;
height: 30px;
}
Copy the code
The second line of display: block is useless because if you float, the target element will have the properties of the block-level box model, even if you display: table-cell or inline. If you are display: flex, float will be ignored.
Similarly, absolute and fixed positions have the same effect, turning row elements into block-level ones.
17. Clear the float
There are several ways to clear the float, usually using the Clearfix method, although this method has defects, it is relatively simple and can be used in most scenarios, a compatible IE8 and above clearfix writing method:
.clearfix:after{
content: "";
display: table;
clear: both;
}
Copy the code
Don’t clear the float by adding an extra element to the end, which is possible but low.
18. Use of quotation marks
(1) the font-family
Font-family: arial, sans-serif; mso-ascii-font-family: arial, sans-serif; mso-ascii-font-family: sans-serif;
font-family:"inherit","serif","sans-serif","monospace","fantasy", and "cursive"Copy the code
(2) URL of background
background-url: url("//cdn.test.me/test.jpg");Copy the code
You can not add, but there is a must add, that is, the URL with special characters without escaping, as follows:
background-url: url(//cdn.test.me/hello world.jpg)Copy the code
The browser will load //cdn.test.me/hello and say 404. This is usually the case when the image is uploaded by the user, the name of the image has Spaces, and the url given by the back end does not handle special characters. Therefore, when the URL is mutable, it is best to enclose quotation marks:
background-url: url('//cdn.test.me/hello world.jpg');Copy the code
The browser should then load the image properly. This situation is best avoided at source, but we can also make it compatible.
(3) Single or double quotation marks
It is recommended that HTML use double quotation marks and CSS use single quotation marks.
19. CSS animation specification
(1) Do not animate with the all attribute
Do not use the all attribute when animating transition. Some browsers may have some problems with this:
transition: all 2s linear;Copy the code
There may be some strange wobbles in Safari. The correct way to do this is to animate whichever property you want, and if there are more than one, separate them, as shown in the following code:
transition: transform 2s linear.opacity 2s linear;Copy the code
(2) Use transform instead of position to animate
If you can animate with transform, you will not use left/top/margin, etc., because transform does not cause redrawing and performance is much higher than position, especially on mobile devices. Basically all displacement animations can be done by transform, without using CSS2 properties such as a box popping from right to left.
(3) Prefer to use CSS animation instead of JS animation
For example, to pop a box from bottom to top, you can use jQuery’s slideUp function, or write your own setInterval function, but these are no better than CSS. Using CSS, the initial state moves the translate box off-screen, then clicks on it with a class that transforms to 0, and then animates transition.
20. Don’t break words
Words or numbers in English will be automatically cut to the next line if the current line does not fit, resulting in different lengths of each line, which may not be very beautiful sometimes. However, word-break is not acceptable.
hyphens: auto;Copy the code
It will split the words into the form of a – link, which seems to be quite reasonable, but because it is not completely broken, some words can not be broken, the phenomenon of different lengths seems to be more obvious, some words are split into two lines, so it is better not to add.
Therefore, don’t use a hyphenate.
21. Do not set font family for ICONS
This is the same as the setting of the font-family mentioned above. Do not manually set the font-family in the code as follows:
.icon-up:before{
content: "\e950";
font-family: "icon-font";
}
Copy the code
The correct way to do this is to create a.icon class for the.icon-up element.
.icon{
font-family: "icon-font";
/* Better Font Rendering =========== */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
Copy the code
Because we may have to add some other Settings, it’s good to have a.icon class to handle. Don’t manually set font-family one by one.
22. Set common style reset
Each browser has its own UA style, and these styles are not uniform, so you need to do the style reset, common reset:
/* Internet Explorer has its own font family for input controls, which needs to be unified */
input.textarea.button{
font-family: inherit;
}
/* Chrome adds a blue outline*/ when entering control aggregation
input:focus.textarea:focus.select:focus{
outline: none;
}
/* Remove the textarea pull size function */
textarea{
resize: none;
}
/* IOS Safari magnifies the font in landscape, and the second property makes scrolling smoother */
html{
-webkit-text-size-adjust: 100%;
-webkit-overflow-scrolling : touch;
}
/* Align the margin of the tag with the line height of the p tag
body.p.h1.h2.ul.ol.figure.li{
padding: 0;
margin: 0;
}
h1.h2.p{
line-height: 150%;
}
/* Remove the default select style */
select{
-webkit-appearance: none;
}
/* If there is any input, IE will add a big X */ to the right of the input box
input::-ms-clear{
display: none;
width: 0;
height: 0;
}
/* Remove the triangle */ on the right side of the number input box
input::-webkit-inner-spin-button{
-webkit-appearance: none;
}
input::-webki-outer-spin-button{
-webki-appearance: none;
}
Copy the code
23. Image compression
It is recommended to use Tinypng, which can reduce the quality of the image at a low level, and press the image very hard. It is better than directly setting the compression quality in PS. For colorful images, use JPG instead of PNG, which is much larger. For vector images like logos, use SVG. Generally speaking, the picture should be controlled within 300K, especially the banner header, and the size of the picture should also be controlled.
24. Use background and IMG correctly
There are two ways to display an image: by setting the BACKground-image of the CSS, or by using the IMG tag.
Use the IMG tag for header images, and use background for background images, since img allows you to write an Alt attribute for SEO, while background images don’t require SEO. Although background has a background-position: Center Center, it is good, but the header image should use img, and center yourself, otherwise you can’t do SEO.
25. Responsive specifications
The worst thing to do in responsive development is not to use rem in combination. Use rem at all, or not at all, and don’t use transform: scale to reduce your text size because it will look a bit weird. Everyone else is 14px and you are 13.231px too small. The general rule of responsiveness is to keep the middle or sides of the space the same, and then reduce the width of the body content.
26. 适当使用:before/:after
:before and :after can be used to draw visual auxiliary elements such as triangles, short dividers, short vertical lines, etc. to reduce unnecessary tags on the page. But don’t use before/after for normal elements like text on a page.
27. Use absolute positioning less
First of all, the rendering performance of absolute positioning elements will be relatively high, because it is independent, the calculation will be less, and it can be used well. If you use absolute for the main layout of a page, it is definitely not desirable, because the scalability of absolute positioning is very poor, you can not change the position of each element, float can be used, although float performance is relatively poor, both practicality and compatibility is good.
28. Use less inline-block layouts
Some people like to use inline-blocks, especially if you’re just learning to cut diagrams, because blocks wrap lines, and inline-blocks don’t wrap lines and have a box model, so inline-blocks are very handy, whereas floats are more complicated and have to deal with things like cleaning up floats. The following layout:
You should write li and then let li float, if you have li display:inline-block you can do that too. But if you use inline-block a lot, you might have some strange problems. You usually have to put a block inside an inline-block element. Inline-block is an inline element, and a block is a block-level element. This should be more natural with float/ Flex, and if you’re comfortable with float you’ll find it much better than inline-block and much more professional. If you’re new to Flex, try switching to Flex, and if you’re new to float, try it. You can only be more flexible when you use a variety of cutting methods.
29. Image center and width and height Settings
Generally speaking, UI images show a fixed width and height, but the actual image length and width are not fixed, most of the images are larger than the length, and a small number of images are larger than the width. Therefore, it needs to be shown in the center, as shown below:
The black box in the middle is the display area. The short side of the picture is the same size as the side of the window. The other side is stretched to the original scale of the picture and then displayed in the center. This has to be done with JS, because you don’t know whether the long side is bigger or the wide side is bigger until the image is loaded. The following code:
<div class="img-container">
<img src="test.jpg" alt onload="resizeImg(this, '400px', '300px'">
</div>
Copy the code
With a resizeImg function, do the processing in the onload function. Then center it with CSS:
.img-container{
position: relative;
width: 400px;
height: 300px;
}
.img-container img{
position: absolute;
left: -9999px;
right: -9999px;
top: -9999px;
bottom: -9999px;
margin: auto;
}
Copy the code
The above code uses a margin: auto as the center.
30. Mobile improves the range of point-able areas
Some ICONS on the mobile terminal, such as X, may be designed to be small, so it is not easy to click. Therefore, to improve the range of clickable area, you can add padding, as follows:
.icon-close{
position: abosulte;
right: 0;
top: 0;
padding: 20px;
}
Copy the code
This adds a circle to the area and makes it easier to point.
31. Do not set input line-height
If you set line-height for your input, you might want to center it vertically:
.request-demo input{
height: 40px;
line-height: 40px;
}
Copy the code
Set the line height is a very high value, this will lead to Safari input cursor | becomes huge, so if you want to center, using padding.
32. Prohibit body sliding on the moving frame
Because IOS Safari, when you switch the input field, it’s going to pop up a lot, because it’s going to put the keyboard away when you’re cutting, and it’s going to pop up again, and it’s going to pop up a little bit, but if you disable the body, it’s not going to do that, and there’s two ways to do that, The first is to fix the body, and the second is to set the body overflow: hidden. The second is relatively simple. IOS10 won’t blink at all, IOS9 will still blink.
33. The treatment of gradient
Sometimes inside the UI will have some of the gradient effect, can’t copy the CSS, this time can use an online tool that generates gradient CSS:www.cssmatic.com/gradient-ge… , but you need to manually tune the UI to look exactly like it, or you can directly tune the UI to its desired effect, which will generate highly compatible CSS:
background: #fff;
background: -moz-linear-gradient(left, #fff 0%, #d2d2d2 43%, #d1d1d1 58%, #fefefe 100%);
background: -webkit-gradient(left top, right top, color-stop(0%, #fff), color-stop(43%, #d2d2d2), color-stop(58%, #d1d1d1), color-stop(100%, #fefefe));
background: -webkit-linear-gradient(left, #fff 0%, #d2d2d2 43%, #d1d1d1 58%, #fefefe 100%);
background: -o-linear-gradient(left, #fff 0%, #d2d2d2 43%, #d1d1d1 58%, #fefefe 100%);
background: -ms-linear-gradient(left, #fff 0%, #d2d2d2 43%, #d1d1d1 58%, #fefefe 100%);
background: linear-gradient(to right, #fff 0%, #d2d2d2 43%, #d1d1d1 58%, #fefefe 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fff', endColorstr='#fefefe', GradientType=1 );Copy the code
34. Margin-left /margin-right can be set directly for inline elements
Some people set span display: inline-block to spread the span:
span.phone-numer{
display: inline-block;
margin-left: 10px;
}
Copy the code
The inline element can be directly left or right of the margin, so it can be stretched out without setting inline-block:
span.phone-numer{
margin-left: 10px;
}
Copy the code
In addition it is important to note the img/input/textarea/button default is the inline – block, also need not set.
JS coding specification
1. Name variables
There is a chapter on variable naming in the complete Code book, and this is illustrated with the advice of the book. In general, a variable name should accurately and completely describe what the variable says, specifically:
(1) Variable names should not be proud of being short
Good variable names and bad variable names like the following:
Bad variable names | Okay, variable name |
inp | input, priceInput |
day1, day2, param1 | today, tomorrow |
id | userId, orderId |
obj | orderData, houseInfos |
tId | removeMsgTimerId |
handler | submitHandler, searchHandler |
The variable names on the left are not very clear, the code does not scale well, and when the code needs to add features, it is easy to name obj1, obj2, obj3 in an abstract way. So start with names that make sense, not short, generic names.
Of course the variable name is too long is not good, such as maximumNumberOfTeamMembers.
(2) Do not use computer jargon for variable names
Variable names should refer to the problem domain and come from the real world, not the computer world. For example, if you have a name like texareaData, you should have a business-specific name like leaveMsg.
(3) The antithesis of variable name should be clear
Such as up/ Down, begin/end, Opened /closed, Visible/Invisible, and SCource/Target, clear alignment can make the meaning and purpose of two variables very clear.
(4) Beware of temporary variables
Some prefer to take variables like temp and obj. It is acceptable to run out of temporary variables in two lines of code and not use them in subsequent code, such as swapping two elements of an array. But some people take a temp, and the next dozen lines of code use that temp, and it gets confusing. Therefore, we should use temp class variables as little as possible, as follows:
var temp = 10;
varLeftPosition = currentPosition + temp, topPosition = currentPosition-temp;Copy the code
Should be changed to:
var adjustSpace = 10;
varAdjustSpace = Public adjustSpace (adjustSpace);Copy the code
(5) Bool variable
The book Complete Code recommends that Boolean variables do not start with is/do, as in:
var isMobile = true,
isError = true,
doUpdate = false;
Copy the code
Can be changed to:
var mobile = true,
error = true,
updated = false;
Copy the code
There are some other common names, such as the done/found/successs/ok/available/complete etc, combined with the specific context:
var ajaxDone = true,
fileFound = false,
resourceUpdated = true;
Copy the code
Also, don’t use negative nouns like notOk and notReady because it’s weird to use negative nouns like if(! NotOk). Use positive Boolean variable names. If it is a parameter, it can be combined with ES6 default parameter values.
(6) Use correct syntax for variable names
Don’t use Chinese pinyin, such as Shijianchuo should be timestamp, add s if plural, or add List, such as orderList, menuItems, and add Ed, such as updated/found, if ongoing, add ING, Such as calling.
2. Assign values when declaring variables
Declare three variables as follows:
var registerForm,
question,
calculateResult;
Copy the code
The above is definitely valid JS syntax, but the purpose of these three variables can be confusing, especially the second question in the middle, what is the question? But when you assign an initial value to the above variable:
var registerForm = null,
question = "",
calculateResult = 0;
Copy the code
“Question” is a string of questions, “result” is a number, and “form” is an object. This also makes it easier for the JS interpreter to do some optimization ahead of time so that they don’t have to wait until they are used to know what type these variables are.
3. Determine the return value type of the function
The following code:
function calculatePrice(seatCount){
if (seatCount <= 0) {
return "";
} else {
return seatCount * 79; }}Copy the code
This code can return either an integer or a string, which can be confusing and not very high in terms of code performance. Although it is legal JS syntax, the return type of a function must be consistent. You might say I’m using the above function as the value to display in the input box. If it’s negative or zero, then the input box doesn’t display anything, so it returns an empty string. Even if this is the case, it is not recommended. In the long run, you should organize your code in other ways. Develop a strongly typed code style that is less buggy and easier to extend. Also, if you use a variable as a number, don’t use it as a string, because that can be confusing. Microsoft Typescript is a strongly typed writing syntax. Many large projects use Typescript to write JS. If you are interested, you can continue to learn how to write Typescript.
4. Do not assign a variable to undefined
Undefined means a variable is undefined, so you define a variable and then you say it’s undefined. The problem with this is ambiguity, because we often use undefined to determine if a variable is defined:
if (typeof window.HTMLVideoElement === "undefined")Copy the code
If an assignment should be null, such as an object with a value of null, a number with a value of 0, or a string with a null character, then you might say that 0 is also a normal number. What if assigning a value of 0 causes me to mistake it for a normal number? If your numbers are all non-negative, you can start with -1, or if not, NaN.
The return value of a function should not explicitly return undefined.
5. Typesetting specifications
A popular space and indentation type is shown in the following code:
// comma followed by a space,) {with a space in the middle
function getSeatDiscount(seatCount, currentPrice) {
// The binocular operator is left and right with Spaces
var originPrice = editOrder.getSeatsPrice(seatCount);
return Math.round((originPrice - currentPrice) / originPrice * 100);
}
Copy the code
A line is too long to wrap, such as V8 source code inside the longest line is 70 characters, more than the line:
function ArrayUnshift(arg1) { // length == 1
//if is a line break, and if (with a space in between)
if (len > 0&& UseSparseVariant(array, len, IS_ARRAY(array), len) && ! %object_is_sealed(array)) { SparseMove(array,0.0, len, num_arguments);
} else {
SimpleMove(array, 0.0, len, num_arguments); }}Copy the code
It’s a good practice to break a line of code that’s too long. Too long makes it seem like a chore. Basically, a line should be no more than 100 characters long, and any more should be wrapped, either in comments or code.
Use === instead of ==
This is the same as above. We want to write in a strongly typed style, so don’t use ==. If there is a type cast, do not make others guess that there is a type cast.
null= =undefined //true
' '= ='0' //false
0= =' ' //true
0= ='0' //true
' \t\r\n '= =0 //true
new String("abc") = ="abc" //true
new Boolean(true) = =true //true
true= =1 //true
Copy the code
7. Reduce magic number
Give some important constants a name, such as the following code:
const ONE_DATE = 3600 * 24 * 1000;
var tomorrow = today + ONE_DATE;
Copy the code
Another example is the following bad writing:
DialogHandler. ShowQuestionNaire ("seller"."sell".5.true);Copy the code
The four constants above can be confusing, so give them names if you can, and comment them if you don’t feel comfortable.
8. Don’t let code run exposed to the global scope
One reason is that variables in the global scope take longer to find. The second reason is that variables in the global scope can pollute the global scope, sometimes with unexpected results like the following:
var name = "hi boy";
console.log(window.name);
Copy the code
A variable is defined, but window.name is used to have this property, which is usually used to pass data across domains. If you set the name variable, the global window.name will be overwritten.
9. Let /var/const
ES6 has a new let/const definition variable. Using let has some benefits, such as:
(1) Avoid variable repeated definition
let me = "go";
// Uncaught SyntaxError: Identifier 'me' has already been declared
let me = "go";
Copy the code
When using the Babel loader to package, it does a static check:
Module build failed: Duplicate declaration “me”
(2) The variable scope of the for loop is independent
for(let i = 0; i <= 4; i++) {
tasks.push(function(){
console.log("i is " + i);
});
}
Copy the code
Use let to make the scope of I independent for each run in the for loop. And variables defined in for are not visible outside the for loop.
Babel uses a function inside the for loop and takes I as an argument to the function:
var _loop = function _loop(_i) {
tasks.push(function () {
console.log("i is " + _i);
});
};
for (var _i = 0; _i <= 4; _i++) {
_loop(_i);
}
Copy the code
Let makes sense because it avoids variable duplication. Therefore, let variables are recommended. So the variables below this specification will use let instead of var.
Const is good for giving a constant a name, as mentioned above:
const ONE_DAY = 3600 * 24 * 1000;
const adjustSpace = 10;
Copy the code
Or you can define some other variable that doesn’t need to be changed, in case it’s accidentally changed by other code.
10. Clean code
(1) Use ternary operation instead of simple if-else
Write one line instead of three, as follows:
let seatDiscount = 100;
if(seat < 5) {
seatDiscount = 90;
} else if(seat < 10) {
seatDiscount = 80;
} else {
seatDiscount = 70;
}
Copy the code
We can change it to the ternary operator:
let seatDiscount = seat < 5 ? 90 :
seat < 10 ? 80 : 70;
Copy the code
The code was reduced from 8 to 2 lines.
(2) Use arrow functions instead of simple functions
For example:
setTimeout(function(){
window.location.reload(true);
}, 2000);
Copy the code
Can be changed to:
setTimeout((a)= > window.location.reload(true), 2000);Copy the code
The code went from 3 lines to 1.
11. Be careful not to execute long JS code
For the average amount of data on a page, addition, subtraction, multiplication and division are not enough to cause performance bottlenecks. The easiest bottleneck is DOM manipulation, especially in large quantities, where hundreds or thousands of levels at a time can cause pages to stall. In particular, don’t constantly modify the DOM in a for loop like this:
for(var i = 0; i < 1000; i++) {
ul.appendChild(li);
}
Copy the code
This can first spell li, and then append to UL, as follows:
var fragment = document.createDocumentFragment();
for(var i = 0; i < 1000; i++) {
fragment.appendChild(li);
}
ul.appendChild(fragment);
Copy the code
If you use JQ, you should render the template and append it to the DOM once, rather than repeatedly. Today’s browsers are generally smart and do some optimization, but we can’t always count on browsers to be optimized.
However, if you have a very large amount of data, you may need to use setTimeout to process the data in segments, or even multithreading. Using setTimeout you can do this:
function sliceWorks(data, finishedCallback) {
if(! data.length) { finishedCallback(); }else {
const PIECES = 100;
process(data.splice(0, PIECES));
setTimeout((a)= > sliceWorks(data, finishedCallback), 100); }}Copy the code
We use a recursion to divide the data into 100 segments and call the callback function when the data is processed.
12. Write lots of comments
This is similar to the CSS specification:
(1) Comments at the top of the file, including description, author, update
/* * @file listing-detail.js * @description listing detail page js main file, * @author yincheng.li * @update (yincheng.li 2017/8/19) */
Copy the code
(2) Annotation of function
/* * Processing logic related to the search interface display * @namespace */
var searchWinHandler = {
@param {bool} realTimeSearch whether to search in real time @param {HTMLFormElement} form search for form DOM elements * */
init(realTimeSearch, HTMLFormElement){
}
* * @param {object} jquery event * @trigger will trigger the search button click event, TODO temporarily uses a global variable flag, which is not a very good implementation * although it is more convenient */
closeFilterSpan(event){
}
};
Copy the code
The above @auhor @return are all comment tags. Other commonly used comment tags include:
/* @class represents a class @constructor @deprecated @global variables @namespace objects with namespace functions, such as $.fn.remove, $.fn.append, $and fn are a namespace, and fn is a subnamespace of $. @this where does this point to @throws what exceptions may be thrown in this function @version Current version */
Copy the code
(3) Annotation of variable definition and code
I annotated some important variables to indicate their purposes, and annotated some core code logic or more complex business logic. I wrote 5 cases and what each case represents. Code added to fix a bug, stating what the problem is to be solved. There are also some confusable judgments, why there are four if judgments, why the code to this if judgment fails and then returns; Some constant comments, why does the number 100 pop up; If you change someone else’s code, why change it? And so on. Such as:
var requestData = {
listingId: listingData.listingId,
page: 1.// Change 200 to 5, click More to refresh the page, there is no other use,
// There is no need for so many requests, which can seriously affect performance
pageSize: 5/ / 200
};
Copy the code
In short, it is good to write more comments, as long as it is not nonsense:
// define a number variable
let number = 5;
Copy the code
Or an incorrect comment that doesn’t fit the logic.
There is also a typesetting comment, the corresponding relationship between the closing brackets:
} //function ajax
} //switch(b)
} //if(a)
} //searchHandler
Copy the code
For example, I want to add the code after switch(b). When I see this comment, I know exactly where I need to press Enter. However, it is generally not recommended to have very deep nested code, or to write very long, hundreds of lines per function.
13. Don’t nest code too deeply
Some people often have seven or eight layers of code, take JQ code as an example, as follows:
var orderHandler = {
bindEvent: function(){$(".update-order").on("click".function(){
if(orderStatus === "active"){
ajax({
url: "/update-order".success: function(data){
for(let i = 0; i < data.orders.length; i++){ dom.append(); }}}); }else {
ajax({
url: "/create-order".success: function(data){}}); }}); }};Copy the code
The code above has the deepest indent of eight layers, which you might think is pretty logical, but it’s also a bit spaghetti. If I had to write the above code, I would organize it like this:
var orderHandler = {
sendUpdateOrderReq: function(requestUrl, successCallback){
ajax({
url: requestUrl,
success: successCallback;
});
},
updateOrder: function(event){
let requestUrl = orderStatus === "active" ? "/update-order"
: "create-order";
// Update the order callback function
let activeUpdateCallback = function(data){
for(var i = 0; i < data.orders.length; i++){
console.log(data.orders[i].id); }};// Create the order callback function
let inactiveUpdateCallback = function(data){};let successCallback = {
active: activeUpdateCallback,
inactive: inactiveUpdateCallback
};
// Make a request to process the order
searchHandler.sendUpdateOrderReq(requestUrl,
successCallback[orderStatus]);
},
bindEvent: function(){$(".update-order").on("click", searchHandler.updateOrder); }};Copy the code
First change the bound anonymous function to a named function. This has the advantage that you can disable it whenever you want. Then you can reduce the indentation by one layer, and then determine the callbacks based on orderStatus by variable first, rather than backlog them all at the same time. Separate out the function that sent the request as a function, reducing the indentation by two layers. The deepest indentation above is 4 layers, reduced by half. And you’ll find that the logic of writing code is much clearer. I can just glance inside bindEvent and see which DOM is tied to which event, and then JUMP to the corresponding callback function to see which DOM event I’m interested in, rather than having to drag a page or two to find the target DOM in bindEvent. And keep updateOrder as a separate function that can be used elsewhere if needed, such as for a combined function operation. Another layer of abstraction for Ajax is that it’s so common that people know what to do at a glance, and separating it into a different place makes the actual business code much simpler, such as making a request above, and once I’ve got the callback function ready, I just need to execute one line of code.
If you indent too many layers, you’ll lose 30 or 40 characters of space on a line, which is not very good, and you’ll end up with a lot of closing parentheses at the end, as mentioned above, and you’ll end up with two or three hundred lines of a function.
14. JQuery coding specification
If you use jQuery.
Closest instead of parent
Try not to use parent to get DOM elements:
var $activeRows = $this.parent().parent().children(".active");Copy the code
This code doesn’t scale well, and if the DOM structure changes, the logic will be broken in minutes, such as one day you might have a div to clean up the float, but a button can’t be clicked.
Closest should be used, eg:
var $activeRows = $this.closest(".order-list").find(".active");Copy the code
Locate the last common ancestor node of the target element and find the target element. This will not happen, as long as the container class has not changed. If you need to deal with adjacent elements that are not your own, you can do this:
$this.closest("li").siblings("li.active").removeClass("active");
$this.addClass("active");Copy the code
Sometimes you can put all the li first into a class, and then put himself back is desirable, because the browser will optimize, not seeing the DOM operation immediately, will be arranged in a queue, and then to deal with, so the actual DOM manipulation to add a class first and then get rid of the net operation is likely to be won’t execute.
(2) The performance of the selector
The following code:
$(".page ul").addClass("shown");
$(".page .page-number").text(number);
$(".page .page-next").removeClass("active");
Copy the code
The code above does three global lookups that could be optimized:
var $page = $(".page");
$page.find("ul").addClass("shown");
$page.find(".page-number").text(number);
$page.find(".page-next").removeClass("active");
Copy the code
Do a global search, the subsequent DOM search is narrowed down to the $page range, $page nodes only a few dozen, in a few of the document to find a few hundred or thousands of nodes in the search is much faster. JQuery also uses querySelectorAll to query the DOM. This function can be used in other DOM nodes besides document.
(3) Off when needed before the event
Some like tying events before you off, that feeling can be sure, but if you bind event is anonymous, you are likely to be tied to other JS files off off together, and not easy to expose question, sometimes you may be repeated binding events, such as point a button to bind a leads to tied several times, So here’s the root cause. You should make sure that the event is tied only once, rather than making sure that it is off each time you write. If your events tend to be tied more than once, there is a problem with your code organization, which should be exposed at development time.
(4) Do not use delegate for DOM nodes with fewer nodes
For example, if you have a form that only has a few input elements, and you delegate to the input on the form, and sometimes even on the body, all actions on the form or on the page will bubble onto the form/body, even if they’re not the target element, JQuery will then receive the event on the body and determine if the target element for all operations is the one you specified, and if so, trigger the callback you tied. In particular, events that fire frequently like Mousemove need to be executed. So don’t use bubbles if you have few elements or don’t need dynamic additions and deletions. Instead, bind multiple elements directly.
(5) Sometimes it’s easier to use native
For example, get the input of the form and its value:
let email = form.email.value.trim();Copy the code
This can be used if the form has an input[name=email] field.
Change the state of a button, but the first one will hang if the dom element is not available:
$("#update-order") [0].disabled = true;
$("#update-order").prop("disabled".true);
Copy the code
Set the display of an element to block:
div.style.display = "block";Copy the code
In most cases, however, jQ’s API is used to ensure compatibility. Here’s how to get the scrollTop:
// Always return 0 in Firefox
let _scrollTop = document.body.scrollTop();
// The correct way
let scrollTop = $(window).scrollTop();
Copy the code
Because in Firefox you need to use:
document.documentElement.scrollTopCopy the code
And this in Chrome always returns 0. Window. innerWidth, for example, is problematic on some older Android phones. So don’t use native apis when you’re not sure about compatibility, or you’ll have to be carefully validated before using them. You don’t have to, but that doesn’t mean you shouldn’t know about native apis. It’s helpful to know about native DOM manipulation.
15. Cache commonly used attributes
The following code frequently uses the window.location property:
let webLink = window.location.protocol + window.location.hostname;
if(openType === "needtoTouch"){
webLink += "/admin/lead/list/page" +
window.location.search.replace(/openType=needToTouch(&?) /."") +
window.location.hash;
}
Copy the code
We can cache it first to speed up variable scope lookup:
let location = window.location;
let webLink = location.protocol + location.hostname;
if(openType === "needtoTouch"){
webLink += "/admin/lead/list/page" +
location.search.replace(/openType=needToTouch(&?) /."") +
location.hash;
}
Copy the code
When location is made a local variable, its lookup time is significantly faster than that of a global variable. You might say that even a little bit faster doesn’t make a difference to the user, but that’s what a programmer is after, and it makes the code cleaner.
16. Try not to write CSS in JS
If it is not selected, set the color to grey:
$menuItem.css("color"."#ccc");Copy the code
Otherwise, the color will return to normal:
$menuItem.css("color"."# 000");
Copy the code
There is a problem with this code, if the color changes later, then you need to change two places, one is the CSS Settings, and the other is the JS Settings, and THE JS style is very easy to ignore, it is not easy to locate. A good practice would be to add methods to delete classes:
// Become selected
$menuItem.addClass("selected");
// Becomes unselected
$menuItem.removeClass("selected");
Copy the code
Then style the selected class using CSS. If it isa button control, you can combine :disabled, : Checked, : Valid and other pseudo-classes, and do not even add classes
If you want to change a position or transform dynamically, you need to calculate it. If you want to change a position or transform dynamically, you need to change a transform.
17. Add nonnull judgments where necessary
Adding a non-null judgment improves the robustness of the code as follows:
// Other monthly charge pops up
showOtherMonthlyCharge: function(otherCharges, $dialog){
if(! otherCharges || ! otherCharges.length){return; }}Copy the code
If it’s empty, you don’t have to deal with it, sometimes you might throw an exception to tell the caller. You may also want to add type checking to some of the more important areas. Make sure the data passed from the back end has that property, and add a non-null judgment if you’re not sure. If you’re using a third-party API, it’s also important to add error handling, because you can’t be sure that the third-party API will work properly.
Do not loop through arrays with for in
The following code:
let a = [9.3.5];
for(let i in a){
console.log(a[i])
}
Copy the code
It would normally print the elements of an array, but unfortunately, if someone added a function to the array prototype:
Array.prototype.add = function(){};Copy the code
The I in the loop will have four values: 0, 1, 2, and “add”. This will cause your traversal problems, so array traversal should use the length property or the array’s forEach/map method.
19. Semicolon specification
Javascript expressions can be used without semicolons at the end. For example, Zepto source code rarely sees a semicolon, but we still advocate adding semicolons at the end of each sentence, so that it is not easy to make mistakes.
20. Using a location jump requires escaping first
For those who jump based on user input, need to escape user content first, the following problematic code:
let searchContent = form.search.value.trim();
window.location.href = `/search? key=${searchContent}`;
Copy the code
If the user enters a # such as a house number, the content after the # will be used as an anchor, or the user may enter a space. So if you are not sure of the content of things need to encode first, the following code:
let searchContent = encodeURIComponent(form.search.value.trim());
window.location.href = `/search? key=${searchContent}`;
Copy the code
Then the jump is no problem.
21. Do not use onclick jumps
To jump when you click on a container, some people like to write:
<div onclick="window.locatioin.href='/listing/detail? id={{listingId}}'">
<img>
<div></div>
</div>Copy the code
In fact, this is not good for SEO, if it is a jump should use a tag, as follows:
<a href="window.locatioin.href='/listing/detail? id={{listingId}}'">
<img>
<div></div>
</a>
Copy the code
Also change the A tag to block level. Even if you don’t have to do SEO, you should use this method as much as possible because it feels natural and allows you to control whether or not to open a new page, and if you’re on mobile, you don’t have to worry about whether or not the click event is delayed.
22. Do not use localStorage directly
Because localStorage is disabled in incognito mode in Safari, if you try to write data to localStorage, you will get an error that exceeds the usage limit:
QuotaExceededError (DOM Exception 22): The quota has been exceeded.
Chrome’s incognito window will not be disabled. And Safari users might open invisible Windows, especially on their phones. LocalStorage = localStorage = localStorage = localStorage = localStorage = localStorage
Data.hasLocalStorage = true;
try{
window.localStorage.trySetData = 1;
}catch(e){
Data.hasLocalStorage = false;
}
setLocalData: function(key, value){
if(Data.hasLocalStorage){
window.localStorage[key] = value;
}
else{
util.setCookie("_LOCAL_DATA_" + key, value, 1000); }},getLocalData: function(key){
if(Data.hasLocalStorage){
return window.localStorage[key];
}
else{
return util.getCookie("_LOCAL_DATA_"+ key); }}Copy the code
The above code is compatible with using cookies if localStorage is not supported. Note that a domain name cookie can contain a maximum of 4kB and 50 keys, and the local storage limit is 5Mb.
23. Use easy conversions
(1) To convert a string to an integer, you can use the + sign
let maxPrice = +form.maxPrice.value;Copy the code
+ is equivalent to Number:
let maxPrice = Number(form.maxPrice.value);Copy the code
One big difference between parseInt and Number is that parseInt(” 10px “) results in 10, while Number(” 10px “) is NaN. ParseInt is more natural, and other programming languages have similar conversions. But Number still applies to a lot of scenarios.
(2) Change the mantissa from decimal to integer, you can use >> 0
If you calculate what row a number is in:
let _row = Math.floor(index / columns);
let row = parseInt(index / columns);
Copy the code
Can be changed to:
let row = index / columns >> 0;Copy the code
This bitwise operation will be significantly more efficient than the above two.
(3) Convert to Boolean!!
The following code:
letmobile = !! ua.match(/iPhone|iPad|Android|iPod|Windows Phone/)Copy the code
24. Notice the variable that returns false
There are several values that return false in the if test: 0, false, “”, undefined, null, NaN are all false.
if (array.length) {}Copy the code
Instead of writing:
if(array.length ! = =0) {}Copy the code
To determine whether a string is empty, write:
if (str) {}Copy the code
But to determine whether a variable is defined or not, write:
if (typeoffoo ! = ="undefined") {}Copy the code
Because if you go directly to the if variable, all of the above possible values will be considered undefined.
Simplify data assignment with Object.assgin
The following code often needs to fetch the form’s value before sending the request, and then modify and add the old data submission:
var orderData = {
id: 123.price: 500
}
orderData.price = 600;
orderData.discount = 15;
orderData.manageFee = 100;
Copy the code
A more elegant way to do this is to use object. assign:
var setOrderData = {
price: 600.discount: 15.manageFee: 100
}
Object.assgin(orderData, setOrderData);
Copy the code
The advantage of using this is that you can make an Object of setOrderData and write it in curly braces instead of having to assign each of the values, which is a bit tiring to write and look at. Finally, assign to the original Object.
26. Remove the irrelevant console after debugging
Delete console.log prints after debugging. Don’t try to delete them later because they will be forgotten later. Also, don’t debug with alert. The console/debugger is fine once it’s up. The average user wouldn’t open a console, but alert is dead, especially if some people like to use alert(” fuck “) to see if the code is running here. I might have to go home if I did. This can also be checked statically with a code inspection tool.
27. Notice where this is pointing
The following code:
let searchHandler = {
search() {
console.log(this);
this.ajax();
},
ajax() {
}
};
$searchBtn.on("click", searchHandler.search);
Copy the code
When the click event for searchBtn is triggered, this in the search function already points to searchBtn because it is the click callback:
searchHandler.search.call(btn, event);Copy the code
Therefore, it is better to use the variable name of the current namespace instead of this for the singleton Object:
let searchHandler = {
search() {
console.log(this);
searchHandler.ajax();
},
ajax() {
}
};
$searchBtn.on("click", searchHandler.search);
Copy the code
That’s fine.
28. String manipulation using regular expressions
Regular expressions make it easy to manipulate strings, usually in a single line of code. For example, to remove a global character, such as the – hyphen of a phone number:
phoneNumer = phoneNumber.replace(/\-/g, “”);Copy the code
Or the other way around, change the phone number to a 3-3-4:
phoneNumber = phoneNumber.replace(/^(\d{3})(\d{3})(\d{4})$/, “$1- $2- $3");Copy the code
Mastering regular expressions is an essential skill for every front-end.
29. Keep the concept of reusing modules
When you write a function to a long time, such as two, line three hundred, this time you think about the big function to the demolition, split into several small function, and then make the main function of logic clear and concise, and the function of each small function single independent, users only need to input and output, and don’t need to be concerned with internal operation. Handle user click handlers in the map as follows:
handleMouseClick(latLng, ajax = true) {
var path = this.path;
// Call closeToFirstPoint to determine if the click position is close to the first point
if(path.length >= 2 && ajax && this.closeToFirstPoint(latLng)){
If so, call closePath to close the path
this.closePath(ajax);
return;
}
path.push({lat: latLng.lat(), lng: latLng.lng()});
// Adjust the function of point
this.drawPoint(latLng);
// Call the line function
this.drawSolidLine();
// Function to draw polygon background
this.drawPolygonMask();
this.lastMoveLine && this.lastMoveLine.setMap(null);
this.$drawTip.hide();
}
Copy the code
This is a bunch of little functions, the drawPoint function for a picture point, and all you need to do with this function is give it the latitude and longitude of the current point, and it will draw a point for you.
You can continue to abstract on top of the function, for example, write the drawing module as a DrawTool class. This class is responsible for the drawing function, and the user only needs to instantiate an object, call init, and pass some parameters.
First, different functions are selected, and each function is responsible for a small piece. Similar functions are gathered together to form a module. The mutual calls of several modules form a plug-in.
30. Notice that the label event is triggered twice
If there is input inside the label, the event that listens for the label will fire twice, as follows:
<form id="choose-fruit">
<label>
<input type="radio" name="fruit" value="apple">
<span>apple</span>
</label>
<label>
<input type="radio" name="fruit" value="pear">
<span>pear</span>
</label>
<form>
<script>
{
let $form = $("#choose-fruit");
$form.find("label").on("click", function(event){
console.log(event.target);
});
}
</script>
Copy the code
The click event fires twice when a span is clicked, and only once if there is no input inside the label. Why is that? Because inside the Label container, clicking on the SPAN text sends a click event to the input, which in turn bubbles up to the label, so the label fires twice. So if you’re listening directly for the label event you have to be careful that it fires twice.