Прокрутка дочернего div прокручивает окно, как я могу остановить это?

У меня есть div, с полосой прокрутки. Когда он дойдет до конца, моя страница начнет прокрутку. В любом случае я могу остановить это поведение?

Ответ 1

Найден решение.

http://jsbin.com/itajok

Это то, что мне нужно.

И это код.

http://jsbin.com/itajok/edit#javascript,html

Использует подключаемый модуль jQuery.


Обновление из-за уведомления об отказе

От jquery-mousewheel:

Старое поведение добавления трех аргументов (delta, deltaX и deltaY) для обработчика событий теперь устарели и будут удалены позже релизов.

Затем теперь нужно использовать event.deltaY:

var toolbox = $('#toolbox'),
    height = toolbox.height(),
    scrollHeight = toolbox.get(0).scrollHeight;

toolbox.off("mousewheel").on("mousewheel", function (event) {
  var blockScrolling = this.scrollTop === scrollHeight - height && event.deltaY < 0 || this.scrollTop === 0 && event.deltaY > 0;
  return !blockScrolling;
});

Демо

Ответ 2

Вы можете инактивировать прокрутку всей страницы, выполнив что-то вроде этого:

<div onmouseover="document.body.style.overflow='hidden';" onmouseout="document.body.style.overflow='auto';"></div>

Ответ 3

Выбранное решение является произведением искусства. Думал, что это достойно плагина....

$.fn.scrollGuard = function() {
    return this
        .on( 'wheel', function ( e ) {
            var event = e.originalEvent;
            var d = event.wheelDelta || -event.detail;
            this.scrollTop += ( d < 0 ? 1 : -1 ) * 30;
            e.preventDefault();
        });
};    

Это было неудобством для меня, и это решение настолько чистое по сравнению с другими хаками, которые я видел. Любопытно узнать, как больше о том, как это работает и насколько широко поддерживается, но приветствует Jeevan и того, кто изначально придумал это. BTW - редактор ответов stackoverflow нуждается в этом!

UPDATE

Я считаю, что это лучше в том смысле, что он вообще не пытается манипулировать DOM, только предотвращает пузырьки условно...

$.fn.scrollGuard2 = function() {
  return this
    .on( 'wheel', function ( e ) {
      var $this = $(this);
      if (e.originalEvent.deltaY < 0) {
        /* scrolling up */
        return ($this.scrollTop() > 0);
      } else {
        /* scrolling down */
        return ($this.scrollTop() + $this.innerHeight() < $this[0].scrollHeight);
      }
    })
  ;
};    

Отлично работает в хроме и намного проще, чем другие решения... дайте мне знать, как это работает в другом месте...

FIDDLE

Ответ 4

Вы можете использовать событие mouseover на div, чтобы отключить панель прокрутки тела, а затем событие mouseout, чтобы снова активировать его?

например. HTML

<div onmouseover="disableBodyScroll();" onmouseout="enableBodyScroll();">
    content
</div>

А затем javascript, например:

var body = document.getElementsByTagName('body')[0];
function disableBodyScroll() {
    body.style.overflowY = 'hidden';
}
function enableBodyScroll() {
    body.style.overflowY = 'auto';
}

Ответ 5

Если я правильно понял ваш вопрос, то вы хотите предотвратить прокрутку основного содержимого, когда мышь находится над div (скажем, боковой панели). Для этого боковая панель не может быть дочерним элементом контейнера прокрутки основного содержимого (который был окном браузера), чтобы предотвратить событие прокрутки от пузырька до его родителя.

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

<div id="wrapper"> 
    <div id="content"> 
    </div> 
</div> 
<div id="sidebar"> 
</div> 

Посмотрите, как работает этот образец скрипта и сравните это с этот образец скрипта, который немного отличается от поведения мыши на боковой панели.

См. также прокрутите только один отдельный div с главной полосой прокрутки браузера.

Ответ 6

Я написал решение для этой проблемы

  var div;
  div = document.getElementsByClassName('selector')[0];

  div.addEventListener('mousewheel', function(e) {
    if (div.clientHeight + div.scrollTop + e.deltaY >= div.scrollHeight) {
      e.preventDefault();
      div.scrollTop = div.scrollHeight;
    } else if (div.scrollTop + e.deltaY <= 0) {
      e.preventDefault();
      div.scrollTop = 0;
    }
  }, false);

