Home  >  Article  >  Web Front-end  >  How to disable the bottom page of the pop-up window from scrolling

How to disable the bottom page of the pop-up window from scrolling

亚连
亚连Original
2018-06-22 14:04:163207browse

When we all make pop-up layers, an essential element is the mask layer, which is the mask layer. When the pop-up layer scrolls, the page at the bottom of the mask layer is generally required to be fixed, so this This article will introduce to you several methods on how to disable the scrolling of the bottom page of the mask layer in the pop-up window. Friends in need can refer to it.

Scenario Overview

As we all know, pop-up windows are a common interaction method, and the mask layer is an essential element of pop-up windows. It is used to separate the page from the pop-up window block and temporarily block the interaction of the page. However, when sliding in the masked element, when you slide to the end of the content, and then continue to slide, the page at the bottom of the masked layer will start to scroll. Obviously this is not the effect we want, so this behavior needs to be prevented.

So, how to stop it? Please see the following analysis:

Plan analysis

Plan 1

When the masking layer is turned on, Add a style to the body:

overflow: hidden;
height: 100%;

Under some models, you may also need to add a style to the root node:

overflow: hidden;

When turning off the mask layer, remove the above styles.

Advantages:

Simple and convenient, just add css style, no complicated logic.

Disadvantages:

The compatibility is not good, it is suitable for PC, but the mobile version is awkward.

On some Android models and Safari, it is impossible to prevent the bottom page from scrolling.

If you need to apply it to the mobile terminal, then you may need option 2.

Option 2

is to use the touch event on the mobile side

Touch object represents a touch point, which can be passed event.touches [0] Get, each contact contains position, size, shape, pressure size, and target element attributes.

{
screenX: 511, 
screenY: 400,//触点相对于屏幕左边沿的Y坐标
clientX: 244.37899780273438, 
clientY: 189.3820037841797,//相对于可视区域
pageX: 244.37, 
pageY: 189.37,//相对于HTML文档顶部,当页面有滚动的时候与clientX=Y 不等
force: 1,//压力大小,是从0.0(没有压力)到1.0(最大压力)的浮点数
identifier: 1036403715,//一次触摸动作的唯一标识符
radiusX: 37.565673828125, //能够包围用户和触摸平面的接触面的最小椭圆的水平轴(X轴)半径
radiusY: 37.565673828125,
rotationAngle: 0,//它是这样一个角度值:由radiusX 和 radiusY 描述的正方向的椭圆,需要通过顺时针旋转这个角度值,才能最精确地覆盖住用户和触摸平面的接触面
target: {} // 此次触摸事件的目标element
}

Use the touch event on the mobile side to prevent the default behavior (here it can be understood that page scrolling is the default behavior).

// node为蒙层容器dom节点
node.addEventListener('touchstart', e => {
 e.preventDefault()
}, false)

Simple and crude, the bottom page cannot move when scrolling. If your masked content does not have scroll bars, then the above method is perfect.

However, the most fearful thing is that the air suddenly becomes quiet. If the content of the mask layer has a scroll bar, then it will no longer be able to move. Therefore, we need to write some js logic to determine whether to prevent the default behavior, which significantly increases the complexity.

Specific idea: Determine whether the masked content has scrolled to the end. If so, prevent the default behavior, otherwise let it run rampant.

#Tip: Here I found a little trick that can save a lot of code. During a slide, if the masked content can be scrolled, the masked content will scroll. Even if the masked content has scrolled to the end, as long as you don't let go (which can be understood as before the touchend event is triggered), the page content will not scroll when you continue to slide. , if you let go and continue scrolling, the page content will scroll. Using this little trick, we can streamline and optimize our code logic.

The sample code is as follows:

<body>
 <p class="page">
 <!-- 这里多添加一些,直至出现滚动条 -->
 <p>页面</p>
 <p>页面</p>
 <button class="btn">打开蒙层</button>
 <p>页面</p>
 </p>
 <p class="container">
 <p class="layer"></p>
 <p class="content">
  <!-- 这里多添加一些,直至出现滚动条 -->
  <p>蒙层</p>
  <p>蒙层</p>
  <p>蒙层</p>
 </p>
 </p>
</body>
body {
 margin: 0;
 padding: 20px;
}

