Development Tip

요소에서 창으로 스크롤 버블 링 방지

yourdevel 2021. 1. 8. 22:30
반응형

요소에서 창으로 스크롤 버블 링 방지


iframe이 포함 된 모달 상자 창 (팝업)이
있고 해당 iframe 내부 에는 스크롤 가능한 div 가 있습니다.

iframe의 내부 DIV를 스크롤하고 상단 또는 하단 제한에 도달
하면 브라우저 자체의 창이 스크롤되기 시작합니다. 이것은 원치 않는 동작 입니다.


마우스가 팝업 상자 영역에 들어갈 onMouseEnter 때 주 창 스크롤을 죽이는 다음과 같은 것을 시도했습니다 .

e.preventDefault ()가 어떤 이유로 작동하지 않습니다 ...

$("#popup").mouseenter(function(){
   $(window).bind("scroll", function(e){
        e.preventDefault();
   }); 
}).mouseleave(function(){
    $(window).unbind("scroll");
});

최신 정보

지금 2013 년 e.preventDefault();이면 충분 해 ...


죄송합니다. 제가 아는 한 어떤 종류의 스크롤 이벤트도 취소 할 수 없습니다.

W3MSDN모두 다음 과 같이 말합니다.

Cancelable  No
Bubbles     No

이 문제를 해결하려면 브라우저 작성자에게 맡겨야한다고 생각합니다. Firefox (Linux의 3.5, 어쨌든)는 더 나은 동작을하는 것 같습니다 . 스크롤 휠을 사용하기 시작할 때 자식이 이미 상단 / 하단에있는 경우에만 부모를 스크롤합니다.


창 스크롤을 막을 수 없다면 왜 취소하지 않습니까? 즉, 스크롤 이벤트를 포착 한 다음 고정 위치로 다시 스크롤합니다.

다음 코드는 하나를 가리키면 Y 축을 잠급니다 $("#popup").

// here we store the window scroll position to lock; -1 means unlocked
var forceWindowScrollY = -1;

$(window).scroll(function(event) {
  if(forceWindowScrollY != -1 && window.scrollY != forceWindowScrollY) {
    $(window).scrollTop(forceWindowScrollY);    
  }
});

$("#popup").hover(function() {
  if(forceWindowScrollY == -1) {
    forceWindowScrollY = $(window).scrollTop();
  }
}, function() {
  forceWindowScrollY = -1;
});

http://bundestube.de/ 의 쿼리 제안 상자에 이것을 사용합니다 (스크롤 가능한 창을 표시하려면 상단 검색 상자에 일부 문자를 입력) :

스크린 샷

이것은 Chrome / Safari (Webkit)에서 완벽하게 작동하며 Firefox 및 Opera의 일부 스크롤 오류와 함께 작동합니다. 어떤 이유로 IE 설치에서 작동하지 않습니다. 나는 이것이 모든 경우에 100 % 올바르게 작동하지 않는 것으로 보이는 jQuery의 hover 메서드와 관련이 있다고 생각합니다.


간단한 CSS 속성을 사용하여 해결 ( 일부 브라우저의 경우) :
overscroll-behavior

body{
  height: 600px;
  overflow: auto;
}

section{
  width: 50%;
  height: 50%;
  overflow: auto;
  background: lightblue;
  overscroll-behavior: none; /*   <--- the trick    */
}

section::before{
  content: '';
  height: 200%;
  display: block;
}
<section>
 <input value='end' />
</section>

스크롤이 "고정"되어야하는 요소에 해당 스타일 속성을 적용하기 만하면 스크롤 이벤트가 스크롤이있을 수있는 부모 요소까지 버블 링되지 않습니다.


위하지만 동일 데모 없이 트릭 :

body{
  height: 600px;
  overflow: auto;
}

section{
  width: 50%;
  height: 50%;
  overflow: auto;
  background: lightblue;
}

section::before{
  content: '';
  height: 200%;
  display: block;
}
<section>
 <input value='end' />
</section>


나는 그것이 꽤 오래된 질문이라는 것을 알고 있지만 이것이 Google의 최고 결과 중 하나이기 때문에 어떻게 든 jQuery없이 스크롤 버블 링을 취소해야 했고이 코드가 나를 위해 작동합니다.

function preventDefault(e) {
  e = e || window.event;
  if (e.preventDefault)
    e.preventDefault();
  e.returnValue = false;  
}

document.getElementById('a').onmousewheel = function(e) { 
  document.getElementById('a').scrollTop -= e. wheelDeltaY; 
  preventDefault(e);
}

