css overflow-x (or y): hidden breaks javascript .scrollTop - javascript

I'm trying to use a javascript to change a div when you past a certain height scrolling:
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if(scroll > 300){
$('#div').addClass('class');
}
if(scroll > 500){
$('#div').removeClass('class');
}
});
But on the CSS, the properties:
body, html{
overflow-y: overlay
overflow-x: hidden
}
makes the Javascript useless, and it's both X and Y, i've tried with only one hidden, unset, etc.
And they need to be BOTH unset for this script to work.
I would like any way to go around this, either a new Javascript function or any other way to hide the scroll bars. Thank you :)
Tried: CSS overflow:hidden + Javascript scrollTop
Expected: work
Result: didn't work

Related

overflow breaks javascript

I'm trying to use a javascript to change a div when you past a certain height scrolling:
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if(scroll > 300){
$('#div').addClass('class');
}
if(scroll > 500){
$('#div').removeClass('class');
}
});
But on the CSS, the properties:
body, html{
overflow-x: hidden
}
makes the Javascript useless, and it's both X and Y, i've tried with only one hidden, unset, etc. And they need to be BOTH unset for this script to work.
I would like any way to go around this, either a new Javascript function or any other way to hide the scroll bars. Thank you :)
Tried: CSS overflow:hidden + Javascript scrollTop Expected: work Result: didn't work

How to detect when at the bottom of a scrollable div?

