Hide default browser scroll bar without overflow:hidden when using Perfect Scrollbar - javascript

I'm using "perfect scroll bar" on my web page. To hide the default browser scroll bars it adds "overflow:hidden". (http://noraesae.github.io/perfect-scrollbar/)
I'm also using Jquery Sortable in the scrollable section. (http://jqueryui.com/sortable/)
The overflow hidden needed for perfect scroll is a barrier for sortable. When I drag a div it won't scroll down as needed because overflow is hidden. ( But when you scroll with the mouse wheel it will scroll ).
When I removed overflow:hidden the default scrollbar AND the perfect scroll bar shows. (Both of them work as expected)
So, how do I visually hide the scrollbar so that the overflow is not hidden but only the scrollbar is just not visible.

You can enclose your entire page inside a div whose height and width are equal to that of the window and then apply the perfect scroll bar on that div.
HTML:
<div class="body">
<!-- page content -->
</div>
JS
$(".body").css({
"width": $(window).width() + "px",
"height": $(window).height() + "px"
});

The short answer here, is that without using overflow: hidden you're not going to be able to hide the scrollbars.
While webkit browsers do support ::-webkit-scrollbar, ::-webkit-scrollbar-button, ::-webkit-scrollbar-track, ::-webkit-scrollbar-track-piece, ::-webkit-scrollbar-thumb, ::-webkit-scrollbar-corner and ::-webkit-resizer in your CSS, targeting other browsers will be difficult.
A possible "hack" could be wrapping your content in a div with the same size as the window, applying PerfectScrollbars to said div, and placing your jQuery Sortable content inside a child div.

You can try this
HTML
<body>
<div id="scroll">
//Your all content
</div>
</body>
CSS
body{
overflow: hidden;
}
#scroll{
position: relative;
margin: 0px auto;
padding: 0px;
width: auto;
height: auto;
}
JS
$(window).resize(function(){
$("#scroll").css({
"width": $(window).width() + "px",
"height": $(window).height() + "px"
});
});
const ps = new PerfectScrollbar('#scroll', {
wheelSpeed: 2,
wheelPropagation: true,
minScrollbarLength: 20
});
ps.update();

Related

Prevent browser viewport from sticking to bottom when page height increases in runtime?

Modern browsers seem to have a feature where the viewport sticks to bottom when page height increases. What actually happens is that browser scrolls the viewport at the same rate as height being increased when initial position is at (or very close to) the bottom of the page. This results in appearance as if page is expanding upwards instead of downwards.
How can this feature be disabled for a certain page using CSS or JS, so that the page would always visually expand downwards?
This of course, also happens when added element's height is expanded animated. For this reason, if possible, I would want to avoid resetting scroll position afterwards to prevent visible jump. The demo of this "feature" (that seems to happen only within rare conditions) interacting with the viewport and drop animation can be observed in the gif below.
I know there must be a way, otherwise every site with infinite scroll would suffer from an infinite loop. Counter argument: Chrome appears not to do this for containers that surpass certain height limit. So maybe infinite-scroll sites don't even bother addressing this in their sites.
Check this fiddle. You can observe that in Chrome, the first container snaps to the bottom, while the other divs has a scroll relative to the top. In Firefox or IE 11, you cannot observe this behavior.
This happens when the top bound of the last element on a scroll container is above the top bound of the container. The browser decides that the last element is what the user is interested in and decides to stay in that position.
The last div doesn't snap to the bottom because the scroll happens relative to the top bound of the last element and the last element is growing.
If you want a different behavior, I would not suggest handling it with Javascript, but I would suggest changing your layout considering these rules. For example the last div should be the growing one, instead of the previous siblings of it.
Obligatory code:
var div = document.querySelectorAll('.growing');
var height = 500;
setInterval(function(){
height += 100;
div[0].style.height = height + 'px';
div[1].style.height = height + 'px';
div[2].style.height = height + 'px';
},1000);
.start, .end{
height: 110px;
}
.start{
background: red;
}
.end{
background: green;
}
.growing{
background: yellow;
}
.cnt1,.cnt2,.cnt3{
overflow: auto;
border: 5px solid black;
margin: 5px 0;
scroll-snap-type: mandatory;
}
.cnt1{
height: 100px;
}
.cnt2{
height: 120px;
}
.cnt3{
height: 100px;
}
<div class="cnt1">
<div class="start"></div>
<div class="growing"></div>
<div class="end"></div>
</div>
<div class="cnt2">
<div class="start"></div>
<div class="growing"></div>
<div class="end"></div>
</div>
<div class="cnt3">
<div class="start"></div>
<div class="end"></div>
<div class="growing">
Content
</div>
</div>
Edit:
If the bounds of the growing div is in the visible area, the scroll is relative to the top of the growing div. So you can hack CSS to show the growing div, but actually not show it.
In this fiddle I have used two different CSS hacks. First one is adding a negative margin bottom and a positive padding bottom at same amount. The second hack is adding an :after element to the growing div but hide its visibility.
for click events, use blur, avoid scrollTo
It seems like this issue is focus-related. I came across a similar bug and when the element that triggered a height change was switched to an unfocusable element, like a div, the screen jumping disappeared. This clearly isn't a great solution because we should be able to use buttons! It also implicates focus in this strange behavior. Further experimentation led to blurring the trigger element before the height change, which solves the problem without moving the viewport. I've only tried this with click events so I'm not sure if it works for drag n drop.
codepen that showcases viewport jumping with accordions and a blur fix
function handleClick(e) {
e.currentTarget.blur();
// code to change height
}
Do you mean that when you scroll to the bottom, and a piece of content gets added, you stay at the bottom? Because the solution for that is real simple:
Option 1
Store the current scrolloffset to the top (eg how many px you've scrolled down)
Add new content
Set scrolloffset to the top to the stored value
Those last two steps can be done so fast that the user wont notice.
Option 2
Not 100% sure this works, but i'm guessing it does:
When the visitor scroll to the bottom, always scroll them back 3px. This way, they're not at the bottom at the point where new content gets added, so the browser stays where it is.
As per my understanding regarding your requirement, I have given a working jsfiddle sample.
Hope it would help to you.
If you expect something more, feel free to add comment.
Cool!
$(function(){
var height = 200;
var pos = 0;
setInterval(function(){
if($(document).height() >= $(window).height()){
var height = $('.container1').height();
$('.container1').height(height + 20);
pos = pos + 20;
$(window).scrollTop(pos);
}
}, 1000);
});
.container1 {
border: 1px solid #ccc;
min-height: 200px;
background: #ccc;
height: auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container1">
<p>11</p>
<p>12</p>
<p>13</p>
</div>
All of your draggable elements are in a container with no auto overflow, when you drag and drop your elements the whole page scrolls due to dragging.
Instead of that do as:
<div class="container">
<!-- Place all your draggable elements here -->
</div>
set a max-height and overflow of the container class as:
.container {
max-height: 400px;
overflow: auto;
}
Now when you drag and drop your elements, instead of the whole page, the only container will scroll.
After implementing this solution, it will look like this.
Before dragging.
While dragging.
Hope this helps you.

The page gets scrolled to the top if I apply height to the body

My problem is that I have a button on the html page, and when this button is clicked a popup box opens(covering the background), and to stop the background scroll I am applying this css:
windowHeight = $(window).height();
$("body").css({
"height": windowHeight,
"overflow": "hidden",
"overflow-y": "hidden"
});
Everything works perfectly but the page gets scrolled to top. How do I prevent this?
This is due to the fact that you change the height. You don't need to set the height, making the body overflow: hidden should be enough.
CSS:
.locked {
overflow-x: hidden; overflow-y: hidden;
}
Javascript:
$("body").addClass("locked");
Try it: http://jsbin.com/tapagexope/1/edit?html,css,js,output (Click the body)
Tested in FF 34 and Chrome 38.
Note that you should position your overlay in a container that is position: fixed and left, top, bottom, right are all 0, covering the whole viewport. Within that box you can center your overlay element.
I actually already wrote a jQuery plugin to solve this exact problem: jquery-disablescroll
Using the plugin script, when the popup opens call:
$(window).disablescroll();
When the popup is closed, enable scrolling again by calling:
$(window).disablescroll("undo");
Here's the example.

Footer stick to bottom

I have bootstrap accordion in which all panels are collapsed except first one. The height of body is more than window height when the page first loads. The footer is stuck to the bottom of the page initially, and it remains at the bottom if I expand another panel from accordion.
The problem is that, when all the panels are collapsed the body is of less height than the window height. In this scenario the footer is not sticking to the bottom of the window, It positions in the middle of the window where accordion ends.
I tried capturing the resize event, so if the body is of less height than the window then I would stick the footer to the bottom of the window else to bottom of the body, but resize doesn't work in case of accordion trigger.
Here is something I tried :
$(window).resize(function(){
footPosition();
});
function footPosition()
{var bodyHeight = $("body").height();
var vwptHeight = $(window).height();
if (vwptHeight > bodyHeight) {
$("footer#pageFooter").css("position","absolute").css("bottom",0).css("width","100%");
}else{
$("footer#pageFooter").css("position","static").css("bottom",0).css("width","100%");
}
}
Sorry I can't give you the accordion code, its too large.
But its a simple bootstrap accordion and I am stuck on this problem from last two days.
please help.
What you’re looking for is CSS Sticky Footer
<div id="footer">
</div>
#footer {
position: relative;
bootom: 0;
margin-top: -180px; /* negative value of footer height */
height: 180px;
clear:both;
}

CSS how to fix an element to scroll horizontally with the page but not vertically?

I have created an example to help explain. http://jsfiddle.net/9AUbj/1/
<style>
div#one {}
div#two {
height: 50px;
background-color: blue;
width: 1000px;
}
div#three {
height: 1000px;
}
</style>
...
<div id="one">Hello World!</div>
<div id="two"></div>
<div id="three"></div>
I would like "Hello World!" to move horizontally with the window when the user scrolls horizontally. But I DON'T want it to move vertically with the window when the user scrolls vertically. What is the best way to do this? I'm using Bootstrap and jQuery UI, in case those might help. However, I am also interested in a pure CSS solution.
Thanks in advance :-)
ktm
Whenever you scroll the window, reposition the #one element to always be on screen. Also, #one should be position: absolute.
$(window).scroll(function () {
$("#one").css({
left: $(this).scrollLeft()
});
});
Here's your fiddle with the new code: http://jsfiddle.net/9AUbj/15/
While I admit that a CSS-only solution would be cool, you can't apply positioning based on axis. With how fixed positioning works, you can't force a horizontal scroll on the document even if the fixed-position element extends outside.
However, this is very simple to do with jQuery
$(document).on('scroll', function () {
$("#two").css('top', $(this).scrollTop());
});
This requires #two to be absolutely positioned.
http://jsfiddle.net/9AUbj/16/
i used this code
$(window).scroll(function () {
$("#one").css({
left: $(this).scrollLeft()
});
});
and it works perfect on Chrome , but on internet explorer when i drag the horizontal scroll, the fixed content starts to flicker :(

css animation moves page - fix page scroll position on current element with css?

Given the following simplified problem:
foreach i in 1..100 do
<div onclick="$("div").attr('class','expand');">block i</div>
And this css:
div {
height: 20px;
transition: height 0.5s;
}
div.expand {
height: 50px;
}
Now when I click on a div, every div get's the class "expand". This means that the page will expand. However, everything will scroll down. That means that if I click on div 50, it will probably not be in my window anymore and I have to scroll down to see it again.
I would love to make the div that I clicked on stay in the center of the screen. Is this possible with CSS, or do I need JS?
it is possible ... you can use jQuery's .scrollTop() method like this:
$(window).scrollTop( $('.your_element').offset().top + $('.your_element').height() - $(window).height() );
This function scrolls the page according to the position of mouseclick:
$(document).ready(function(){
$('div').click(function(e){
var offsetY = e.pageY - $(window).scrollTop();
$('div').attr('class','expand');
$(window).scrollTop($(this).offset().top-offsetY);
});
});
Example on jsFiddle

Categories

Resources