it-roy-ru.com

не допускать появления прокрутки от элемента к окну

У меня есть окно модального окна (всплывающее окно), которое содержит iframe,
и внутри этого iframe есть div , который можно прокручивать.

Когда я прокручиваю внутренний DIV iframe, и он достигает своего верхнего или нижнего предела,
окно самого браузера начинает прокручиваться. это нежелательное поведение.

Я пробовал что-то вроде этого, который убивает прокрутку главного окна, когда
onMouseEnter, когда мышь входит в область всплывающего окна:

e.preventDefault () не работает должным образом по некоторым причинам ...

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

Обновление

Похоже, сейчас в 2013 году e.preventDefault(); достаточно ...

52
vsync

Решено (для браузеров modern) с использованием простого свойства CSS:
оверролл-поведение

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>

1
vsync

Извините, насколько я знаю, невозможно отменить любое событие прокрутки.

Оба W3 и MSDN говорят:

Cancelable  No
Bubbles     No

Я думаю, вам придется оставить это на усмотрение авторов браузера. Firefox (3.5 в Linux, в любом случае), кажется, ведет себя лучше: он прокручивает родительский элемент, только если дочерний элемент уже находится в верхнем/нижнем конце в тот момент, когда вы start используете колесо прокрутки.

25
bobince

Если мы не можем предотвратить прокрутку окна, почему бы не отменить ее? То есть перехватить событие прокрутки и затем прокрутить обратно в фиксированное положение.

Следующий код блокирует ось 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/ (введите несколько символов в верхнее окно поиска, чтобы сделать прокручиваемую панель видимой):

Screenshot

Это работает безупречно в Chrome/Safari (Webkit) и с некоторыми скроллами в Firefox и Opera. По какой-то причине он не работает с моей установкой IE. Я предполагаю, что это связано с методом наведения jQuery, который, кажется, не работает правильно в 100% всех случаев.

17
Christian Kohlschütter

Я знаю, что это довольно старый вопрос, но так как это один из лучших результатов в 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);
}
4
Nebril

мой плагин 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;
    });
}
3
psycho brm

Вот как я решил проблему:

Когда я открываю всплывающее окно, я вызываю следующее:

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

Затем, когда я закрываю всплывающее окно, я называю это:

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

Всплывающее окно должно быть модальным, поэтому взаимодействие с нижележащим телом не требуется.

Работает довольно хорошо

1
Gianluca Ghettini

Видимо, вы можете установить overflow:hidden, чтобы предотвратить прокрутку . Не уверен, как это будет, если документ уже прокручен. Я тоже на ноутбуке без мыши, так что сегодня вечером я не буду тестировать колесо прокрутки :-) Хотя, наверное, стоит попробовать.

0
Dan F

Вот что я делаю:

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

демо скрипка

Используйте CSS overflow:hidden, чтобы скрыть полосу прокрутки, так как это ничего не изменит, если они перетащат ее.

Работает кросс-браузер

0
parliament

Я хотел бы добавить немного обновленный код, который я нашел, чтобы работать лучше всего:

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

Разница между этим и тем, что уже упоминалась выше, заключается в добавлении большего количества событий и использовании outerHeight () вместо height () , чтобы избежать сбоя, если элемент имеет отступ!

0
Aleksandar Ivanov

Новый веб-разработчик здесь. Это сработало как для меня 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();
        }
    }
}

Не позволяйте количеству строк ввести вас в заблуждение, это довольно просто - просто немного многословно для удобочитаемости (самодокументированный код, верно?)

0
Vivek Maharajh

вы можете попробовать jscroll pane внутри iframe, чтобы заменить прокрутку по умолчанию. 

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

Я не уверен, но попробуйте

0
adardesign

На данный момент в 2018 году и далее достаточно e.preventDefault.

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

Это предотвратит прокрутку к родителю.

0
Must Keem J
$('.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();
    }
});
0
Roland Soós