내 jQuery 플러그인 :

$('.child').dontScrollParent();

$.fn.dontScrollParent = function()
{
    this.bind('mousewheel DOMMouseScroll',function(e)
    {
        var delta = e.originalEvent.wheelDelta || -e.originalEvent.detail;

        if (delta > 0 && $(this).scrollTop() <= 0)
            return false;
        if (delta < 0 && $(this).scrollTop() >= this.scrollHeight - $(this).height())
            return false;

        return true;
    });
}

That's how I solved the problem:

I call the following when I open the popup:

$('body').css('overflow','hidden');

Then, when I close the popup I call this:

$('body').css('overflow','auto');

The popup is meant to be modal so no interaction is required with the underlying body

Works pretty well


Apparently, you can set overflow:hidden to prevent scrolling. Not sure how that'd go if the doc is already scrolled. I'm also on a mouseless laptop, so no scrolly wheel testing for me tonight :-) It's probably worth a shot though.


you can try jscroll pane inside the iframe to replace the default scroll.

http://www.kelvinluck.com/assets/jquery/jScrollPane/jScrollPane.html

I am not sure, but give it a try


Here's what I do:

  $('.noscroll').on('DOMMouseScroll mousewheel', function(ev) {
     var prevent = function() {
         ev.stopPropagation();
         ev.preventDefault();
         ev.returnValue = false;
         return false;
     }
     return prevent();
  }); 

demo fiddle

Use CSS overflow:hidden to hide the scrollbar as this will do nothing if they drag it.

Works cross-browser


여기에 새로운 웹 개발자가 있습니다. 이것은 IE와 Chrome에서 나에게 매력처럼 작동했습니다.

static preventScrollPropagation(e: HTMLElement) {
    e.onmousewheel = (ev) => {
        var preventScroll = false;
        var isScrollingDown = ev.wheelDelta < 0;
        if (isScrollingDown) {
            var isAtBottom = e.scrollTop + e.clientHeight == e.scrollHeight;
            if (isAtBottom) {
                preventScroll = true;
            }
        } else {
            var isAtTop = e.scrollTop == 0;
            if (isAtTop) {
                preventScroll = true;
            }
        }
        if (preventScroll) {
            ev.preventDefault();
        }
    }
}

줄 수에 속지 마십시오. 매우 간단합니다. 가독성을 위해 약간 장황합니다 (자체 문서화 코드 ftw 맞습니까?).


가장 잘 작동하는 것으로 확인 된 약간 업데이트 된 코드를 추가하고 싶습니다.

var yourElement = $('.my-element');

yourElement.on('scroll mousewheel wheel DOMMouseScroll', function (e) {
    var delta = e.originalEvent.wheelDelta || -e.originalEvent.detail;

    if (delta > 0 && $(this).scrollTop() <= 0)
        return false;
    if (delta < 0 && $(this).scrollTop() >= this.scrollHeight - $(this).outerHeight())
        return false;

    return true;
});

이 것과 이미 위에서 언급 한 것의 차이점은 더 많은 이벤트를 추가하고 요소에 패딩이있는 경우 충돌을 피하기 위해 height () 대신 outerHeight ()를 사용한다는 것입니다 !


$('.scrollable').on('DOMMouseScroll mousewheel', function (e) {
    var up = false;
    if (e.originalEvent) {
        if (e.originalEvent.wheelDelta) up = e.originalEvent.wheelDelta / -1 < 0;
        if (e.originalEvent.deltaY) up = e.originalEvent.deltaY < 0;
        if (e.originalEvent.detail) up = e.originalEvent.detail < 0;
    }

    var prevent = function () {
        e.stopPropagation();
        e.preventDefault();
        e.returnValue = false;
        return false;
    }

    if (!up && this.scrollHeight <= $(this).innerHeight() + this.scrollTop + 1) {
        return prevent();
    } else if (up && 0 >= this.scrollTop - 1) {
        return prevent();
    }
});

2018 년 이후로는 e.preventDefault로 충분합니다.

$('.elementClass').on("scroll", function(e){
    e.preventDefault();
 }); 

그러면 부모로 스크롤되지 않습니다.


function stopPropogation(e)
{
    e = e || window.event;
    e.cancelBubble = true;
    if (e.stopPropagation) e.stopPropagation();
    if (e.preventDefault) e.preventDefault();
}

작동합니다.

참조 URL : https://stackoverflow.com/questions/1459676/prevent-scroll-bubbling-from-element-to-window

반응형