tutorial - w3school css



منع تمرير الجسم ولكن مع السماح بتمرير التراكب (10)

لقد كنت أبحث عن حل نوع "Lightbox" يسمح بذلك ولكن لم يتم العثور عليه بعد (من فضلك ، أقترح إذا كنت تعرف أيًا).

السلوك الذي أحاول إعادة إنشائه يشبه تمامًا ما تراه في موقع Pinterest عند النقر على إحدى الصور. التراكب قابل للتمرير ( كما هو الحال في التراكب بأكمله يتحرك لأعلى مثل صفحة في أعلى الصفحة ) ولكن يتم إصلاح الجسم خلف التراكب.

لقد حاولت إنشاء هذا باستخدام CSS فقط ( أي تراكب div أعلى الصفحة بأكملها والجسم مع overflow: hidden ) ، ولكنه لا يمنع div من التمرير.

كيفية الاحتفاظ بالجسم / الصفحة من التمرير مع الاستمرار في التمرير داخل حاوية ملء الشاشة؟


Answer #1

أود أن أضيف إلى الإجابات السابقة لأنني حاولت القيام بذلك ، وانكسر بعض التصميم بمجرد أن أقوم بتحويل الجسم إلى موضع: ثابت. لتجنب ذلك ، اضطررت أيضًا إلى ضبط ارتفاع الجسم إلى 100٪:

function onMouseOverOverlay(over){
    document.getElementsByTagName("body")[0].style.overflowY = (over?"hidden":"scroll");
    document.getElementsByTagName("html")[0].style.position = (over?"fixed":"static");
    document.getElementsByTagName("html")[0].style.height = (over?"100%":"auto");
}

Answer #2

إذا كان القصد هو تعطيل الأجهزة المحمولة / التي تعمل باللمس ، فإن الطريقة الأكثر مباشرة للقيام بذلك هي استخدام touch-action: none; .

مثال:

const app = document.getElementById('app');
const overlay = document.getElementById('overlay');

let body = '';

for (let index = 0; index < 500; index++) {
  body += index + '<br />';
}

app.innerHTML = body;
app.scrollTop = 200;

overlay.innerHTML = body;
* {
  margin: 0;
  padding: 0;
}

html,
body {
  height: 100%;
}

#app {
  background: #f00;
  position: absolute;
  height: 100%;
  width: 100%;
  overflow-y: scroll;
  line-height: 20px;
}

#overlay {
  background: rgba(0,0,0,.5);
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 100%;
  padding: 0 0 0 100px;
  overflow: scroll;
}
<div id='app'></div>
<div id='overlay'></div>

(المثال لا يعمل في سياق . ستحتاج إلى إعادة إنشاءه في صفحة مستقلة.)

إذا كنت تريد تعطيل تمرير الحاوية #app ، #app سوى إضافة touch-action: none; .


Answer #3

استخدم HTML التالي:

<body>
  <div class="page">Page content here</div>
  <div class="overlay"></div>
</body>

ثم JavaScript لاعتراض وإيقاف التمرير:

$(".page").on("touchmove", function(event) {
  event.preventDefault()
});

ثم لإعادة الأمور إلى طبيعتها:

$(".page").off("touchmove");


Answer #4

استخدم الرمز أدناه لتعطيل شريط التمرير وتمكينه.

Scroll = (
    function(){
          var x,y;
         function hndlr(){
            window.scrollTo(x,y);
            //return;
          }  
          return {

               disable : function(x1,y1){
                    x = x1;
                    y = y1;
                   if(window.addEventListener){
                       window.addEventListener("scroll",hndlr);
                   } 
                   else{
                        window.attachEvent("onscroll", hndlr);
                   }     

               },
               enable: function(){
                      if(window.removeEventListener){
                         window.removeEventListener("scroll",hndlr);
                      }
                      else{
                        window.detachEvent("onscroll", hndlr);
                      }
               } 

          }
    })();
 //for disabled scroll bar.
Scroll.disable(0,document.body.scrollTop);
//for enabled scroll bar.
Scroll.enable();

Answer #5

بالنسبة للأجهزة التي تعمل باللمس ، جرِّب إضافة div شفاف يبلغ عرضه 1 بكسل ، 101vh الدقيقة في غلاف التراكب. ثم إضافة -webkit-overflow-scrolling:touch; overflow-y: auto; -webkit-overflow-scrolling:touch; overflow-y: auto; إلى المجمع. هذه الحيل السفاري المتنقلة إلى التفكير في تراكب قابلة للتمرير ، وبالتالي اعتراض الحدث لمسة من الجسم.

وهنا صفحة عينة. افتح على رحلات السفاري للجوال: http://www.originalfunction.com/overlay.html

https://gist.github.com/YarGnawh/90e0647f21b5fa78d2f678909673507f


Answer #6

بشكل عام ، إذا كنت تريد أن يقوم الوالد (الجسم في هذه الحالة) بمنعه من التمرير عندما يقوم الطفل (التراكب في هذه الحالة) بالتمرير ، اجعل الطفل شقيقًا للوالد لمنع حدث التمرير من الفقاقيع حتى الاباء. في حالة كون الوالد هو الجسم ، يتطلب ذلك عنصر التفاف إضافي:

<div id="content">
</div>
<div id="overlay">
</div>

راجع تصفح محتويات DIV معينة باستخدام شريط التمرير الرئيسي الخاص بالمتصفح للاطلاع على عمله.


Answer #7

خاصية css overscroll-behavior تسمح بتجاوز سلوك التمرير الافتراضي الخاص بالمتصفح الافتراضي عند الوصول إلى أعلى / أسفل المحتوى.

ما عليك سوى إضافة الأنماط التالية إلى التراكب:

.overlay {
   overscroll-behavior: contain;
   ...
}

Codepen التجريبي

يعمل حاليًا في Chrome و Firefox ( caniuse )

لمزيد من التفاصيل ، راجع مقالة مطوّري برامج Google .


Answer #8

في حالتي ، لم يتم حل أي من هذه الحلول على iPhone (iOS 11.0).

الإصلاح الوحيد الفعال الذي يعمل على جميع أجهزتي هو هذا - ios-10-safari-prevent-scrolling-behind-a-fixed-overlay-and-maintain-scroll-position


Answer #9

لقد وجدت هذا السؤال في محاولة لحل المشكلة التي واجهتها مع صفحتي على Ipad و Iphone - تم التمرير في الجسم عندما كنت أعرض div ثابت كنقطة منبثقة مع الصورة.

بعض الإجابات جيدة ، إلا أن أيا منها لم يحل مشكلتي. لقد وجدت بعد بلوق وظيفة من قبل كريستوفر بيترسون. ساعد الحل المقدم هناك في إصدار واجهتي مع الأجهزة التي تعمل بنظام التشغيل iOS وقد ساعد في مشكلة خلفية التمرير.

ستة أشياء تعلمتها حول التمرير المطاطي لـ iOS Safari

وكما اقترح ، أقوم بتضمين النقاط الرئيسية في تدوينة المدونة في حالة ما إذا كان الرابط قديمًا.

"لتعطيل ذلك ، يمكن للمستخدم التمرير إلى صفحة الخلفية أثناء" فتح القائمة "، فمن الممكن التحكم في العناصر التي يجب السماح بتمريرها أو لا ، من خلال تطبيق بعض JavaScript وفئة CSS.

استنادًا إلى إجابة هذه ، يمكنك التحكم في هذه العناصر مع عدم تمكين التمرير - تعطيل إجراء التمرير الافتراضي عند تشغيل الحدث touchmove. "

 document.ontouchmove = function ( event ) {

    var isTouchMoveAllowed = true, target = event.target;

    while ( target !== null ) {
        if ( target.classList && target.classList.contains( 'disable-scrolling' ) ) {
            isTouchMoveAllowed = false;
            break;
        }
        target = target.parentNode;
    }

    if ( !isTouchMoveAllowed ) {
        event.preventDefault();
    }
};

ثم ضع فئة التمرير - تعطيل في الصفحة div:

<div class="page disable-scrolling">

Answer #10

معظم الحلول لديها مشكلة أنها لا تحتفظ بموضع التمرير ، لذا فقد ألقيت نظرة على كيفية قيام Facebook بذلك. بالإضافة إلى تعيين المحتوى الذي تحته إلى position: fixed يتم أيضًا تعيين الجزء العلوي بشكل ديناميكي للاحتفاظ بموضع التمرير:

scrollPosition = window.pageYOffset;
mainEl.style.top = -scrollPosition + 'px';

بعد ذلك ، عند إزالة التراكب مرة أخرى ، تحتاج إلى إعادة تعيين موضع التمرير:

window.scrollTo(0, scrollPosition);

أنا خلقت مثالا قليلا لإثبات هذا الحل

let overlayShown = false;
let scrollPosition = 0;

document.querySelector('.toggle').addEventListener('click', function() {
  if (overlayShown) {
		showOverlay();
  } else {
    removeOverlay();
  }
  overlayShown = !overlayShown;
});

function showOverlay() {
    scrollPosition = window.pageYOffset;
  	const mainEl = document.querySelector('.main-content');
    mainEl.style.top = -scrollPosition + 'px';
  	document.body.classList.add('show-overlay');
}

function removeOverlay() {
		document.body.classList.remove('show-overlay');
  	window.scrollTo(0, scrollPosition);
    const mainEl = document.querySelector('.main-content');
    mainEl.style.top = 0;
}
.main-content {
  background-image: repeating-linear-gradient( lime, blue 103px);
  width: 100%;
  height: 200vh;
}

.show-overlay .main-content {
  position: fixed;
  left: 0;
  right: 0;
  overflow-y: scroll; /* render disabled scroll bar to keep the same width */
}

.overlay {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.3);
  overflow: auto;
}

.show-overlay .overlay {
  display: block;
}

.overlay-content {
  margin: 50px;
  background-image: repeating-linear-gradient( grey, grey 20px, black 20px, black 40px);
  height: 120vh;
}

.toggle {
  position: fixed;
  top: 5px;
  left: 15px;
  padding: 10px;
  background: red;
}
  <main class="main-content"></main>

  <div class="overlay">
    <div class="overlay-content"></div>
  </div>
  
  <button class="toggle">Overlay</button>





lightbox