Ответ 7

Здесь кросс-браузерный способ сделать это по оси Y, он работает на рабочем столе и на мобильных устройствах. Протестировано на OSX и iOS.

var scrollArea = this.querySelector(".scroll-area");
scrollArea.addEventListener("wheel", function() {
    var scrollTop = this.scrollTop;
    var maxScroll = this.scrollHeight - this.offsetHeight;
    var deltaY = event.deltaY;
    if ( (scrollTop === maxScroll && deltaY > 0) || (scrollTop === 0 && deltaY < 0) ) {
        event.preventDefault();
    }
});

scrollArea.addEventListener("touchstart", function(event) {
    this.previousClientY = event.touches[0].clientY;
});

scrollArea.addEventListener("touchmove", function(event) {
    var scrollTop = this.scrollTop;
    var maxScroll = this.scrollHeight - this.offsetHeight;
    var currentClientY = event.touches[0].clientY;
    var deltaY = this.previousClientY - currentClientY;
    if ( (scrollTop === maxScroll && deltaY > 0) || (scrollTop === 0 && deltaY < 0) ) {
        event.preventDefault();
    }
    this.previousClientY = currentClientY;
});

Ответ 8

$this.find('.scrollingDiv').on('mousewheel DOMMouseScroll', function (e) {
  var delta = -e.originalEvent.wheelDelta || e.originalEvent.detail;
  var scrollTop = this.scrollTop;
  if((delta < 0 && scrollTop === 0) || (delta > 0 && this.scrollHeight - this.clientHeight - scrollTop === 0)) {
    e.preventDefault();
  }
});

Ответ 9

это отключает прокрутку в окне, если вы вводите элемент селектора. работает как прелести.

elements = $(".selector");

elements.on('mouseenter', function() {
    window.currentScrollTop = $(window).scrollTop();
    window.currentScrollLeft = $(window).scrollTop();
    $(window).on("scroll.prevent", function() {
        $(window).scrollTop(window.currentScrollTop);
        $(window).scrollLeft(window.currentScrollLeft);
    });
});

elements.on('mouseleave', function() {
    $(window).off("scroll.prevent");
});

Ответ 10

Вы можете инактивировать прокрутку всей страницы, выполнив что-то вроде этого, но покажите полосу прокрутки!

<div onmouseover="document.body.style.overflow='hidden'; document.body.style.position='fixed';" onmouseout="document.body.style.overflow='auto'; document.body.style.position='relative';"></div>

Ответ 11

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

jQuery.fn.scrollGuard = function() {
    this
        .addClass('scroll-guarding')
        .off('.scrollGuard').on('mouseenter.scrollGuard', function() {
            var $g = $(this).parent().closest('.scroll-guarding');
            $g = $g.length ? $g : $(window);
            $g[0].myCst = $g.scrollTop();
            $g[0].myCsl = $g.scrollLeft();
            $g.off("scroll.prevent").on("scroll.prevent", function() {
                $g.scrollTop($g[0].myCst);
                $g.scrollLeft($g[0].myCsl);
            });
        })
        .on('mouseleave.scrollGuard', function() {
            var $g = $(this).parent().closest('.scroll-guarding');
            $g = $g.length ? $g : $(window);
            $g.off("scroll.prevent");
        });
};

Один простой способ использования - добавить класс, такой как scroll-guard, ко всем элементам страницы, на которые вы можете прокручивать. Затем используйте $('.scroll-guard').scrollGuard(), чтобы защитить их.

Ответ 12

Если вы применяете стиль overflow: hidden, он должен уходить

edit: на самом деле я неправильно прочитал ваш вопрос, который скроет полосу прокрутки, но я не думаю, что вы ищете.

Ответ 13

Я не мог получить ответы на работу в Chrome и Firefox, поэтому я придумал это объединение:

$someElement.on('mousewheel DOMMouseScroll', scrollProtection);

function scrollProtection(event) {
    var $this = $(this);
    event = event.originalEvent;
    var direction = (event.wheelDelta * -1) || (event.detail);
    if (direction < 0) {
        if ($this.scrollTop() <= 0) {
            return false;
        }
    } else {
        if ($this.scrollTop() + $this.innerHeight() >= $this[0].scrollHeight) {
            return false;
        }
    }
}