I created a website that loads data as you scroll down. Every time you hit the bottom of the page, it loads another 100 rows. I'm trying to replicate this in a div so that the header is always at the top no matter how far you scroll down.
I'm using JQuery and the scrollTop() function to do this.
Here is my code that works if it is not detecting the scroll bar in the div, but the whole window.
$(window).scroll(function(){
if ($(window).scrollTop() == $(document).height() - $(window).height()){
for(i; i < size+100; i++){
document.getElementById('myTable').innerHTML += IPAMArray[i];
}
size = i;
}
});
Now i change the div to this:
<div class = "tableDiv" id="myTableDiv" style="height:800px;width:1000px;border:1px solid #ccc; overflow: scroll;"><table id = "myTable"></table></div>
I dont know how to change this line from "document" and "window" to the correct div variables:
if ($(window).scrollTop() == $(document).height() - $(window).height()){
Here is where i'm currently at with that line:
if ($("div.tableDiv").scrollTop() == $(document).height() - $("div.tableDiv").height()){
I've tried quite a few variants, but i'm completely guessing the code so it could take forever. I would prefer to refer to this div by its ID rather than its class, but i just started using the class references because thats how most of the examples are online. I have tried $(document).getElementById('myTableDiv') in various ways as well but cant seem to find the solution.
if ($("#myTableDiv").scrollTop() == $("#myTable").outherHeight() - $("#myTableDiv").height()){
use ids to identify elements
the height of the inner element is what you need ($("#myTable").height())
jquery's height() function doesn't include borders margins and / or paddings as noted in the doc. Use outherHeight() instead.
OR
make your header position: fixed in css

How would I make div stick to top of screen using this code?

The code below is test code I'm using. The blue bar is supposed to stick to the top of the screen when it reaches the top.
This works on my browser, but the reason I'm here is because when it sticks to the top, it all of a sudden becomes smaller. As you see the blue bar starts with a full width across the container, but on my computer/browser, after it sticks to the top, the div shrinks to just the size of the text.
To make matters worse, I cannot reproduce the problem on jfiddle, because in jfiddle it doesn't work at all! (The images are just there to create a scroll).
Here is the jfiddle
Here is the jquery:
var titlePosition = $('.title').offset().top;
$(window).scroll(function () {
var scrollBar = $(this).scrollTop();
if (scrollBar > titlePosition) {
$('.title').css("top", "0px");
$('.title').css("position", "fixed");
} else {
$('.title').css("position", "relative");
}
});
Try this code:
Fiddle
CSS:
.title {
font-size:200%;
background-color:blue;
width:100%
}
Update your code:
if (scrollBar > titlePosition) {
$('.title').css("top", scrollBar+"px");
$('.title').css("position", "fixed");
} else {
$('.title').css("position", "static"); //otherwise it will still get that top value and cause unwanted position;
}
Just add this css:
.title {
...
width: 100%; /*This does the trick*/
}
Here you have it working: http://jsfiddle.net/edgarinvillegas/yPWAC/3/
Cheers
Set left to 0 as well. Additionally, some optimizations.
I prefer appending/removing classes to put all your CSS in your stylesheet. Saves you from problems later on when the code gets huge (who would be looking for CSS in JS files anyway?).
Also, cache objects. Everytime you fire scroll, your code fetches every single .title in the DOM and generates a jQuery object. Not very optimal. Instead, get all .title and just do the modifications on each scroll.
CSS:
.title.fixed {
position:fixed;
left:0;
right:0;
top:0;
}
JS:
var titlePosition = $('.title').offset().top;
var win = $(window);
var title = $('.title');
win.scroll(function () {
var scrollBar = win.scrollTop();
if (scrollBar > titlePosition) title.addClass('fixed');
else title.removeClass('fixed');
});
As for your non-working fiddle, you forgot to include jQuery. That should be found on the top left.
Try giving z-index:999 or, using jQuery - $('.title').css("z-index", "999");
Rest looks ok.
var titlePosition = $('.title').offset().top;
.top is not a function. offset() returns an object containing the properties top and left
Replace with:
var titlePosition = $('.title').offset();
You can now access the properties like so:
titlePosition.top or titlePosition.left
reference: .offset() http://api.jquery.com/offset/
Thanks for all the feedback.
Even though it helped improve, in the end the div was still resizing. Fixing the width to specific values was not responsive enough.
I finally stumbled upon a solution, based on all the advice:
http://jsfiddle.net/yPWAC/8/
var titleWidth = $('.title').width()
/*then after the div is fixed I change the width */
$('.title').css("width",titleWidth);
I made jquery hold the original width of the div, then change the width of the sticky div to whatever that value is.
For some reason, even if I defined the original width in CSS, the new sticky width would still come out a different size in the browser. So this method gives it the same width as the original (whatever it may be)

Overflow: hidden but i still want to have the empty scrollbar

I set 'overflow:hidden' on my html body with Javascript when I press a button. But when I do that the whole body moves 5 pixels or so to the left because the space of the scrollbar is gone. How do i prevent that.
I can't set margin of the body to a specific size because the width of scrollbars differentiate between browsers
Since the previous solution does not work anymore (see original answer below), I've come across another solution which works for me and, according to MDN, it should work in all browser, with IE starting from version 6.
This solution to get the scrollbar width is even a bit simplified:
Append a div without a scrollbar to the body and position it off screen
Measure the client width of the div
Set the div to have a scrollbar (using css overflow style)
Measure the clientWidth of the div again
Remove the div
Return the difference of the two widths
And the code would look like this:
function scrollbarWidth() {
var div = $('<div style="width:50px;height:50px;overflow:hidden;position:absolute;top:-200px;left:-200px;"></div>');
// Append our div, do our calculation and then remove it
$('body').append(div);
var w1 = div.prop('clientWidth');
div.css('overflow-y', 'scroll');
var w2 = div.prop('clientWidth');
$(div).remove();
return (w1 - w2);
}
And here is a working jsFiddle.
Original answer (for completeness sake)
Here is a solution to calculate the width of a scrollbar, which you can use in conjuction with some of the other answers here (and your own knowledge as far as I can tell).
The idea is to do the following steps:
Append two divs to the body and position them off screen
Measure the width of the inner div
Set the outer div to overflow
Measure the width of the inner div (again)
Remove the divs
Return the difference of the two widths
And here is the code, copied from the referenced page:
function scrollbarWidth() {
var div = $('<div style="width:50px;height:50px;overflow:hidden;position:absolute;top:-200px;left:-200px;"><div style="height:100px;"></div>');
// Append our div, do our calculation and then remove it
$('body').append(div);
var w1 = $('div', div).innerWidth();
div.css('overflow-y', 'scroll');
var w2 = $('div', div).innerWidth();
$(div).remove();
return (w1 - w2);
}
You could try this old trick:
html {
overflow-y: scroll;
}
What this does is force the scrollbar to always be visible.
Compare:
normal JSFiddle
JSFiddle with the vertical scrollbar always there
Here is code to add a disabled vertical scroll bar. If placed more prominent in CSS than the rest of the CSS, it should override whatever you've done to other portions.
html {
overflow-y: scroll;
}
You could always put a wrapper around the content that you are hiding and then place the overflow: scroll on div and overflow: hidden on the content div.
#wrapper { overflow-y: scroll; }
#content { overflow: hidden; }
See the attached fiddle for a working version
http://jsfiddle.net/15km/bfpAD/1/

Always scroll a div element and not page itself

I have a page layout with an inner <div id="content"> element which contains the important stuff on the page. The important part about the design is:
#content {
height: 300px;
width: 500px;
overflow: scroll;
}
Now when the containing text is larger than 300px, I need to be able to scroll it. Is it possible to scroll the <div>, even when the mouse is not hovering the element (arrow keys should also work)?
Note that I don’t want to disable the ‘global’ scrolling: There should be two scrollbars on the page, the global scrollbar and the scrollbar for the <div>.
The only thing that changes is that the inner <div> should always scroll unless it can’t be moved anymore (in which case the page should start scrolling).
Is this possible to achieve somehow?
Edit
I think the problem was a bit confusing, so I’ll append a sequence of how I would like it to work. (Khez already supplied a proof-of-concept.)
The first image is how the page looks when opened.
Now, the mouse sits in the indicated position and scrolls and what should happen is that
First the inner div scrolls its content (Fig. 2)
The inner div has finished scrolling (Fig. 3)
The body element scrolls so that the div itself gets moved. (Fig. 4)
Hope it is a bit clearer now.
(Image thanks to gomockingbird.com)
I don't think that is possible to achieve without scripting it, which could be messy, considering the numerous events which scroll an element (click, scrollwheel, down arrow, space bar).
An option could be using the jQuery scroll plugin. I know it has the availability to create scrollbars on an div. The only thing you need to add yourself is the logic to catch the events when keyboard buttons are pressed. Just check out the keycodes for the arrow keys and make the div scroll down.
The plugin can be found here.
You can use it like this;
<script type="text/javascript">
// append scrollbar to all DOM nodes with class css-scrollbar
$(function(){
$('.css-scrollbar').scrollbar();
})
</script>
here is a solution that might work: (fiddle: http://jsfiddle.net/maniator/9sb2a/)
var last_scroll = -1;
$(window).scroll(function(e){
if($('#content').scrollTop());
var scroll = $('#view').data('scroll');
if(scroll == undefined){
$('#content').data('scroll', 5);
scroll = $('#content').data('scroll');
}
else {
$('#content').data('scroll', scroll + 5);
scroll = $('#view').data('scroll');
}
/*
console.log({
'window scroll':$('window').scrollTop(),
'scroll var': scroll,
'view scroll':$('#view').scrollTop(),
'view height':$('#view').height(),
'ls': last_scroll
});
//*/
if(last_scroll != $('#content').scrollTop()){ //check for new scroll
last_scroll = $('#content').scrollTop()
$('#content').scrollTop($('#content').scrollTop() + scroll);
$(this).scrollTop(0);
//console.log(e, 'scrolling');
}
})
It is a bit buggy but it is a start :-)
The only way I believe you can achieve this is through the use of frames.
Frames - W3Schools Reference
If you just want to have a fixed positioned "div" and scroll only it, maybe you could use a trick like:
http://jsfiddle.net/3cpvT/
Scrolling with mouse wheel and all kinds of keys works as expected. Only thing is that the scrollbar is on the document body only.
I found a solution... Not perfect... http://jsfiddle.net/fGjUD/6/.
CSS:
body.noscroll {
position: fixed;
overflow-y: scroll;
width: 100%;
}
JS (jQuery):
if ($("body").height() > $(window).height()) {
var top;
$('#scrolldiv').mouseenter(function() {
top = $(window).scrollTop();
$('body').addClass('noscroll').css({top: -top + 'px'});
}).mouseleave(function() {
$('body').removeClass('noscroll');
$(window).scrollTop(top);
});
}
The text wrapping problem can be solved putting the whole content in fixed-width div. There is another bug for IE browser. If the page has center-aligned backgrond, it will move left-right on mouseenter on #scrolldiv

Categories