>  기사  >  웹 프론트엔드  >  팝업 창 하단 페이지의 스크롤을 비활성화하는 방법

팝업 창 하단 페이지의 스크롤을 비활성화하는 방법

亚连
亚连원래의
2018-06-22 14:04:163207검색

우리 모두 팝업 레이어를 만들 때 필수 요소는 마스크 레이어인 마스크 레이어입니다. 팝업 레이어 스크롤 시 일반적으로 마스크 레이어 하단의 페이지를 고정해야 하므로 이렇게 합니다. 글 팝업창의 마스크 레이어 하단 스크롤을 방지하는 방법에 대해 여러 가지 방법을 소개해 드리겠습니다. 필요하신 분들은 참고하시면 됩니다.

시나리오 개요

우리 모두 알고 있듯이 팝업 창은 일반적인 상호 작용 방식이며 마스크 레이어는 팝업 창의 필수 요소로 페이지와 팝을 분리하는 데 사용됩니다. -up 창을 차단하고 페이지 상호작용을 일시적으로 차단합니다. 그러나 마스크된 요소를 슬라이드할 때 콘텐츠 끝으로 슬라이드한 다음 계속 슬라이드하면 마스크된 레이어 하단에 있는 페이지가 스크롤되기 시작합니다. 분명히 이는 우리가 원하는 효과가 아니기 때문입니다. 행동을 예방해야 합니다.

그렇다면 어떻게 막을 수 있을까요? 다음 분석을 참조하십시오.

계획 분석

계획 1

마스크 레이어를 켤 때 몸체에 스타일을 추가하세요.

overflow: hidden;
height: 100%;

일부 모델에서는 스타일을 추가해야 할 수도 있습니다. 루트 노드:

overflow: hidden;

마스크 레이어를 끌 때 위 스타일을 제거하세요.

장점:

간단하고 편리합니다. 복잡한 논리 없이 CSS 스타일만 추가하면 됩니다.

단점:

호환성이 좋지 않아 PC에는 적합하지만 모바일 버전은 어색합니다.

일부 Android 모델 및 Safari에서는 하단 페이지 스크롤을 방지하는 것이 불가능합니다.

모바일 단말에 적용해야 하는 경우 옵션 2가 필요할 수 있습니다.

옵션 2

는 모바일 측에서 터치 이벤트를 사용하는 것입니다.

Touch 개체는 터치 지점을 나타내며, event.touches[0]를 통해 얻을 수 있습니다. 각 터치 지점에는 위치, 크기, 모양이 포함됩니다. , 압력 수준 및 대상 요소 속성입니다.

{
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
}

기본 동작을 방지하려면 모바일 측의 터치 이벤트를 사용하세요(여기서는 페이지 스크롤이 기본 동작이라는 것을 이해할 수 있습니다).

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

간단하고 투박하며 스크롤할 때 하단 페이지가 이동할 수 없습니다. 마스크된 콘텐츠에 스크롤 막대가 없으면 위의 방법이 완벽합니다.

그러나 가장 두려운 점은 공기가 갑자기 조용해지면 마스크 레이어의 내용에 스크롤 막대가 있으면 더 이상 움직일 수 없다는 것입니다. 따라서 기본 동작을 방지할지 여부를 결정하기 위해 일부 js 로직을 작성해야 하며 이로 인해 복잡성이 크게 증가합니다.

구체적인 아이디어: 마스크된 콘텐츠를 끝까지 스크롤할지 여부를 결정합니다. 그렇다면 기본 동작을 방지하고, 그렇지 않으면 만연하게 실행합니다.

팁: 여기서 저는 많은 코드를 절약할 수 있는 작은 트릭을 발견했습니다. 슬라이드 중에 마스크된 콘텐츠를 스크롤할 수 있으면 마스크된 콘텐츠가 끝까지 스크롤되더라도 손을 떼지 않는 한(터치엔드 이벤트가 트리거되기 전으로 이해될 수 있음) ), 계속 슬라이드하면 페이지 콘텐츠가 스크롤되지 않습니다. 손을 떼고 계속 스크롤하면 페이지 콘텐츠가 스크롤됩니다. 이 작은 트릭을 사용하면 코드 로직을 간소화하고 최적화할 수 있습니다.

샘플 코드는 다음과 같습니다.

<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)

문제는 해결되었지만 되돌아보면 복잡성과 코드량이 확실히 그라디언트 증가했습니다.

단순성과 편의성의 원칙을 바탕으로 다른 솔루션을 모색할 수 있을까요?

터치 이벤트의 결정은 더 복잡하므로 이 상자에서 벗어나 다른 방법을 찾아 더 적합한 솔루션을 찾아보세요.

그래서 세 번째 계획이 있습니다.

옵션 3

페이지가 스크롤되는 것을 방지하고 싶기 때문에 마스크가 스크롤될 때 스크롤 및 해제가 불가능하도록 창에서 수정하면 어떨까요? 폐쇄 .

위치: 수정 사항을 너무 많이 소개할 필요는 없습니다. 자세한 소개는 다음 기사를 참조하세요: //www.jb51.net/article/83175.htm

물론 몇 가지 세부 사항이 있습니다. 페이지 변경 창을 수정한 후 내용이 맨 위로 돌아가므로 이를 기록하고 상위 값을 동기화해야 합니다.

샘플 코드:

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
 }
}

생각 요약

  • 적용 시나리오가 PC라면 권장 옵션 1은 그다지 편리하지 않습니다

  • 적용 시나리오가 h5라면 옵션 2를 사용해도 되지만 저는 옵션 3을 채택하는 것이 좋습니다

  • 적용 시나리오가 모든 플랫폼이라면 옵션 3을 놓치지 마세요

옵션 3은 간단하기 때문에 여기서 마무리하겠습니다. , 편리하고 호환성이 뛰어나며 일단 포장되면 영원히 지속됩니다.

위 내용은 모두를 위해 제가 정리한 내용입니다. 앞으로 모든 사람에게 도움이 되기를 바랍니다.

관련 기사:

Vue의 반응형 원칙에 대하여(자세한 튜토리얼)

Angularjs에서 막대 차트의 동적 로딩을 구현하는 방법

Angular 범위에서 범위를 사용하는 방법

사용법 구현 방법 반응의 메뉴 권한 제어

위 내용은 팝업 창 하단 페이지의 스크롤을 비활성화하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.