It has been nearly 40 years since the first episode was released in 1979, and since its inception as a horror film, alien has become a classic in the history of science fiction movies… . No, this is not a movie review, this is knowledge!

background

Today’s mobile phone makers make the screen as big as possible while keeping the size unchanged. Indeed, they take great pains in screen design. In order to increase the proportion of LCD screens, “aliens” appear! Water drop screen, bangs screen and other “special-shaped screen” unique interface design to replace the original orderly layout, users happy, front-end students can headache, not only to ensure the normal display of the page, but also take into account the user’s visual experience. The emergence of these “alien screens” means that we spend a lot of energy on adaptation, or often forget about adaptation, resulting in blocked or missing features and affecting the user experience.

In order to solve this general need, we decided to make a universal top and bottom, compatible with a variety of different screen frame components, with this component you don’t have to worry about compatibility, components will help everyone achieve. This article starts from here

Browser Introduction

Currently, there is no special screen related API in HTML5 specification, so the processing of APP, mobile browser, PC browser and other terminals will be different.

Within the APP side

The number of devices with irregular screens on Android and iOS has increased in the last two years, indicating that there are still full screen devices in stock. In addition, android and iOS systems have different support levels for the unusual top bar. Usually, only newer systems can support cool effects. Therefore, FE alone cannot solve the compatibility problems of a large number of different devices (mainly Android) and different operating systems (iOS versions vary).

Based on APP and M pages, there are usually mature communication frameworks, which require the assistance of APP developers to ensure compatibility:

  1. Declare the top bar penetration effect to app by adding parameters in URL; (If the APP penetrates by default, it can be ignored);
  2. APP provides a method to judge whether the top bar penetrates successfully;
  3. If the top bar penetrates successfully, the APP returns the height of the top bar. FE uses the height of the top column to make the top offset;

The browser APP

Depending on the capabilities of each browser APP, each browser APP has to be adapted one by one.

PC browser

There is no abnormal screen on PC, so it is not considered.

The emergence of frames:

Before the emergence of special-shaped screen framework, front-end students need to realize a series of related logic in the development of the page: whether the top supports penetration, achieve penetration ability, obtain the height of the top bar, etc., and the implementation methods are different, not reusable, low maintainability. Top penetration can now be achieved in one step using the Hetero screen framework. Just wrap your page code around the framework, as shown below:

import { PageBaseBox } from '@zz-common/zz-ui'; Vue.use(PageBaseBox); <! -- With title taskbar by default, 1</div> <div> Custom module part 2</div> <template V-slot :fixedFooter> <div Class ="footer"> </div> </template> </z-page-base-box>Copy the code

In addition to top penetration, the following features can be extended:

  • Ta supports universal top and bottom suction; Compatible with water drop screen, bangs screen and other special-shaped screen.
  • Ta supports continuous cumulative suction top (currently supports stage 2) or continuous covering suction top.
  • Ta supports serviceWork and exception monitoring.
  • Ta can support the unified addition of specific modules or functions to each page (such as unified page navigation bar)

A short video demonstration:

Next, a brief look at the source code, extract the framework of several implementation logic:

Basic functions – Top & Bottom suction:

The sticky top is used, but the compatibility is not very good, here is the compatibility processing:

CssSupport (attr? : any, value? : any) { if (fixedMainDom && fixedMainDom.style && attr in fixedMainDom.style) { fixedMainDom.style[attr] = value fixedSubDom.style[attr] = value return fixedMainDom.style[attr] === value } else { return false } } initDome () { ... If (this.cssSupport('position', 'sticky')) {return} else {// do SomeThingA}}Copy the code

What does do SomeThingA do?

Listen for page scroll events (scroll throttling was added to improve performance) and identify element peak timing; Calculate the height from the top element to get the top value.

Use position:fixed and set the top to top: 0. This time the problem appeared, page elements with the iphoneX bangs in the screen can not be hidden off the time and signal taskbar, heavy! Fold! !

The interface of the suction top is compatible with different “abnormals” and different top height is reserved, that is, top value. If it is in the client, you can ask the client to cooperate to get the taskbar height and provide it to the front end (not to be described here), and then get this value, add paddingTop to the frame, and discard the taskbar part to avoid h5 content being overwritten. PaddingTop is not required if it is processed by the browser outside the end.

Similarly, the bottom suction is also directly using position:fixed; bottom:0

Note that the bottom action bar of iphoneX covers the bottom content, causing the button to be invalid. Here we need to make a compatibility.

// For iphoneX, add specific class <div :class="['page_base', {'is_iphonex': isIphoneX}]"> <div class="fixed_footer"></div> </div> // this.isIphoneX = The navigator. UserAgent. ToLocaleUpperCase (.) indexOf (' IPHONE ') > = 0 & & window. The screen. The height > = 812 / / style < style scoped lang="scss"> $fixedBottomIPhoneX: 50px; .page_base.is_iphonex{ margin-bottom: $fixedBottomIPhoneX; .fixed_footer{ bottom: $fixedBottomIPhoneX } } </style>Copy the code

Basic layout – Slot implementation:

As a framework, it is necessary to control the top module, bottom module, continuous top, etc. Developing a page with a variety of content layouts, how to identify modules?

To do this, special identity slots have been added to the framework, as well as support for passing custom slots. For solT with special status, some processing is done, such as top/bottom calculation

<! -- z-page-base-box with title taskbar by default, <template V-slot :fixedHeaderSlot> <div class="header"> Custom taskbar information </div> </template> </div> <div> <template V-slot :fixedFooter> <div class="footer"> Bottom module - editable style </div> </template> </z-page-base-box>Copy the code

Continuous top suction, covering top suction – Dom follow:

  • TaskHeigth = taskHeigth = taskHeigth = taskHeigth = taskHeigth = taskHeigth = taskHeigth = taskHeigth = taskHeigth = taskHeigth (See a short video demo at the beginning of this article.)

  • Then successive suction top: head suction top, first suction top, second suction top!

Here you can see that the height of the primary top changes, and the DOM of the secondary top follows. How does that happen?

Here we use MutationObserver to create an observer.

The MutationObserver interface provides the ability to monitor changes made to the DOM tree, dubbed DOM Change Observer

Var observe = new MutationObserver(function(mutations,observer){})Copy the code

MutationObserver has three methods, as follows:

  • 1. Observe: Set observation object. Accept two parameters: target: observe object and options: Set observation options through object member
  • Disconnect: Blocks the observer from seeing any changes
  • 3. TakeRecords: Clear the record queue and return its contents
AddAbserve (target) {observe = new MutationObserver((mutations,observe) => {this.mainheight = This.gettargetrect (abserveTarget).height}) // childList: set true to observe the change of the target child node, such as adding or deleting the target child node, does not include the change of the child node and its descendants. / / subtree: set to true, the offspring of the objectives and goals change will observe observe, observe (target, {childList that consists: true, subtree: RemoveAbserve () {observe&& observe.disconnect()}Copy the code

enhancements

Since it is a framework that wraps the page content, you can add some general UI, such as the bottom navigation bar, side function bar, and advertisement space. You can also add some general functions, such as serviceWork and exception monitoring

Here is a small series of ideas to solve the problem, to attract jade, if you have a good idea welcome to communicate!

The welfare of

Article in the “big turn FE” public number will also be sent, and the public number has a lucky draw, this prize is around a memorial T-shirt or around a random hand do, any one of them, welcome to pay attention to (°▽°) Blue ✿