предотвратить прокрутку "пузырящийся" от элемента к окну


у меня есть окно модального окна (всплывающее), которое содержит 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(); достаточно...

13 51

13 ответов:

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

и W3 и MSDN говорят:

Cancelable  No
Bubbles     No

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

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

следующий код блокирует ось 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% всех случаев.

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

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

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() вместо высота() чтобы избежать сбоя, если элемент имеет прокладку!

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

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

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

Я не уверен, но дать ему попробовать

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

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

демо-скрипка

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

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

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

$('.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();
    }
});

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

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

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

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

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

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

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

на данный момент в 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();
}

Это должно работать.