Создание бесшовного вложенного прокрутки прокрутки
Я пытаюсь создать серию оконных размерных div с внутренними divs размеров переменных > размер окна. Уловку нужно прокручивать, как если бы divs не были вложены.
Короче говоря, я хочу ЭТО:
css{
block{ height:100wh; }
innerBlockSmall{ height:100wh; }
innerBlockLarge{ height:200wh; }
}
<div class="block">
<div class="innerBlockLarge"></div>
</div>
<div class="block">
<div class="innerBlockSmall"></div>
</div>
https://jsfiddle.net/cbuh8psd/
действовать так же, как ЭТО
css{
innerBlockSmall{ height:100wh; }
innerBlockLarge{ height:200wh; }
}
<div class="innerBlockLarge"></div>
<div class="innerBlockSmall"></div>
https://jsfiddle.net/t6zrvo7u/1/
К сожалению, прокрутка "Фокус" срабатывает hover
по прокручиваемому элементу. В этом случае это нежелательное поведение.
Есть два возможных решения, о которых я сейчас знаю.
-
Вручную назначает прокрутку "Фокус" через javascript. (Оптимальное)
-
Полностью переписывает javascript по умолчанию для прокрутки по умолчанию, для
пример библиотеки ISCROLL5.
(хорошо, если удар производительности мал)
К сожалению, просмотрев документацию developer.mozilla HTML5, я не перешел ни в какую сторону, чтобы прокрутить "Фокус" к элементу через javascript.
Что касается варианта 2: у ISCROLL5 было нежелательное поражение производительности с более чем 15-20 прокручивающимися div.
Я надеюсь, что здесь что-то не хватает, любые решения, исправления или советы будут очень оценены.
Ответы
Ответ 1
Я понятия не имею, почему вы хотели бы это сделать, но единственный способ, которым я могу думать о достижении желаемого эффекта, - это воссоздание полосы прокрутки, однако хорошая новость заключается в том, что это не стоит за счет потерять свой родной опыт.
К сожалению, я не могу вспомнить проект, который я написал для этого кода, хотя один из способов добиться этого - сделать себя компонентом прокрутки. Этот компонент полосы прокрутки действительно обеспечил бы поддельную полосу прокрутки, но обеспечивал бы родной интерфейс. Итак, как вы это делаете?
- Вы определяете ширину полосы прокрутки, принимая разницу между элементом с и без
overflow: scroll
. Пусть это будет scrollWidth
- Вы создаете
<div>
с overflow: auto
шириной scrollWidth
и position: fixed
на месте с правой стороны тела. Пусть свойство scrollTop
будет scrollPosition
.
- Внутри элемента вы добавляете еще один
<div>
с шириной 0
(это, по крайней мере, работает в Chrome, проверьте, относятся ли другие браузеры по-другому) и пусть высота будет documentLength
.
- Теперь вы можете полностью управлять полосой прокрутки, установив
documentLength
и scrollPosition
любым способом. В вашем случае вы установите documentLength
как объединенные значения прокруткиHeight каждого элемента и scrollPosition
на основе относительного scrollTop
в этих узлах.
В этом jsfiddle можно найти очень базовую демонстрацию концепции (а не реализации) (обратите внимание на width
полоса прокрутки привязана к 20px
в этом случае и динамический код вообще отсутствует).
Ответ 2
Это решение позволяет прокручивать весь документ, сохраняя возможность прокрутки каждого вложенного div мышью. Надеюсь, я правильно тебя понял.
Это просто концепция, она не предотвращает прокрутку вложенных элементов вместе с окном. Но его можно улучшить.
Array.prototype.slice.call( document.getElementsByClassName('sbRemover') )
.forEach(function (div) {
var scroll = 0,
mousedown = false,
mouseBtnHandler = function (e) {
mousedown = e.type == 'mousedown';
}
div.addEventListener('scroll', function (e) {
// Change of div scrollTop. Negative when scrolling down
var diff = scroll - e.target.scrollTop;
// Save new scroll value to be able to compare with it later
scroll = e.target.scrollTop;
// Do nothing when div is scrolled by dragging the scrollbar
if (!mousedown) {
// Scroll the window to the same amount of pixels the div was scrolled
window.scrollTo(window.pageXOffset, window.pageYOffset - diff);
}
});
div.addEventListener('mouseup', mouseBtnHandler);
div.addEventListener('mousedown', mouseBtnHandler);
});
body, div {
margin: 0;
padding: 0;
}
.block{
position: relative;
width:100vw;
height:100vh;
overflow: hidden;
z-index: 1;
opacity: 100;
}
.sbRemover{
width:100%;
height:100%;
padding-right:15px;
overflow: auto;
}
.largeContent{
height:225vh;
}
.smallContent{
height:100vh;
}
<div id="simpleCanvas">
<div class="block" style="background-color: blue">
<div class="sbRemover">
<div id="ok" class="largeContent" style="background-image: url('http://silviahartmann.com/background-tile-art/images/grey-repeating-background-8.jpg');"></div>
</div>
</div>
<div class="block" style="background-color: red;">
<div class="sbRemover">
<div class="largeContent" style="background-image: url('http://a1star.com/images/star--background-seamless-repeating9.jpg');"></div>
</div>
</div>
<div class="block" style="background-color: green">
<div class="sbRemover">
<div class="smallContent"></div>
</div>
</div>
<div class="block" style="background-color: blue">
<div class="sbRemover">
<div class="smallContent"></div>
</div>
</div>
<div class="block" style="background-color: red;">
<div class="sbRemover">
<div class="largeContent" style="background-image: url('http://people.stfx.ca/x2011/x2011ane/info102/assignment1/11500341-abstract-colorful-repeating-background.jpg');"></div>
</div>
</div>
<div class="block" style="background-color: green">
<div class="sbRemover">
<div class="smallContent"></div>
</div>
</div>
</div>