.btn {
 border: none;
 outline: none;
 font-size: inherit;
 border-radius: 4px;
 padding: 1em;
 width: 100%;
 margin: 1em 0;
 color: #fff;
 background-color: #ff5777;
}

.container {
 position: fixed;
 top: 0;
 left: 0;
 bottom: 0;
 right: 0;
 z-index: 1001;
 display: none;
}

.layer {
 position: absolute;
 top: 0;
 left: 0;
 bottom: 0;
 right: 0;
 z-index: 1;
 background-color: rgba(0, 0, 0, .3);
}

.content {
 position: absolute;
 bottom: 0;
 left: 0;
 right: 0;
 height: 50%;
 z-index: 2;
 background-color: #f6f6f6;
 overflow-y: auto;
}
const btnNode = document.querySelector(&#39;.btn&#39;)
const containerNode = document.querySelector(&#39;.container&#39;)
const layerNode = document.querySelector(&#39;.layer&#39;)
const contentNode = document.querySelector(&#39;.content&#39;)
let startY = 0 // 记录开始滑动的坐标,用于判断滑动方向
let status = 0 // 0:未开始,1:已开始,2:滑动中

// 打开蒙层
btnNode.addEventListener(&#39;click&#39;, () => {
 containerNode.style.display = &#39;block&#39;
}, false)

// 蒙层部分始终阻止默认行为
layerNode.addEventListener(&#39;touchstart&#39;, e => {
 e.preventDefault()
}, false)

// 核心部分
contentNode.addEventListener(&#39;touchstart&#39;, e => {
 status = 1
 startY = e.targetTouches[0].pageY
}, false)

contentNode.addEventListener(&#39;touchmove&#39;, e => {
 // 判定一次就够了
 if (status !== 1) return

 status = 2

 let t = e.target || e.srcElement
 let py = e.targetTouches[0].pageY
 let ch = t.clientHeight // 内容可视高度
 let sh = t.scrollHeight // 内容滚动高度
 let st = t.scrollTop // 当前滚动高度

 // 已经到头部尽头了还要向上滑动,阻止它
 if (st === 0 && startY < py) {
 e.preventDefault()
 }

 // 已经到低部尽头了还要向下滑动,阻止它
 if ((st === sh - ch) && startY > py) {
 e.preventDefault()
 }
}, false)

contentNode.addEventListener(&#39;touchend&#39;, e => {
 status = 0
}, false)

Although the problem has been solved, looking back, the complexity and code volume have obviously increased by a gradient.

Based on the principle of simplicity and convenience, can we explore other solutions?

Since the touch event determination is more complicated, why not step out of this box, find another way, and explore a more suitable solution.

So, we have our plan three.

Option 3

Let me talk about my idea. Since we want to prevent the page from scrolling, why not fix it in the window (i.e. position: fixed), so that it It will no longer be scrollable and will be released when the mask is closed.

position: fixed I don’t need to introduce too much to you. For a detailed introduction, you can refer to this article: //www.jb51.net/article/83175.htm

Of course There are some details to consider. After fixing the page window, the content will return to the top. Here we need to record it and synchronize the top value.

Sample code:

let bodyEl = document.body
let top = 0

function stopBodyScroll (isFixed) {
 if (isFixed) {
 top = window.scrollY

 bodyEl.style.position = &#39;fixed&#39;
 bodyEl.style.top = -top + &#39;px&#39;
 } else {
 bodyEl.style.position = &#39;&#39;
 bodyEl.style.top = &#39;&#39;

 window.scrollTo(0, top) // 回到原先的top
 }
}

Thinking summary

  • If the application scenario is PC, recommended option one is really not necessary Too convenient

  • If the application scenario is h5, you can use option two, but I suggest you adopt option three

  • If the application scenario is full platform, then you shouldn’t miss option three

This article is about to end here. Here I strongly recommend option three because it is simple, convenient, has good compatibility, and can be packaged in one time. Used forever.

The above is what I compiled for everyone. I hope it will be helpful to everyone in the future.

Related articles:

Responsive principles in Vue (detailed tutorial)

How to implement dynamic loading of bar charts in angularjs

How to use scope in Angular scope

How to use react to implement menu permission control

The above is the detailed content of How to disable the bottom page of the pop-up window from scrolling. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn