I was just working on an OKR project and stayed up one or two hours in the morning for three days in a row. A line found a bug, fix it, and then on line, I play芔 茻, unexpectedly did not change right, or there is a problem. My whole person is in the following GIF state, crying for my father and mother, with no one behind me (basically one front end for each project). I had to analyze the problem, look at the code.
The main reason for this repeated online problem is that the time is tight, the task is heavy, the test is not sufficient, and the ability is not enough, 🙃 can not quickly and timely make a correct and rapid response to the problem. I was beaten by reality for the first time at an Internet company.
Since the bitter have eaten, must learn to grow. So use this article to write it down and learn something.
Top, middle and bottom layout
One of the most popular interview topics is left, center and right layouts, fixed left and right, and adaptive middle. In the OKR project, I found that the UI page had an obvious feature of top, middle and bottom layout. The top part of the page was usually fixed at the top, the bottom part was fixed at the bottom of the page, and the middle part was scrollbars as the content increased. Hahaha, if I am lucky enough to be an interviewer, I will give a question like this to see the candidate’s CSS ability.
There are two main points:
- Use flex layout implementation, middle section setup
flex: 1;
, the upper and lower use fixed height; Realize the overall layout of the page. - Set the outermost container
height: 100vh; overflow: hidden;
; intermediateOverflow: auto;
Can.
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<title>The intermediate content is adaptive</title>
</head>
<body>
<div class="demo-container">
<div class="demo-container__head border">Fixed header title</div>
<div class="demo-container__content">
<div class="card card-item">card1</div>.<div class="card card-item">card6</div>
</div>
<div class="demo-container__footer border">
<button type="button" class="btn btn-primary">submit</button>
</div>
</div>
</body>
</html>
<style>
.demo-container{
height:100vh;
overflow: hidden;
background-color: #F6F6F6;
display: flex;
flex-direction: column;
}
.demo-container__head{
height: 66px;
background-color: #FFFFFF;
}
.demo-container__footer{
display: flex;
align-items: center;
justify-content: center;
background-color: #FFFFFF;
padding: 10px 16px;
}
.demo-container__content{
flex: 1;
overflow: auto;
}
.card-item{
width: 100%;
height: 400px;
margin-top: 10px;
}
</style>
Copy the code
Custom fonts
In the project, if UI students specify that they want to use a certain font, the front end should not say no, saying “no” is unprofessional, we should say no problem. So how to implement the use of custom fonts in projects? There are two main steps:
- Start by downloading the fonts for the font library. To download it at www.fontke.com/, search for the font, for example, SF Pro Rounded
- In general, only a few words need to use the above font; Also need to use fontmin (ecomfe. Making. IO/fontmin) extract want subsets
Click Generate to get the corresponding character set:
According to the compatibility of the project to the browser, you can use as needed:
An X adaptation
There are two things the iPhone X needs to fit: the fringe on the top and the black line on the bottom. The top fringe browser has adapted for us. There are usually two steps to fit the black line at the bottom:
Step 1: Set viewport-fit=cover so that the content of the web page occupies the entire viewable area of the phone screen as follows:
<meta name='viewport' content="width=device-width, viewport-fit=cover" />
Copy the code
Step 2: Set the padding to make the content appear on top of the black line:
body {
/* Match the bangs */
padding-top: constant(safe-area-inset-top);
padding-top: env(safe-area-inset-top);
/* Fit the bottom black bar */
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
Copy the code
Juejin. Cn/post / 684490…
Bobtung.medium.com/%E9%9D%A2%E…
Check whether it is empty
After finishing the last wave of son line on Friday, the front user unexpectedly also found a bug, a new bug, surprise not, meaning not unexpected, did not go off work on time. I take a look, is missing the non-empty judgment, add it OK, and then online, I erase, reuse the interface, data is empty, there is no re-assignment, which leads to the problem of dirty data, continue to change ah, continue to online ah, finally solved the bug, peace of mind off work.
In my habit of writing code before, I always do non-null judgment, but this interface does not, why? Because logically, with the ID, according to the ID to check the backend data, it must be valuable, but goose, but the backend occasionally have data query failure, but ah, front-end prompt “system exception”, F12 open after:
Such a small probability of bugs are encountered, I feel that I must write code must be rigorous, can not ignore 0.001% of the possible situation.
If you are lazy when writing code and later produce a problem, you have to look at the code and solve the bug, which takes more time and energy, you might as well not be afraid of trouble at the beginning, do not save trouble, and conscientiously write good code.
Therefore, when querying data, we must first judge whether the data is empty; Adding a catch after a try code does not affect subsequent operations on the page.
The page returns to where it left off
Three heights (widths)
Details:
-
ClientHeight: includes padding, but excludes the height, border, and margin of the horizontal scrollbar; So clientHeight = content + padding
-
OffsetHeight: includes the padding, border, and height of the horizontal scrollbar. OffsetHeight = Content + padding + border + ScrollBar height
-
ScrollHeight: The total internal height of the DOM element
You can see that offsetHeight reflects the actual size of the DOM better than clientHeight, which includes the border and scrollbar height.
What is the height of a style style? Height is defined by box-sizing. Box model portal
An example of three height calculations. Note that box-sizing is the default value content-box
English Version
Some properties of Scroll
ScrollTop \scrollLeft
ScrollTop indicates the distance between the hidden content and the scrollbar. When the page leaves, record the value first, and when the page returns, move the scroll bar to the value, and you can achieve the effect of leaving the page at the same position.
Some method for Scroll
scrollBy(options? : ScrollToOptions):void;
scrollBy(x: number.y: number) :void; scrollTo(options? : ScrollToOptions):void;
scrollTo(x: number.y: number) :void; scrollIntoView(arg? :boolean | ScrollIntoViewOptions): void;
Copy the code
ScrollBy and scrollTo are used in a similar way. ScrollBy works on an element with a scrollbar to scroll the scrollbar to a specified position.
The scrollIntoView method scrolls the element’s parent container, making the element called scrollIntoView() visible to the user.
// Method 1:
const dom = document.getElementById('scrollWrap')
dom.scrollTo({
top: 420.behavior: "smooth"
});
// Method 2:
dom.scrollBy(0.420)
// Method 3:
const card2 = document.getElementById('card2')
card2.scrollIntoView()
Copy the code
ScrollTop is a readable and writable property. You can also set the scrollTop directly to the specified position
const dom = document.getElementById('scrollWrap')
dom.scrollTop = 420
Copy the code
Scroll will fail
Find a weird scroll event that you don’t know: Why does the Scroll event fail?
Safari returns without reloading data
In THE OKR project, the old system was used in the recopy; Click the redisk button to jump into the old system, then from the old system and back again. The test students found that there had been a copy of the content, but the page did not show. On the old system, the router.back() function was used to return the same thing as window.history.back().
In Chrome, window.history.back() triggers the window.load event; However, in Safari, window.history.back() does not trigger the window.load event, which results in the data not being up to date and being previously cached.
After a bit of Google research, mobile browsers have a feature called “back-forward cache,” or BFCache, that speeds up page transitions when users use the browser’s “back” and “forward” buttons. This cache not only holds the page data, but also the DOM and JavaScript state; In effect, the entire page is stored in memory. If the page is in bfCache, opening the page again will not trigger the load event.
Solution: Listen for the PagesHow event of the window, or execute the Reload method of the window if it is from cache.
const onPageShow = (event: any) = >{
if (event.persisted) {
window.location.reload()
}
}
window.addEventListener('pageshow', onPageShow)
Copy the code
One thing to note is that in pure Vue2 and Vue3 it is ok to bind window pageshow in created or setup; However, the Vue Router is often used in the project, so registering pagesHow events in the lifecycle of the Vue page component does not take effect. Pageshow events should be registered before instantiating the APP. As follows:
const onPageShow = (event) = >{
if (event.persisted) {
window.location.reload()
}
}
window.addEventListener('pageshow', onPageShow)
createApp(App).use(store).use(router).mount('#app')
Copy the code
Vue Router 4 + keep-alive
Correct keep-alive posture in Vue Router 4:
Using the include page component, the name of Contact must be written as “Contact”, consistent with the string after include.
<router-view v-slot="{ Component }">
<keep-alive include="Contact">
<component :is="Component" />
</keep-alive>
</router-view>
Copy the code
Or use meta: {keepAlive: true} to set it uniformly:
<router-view v-slot="{ Component, route }">
<template v-if="route.meta.keepAlive">
<keep-alive>
<component :is="Component" />
</keep-alive>
</template>
<template v-else>
<component :is="Component" />
</template>
</router-view>
Copy the code
const routes: Array<RouteRecordRaw> = [
{
path: '/'.name: 'Home'.component: Home
},
{
path: '/about'.name: 'About'.component: () = > import(/* webpackChunkName: "about" */ '.. /views/About.vue')}, {path: '/contact/:id'.name: 'Contact'.meta: {
keepAlive: true
},
component: () = > import('.. /views/Contact.vue'),}]Copy the code