Issue calculating table scrollbar location - javascript

So I have a script that adds a slight shadow to table edge where you can scroll, depending on the location of the scrollbar, but it sometimes doesn't work.
This is one part of it:
$('table').on('scrollstart scrollstop', function(){
if($(this).parent().hasClass('table-wrap')){
var elem = $(this),
elemBody = elem.find('tbody'),
elemParent = elem.parent('.table-wrap');
var scrolled = (elemBody.outerWidth() - elemParent.outerWidth() - elem.scrollLeft());
if(scrolled === 0){
elemParent.addClass('left_active');
elemParent.removeClass('right_active');
} else if(elem.scrollLeft() === 0) {
elemParent.removeClass('left_active');
elemParent.addClass('right_active');
} else {
elemParent.addClass('left_active');
elemParent.addClass('right_active');
}
}
});
This part sometimes I have to add "+1" to "elem.scrollLeft() --here---); to make it work.
var scrolled = (elemBody.outerWidth() - elemParent.outerWidth() -
elem.scrollLeft());
But then I noticed, some tables it helps and on others, it stops working. Meaning when I scroll to right the 'right_active' class will not disappear.
Any suggestions?

Have you tried including scrollbar width in your calculation for var scrolled?
var scrolled = (elemBody.outerWidth() - elemParent.outerWidth() - elem.scrollLeft());
I think you are on the right track but the width is probably not precise since .outerWidth() doesn't include scrollbar width. Hence, the maximum scroll width is always greater than the actual element width.

Related

How to make an element become fixed when 50px from the top of the screen

I have a html div element that scrolls with the page but I would like it to become fixed once it reaches 50px from the top of the screen...
How is this done?
My div id is #box
Thanks!
-Ina
If you want it to be fixed at the top of the page at some distance from the top, you can check the top offset of the element and change the class when it reach the distance you want.
Here is the jquery code for your reference
jQuery(document).scroll(function() {
var documentTop = jQuery(document).scrollTop();
console.log('this is current top of your document' + documentTop );
//box top is 891
if (documentTop > 841) {
//change the value of the css at this point
jQuery("#box").addClass("stayfix");
}
else
{
jQuery("#box").removeClass("stayfix");
}
});
You need to be more specific about what have you done so far. For eg, how did you make the div element to scrolls inside the page. using css or js/jquery animation features?That will help us to give more specific answer.
**Edited According to your fiddle.
They are right, this question is duplicate. Here is a code I made with answers from the forum.
var box_top = $("#box").offset().top;
$(window).scroll(function (event) {
if ($(window).scrollTop() >= (box_top - 50)) {
$("#box").css({position:"fixed",top:"50px"});
} else {
$("#box").css({position:"relative"});
}
});
Hope it helps anyway.
https://jsfiddle.net/ay54msd5/1/
Try something like this. It's a solution using jquery (hopefully not a problem) that checks the scrollHeight of the page every time the page scrolls. If the scrollHeight is greater than a certain threshold, the element becomes fixed. If not, the element is positioned relatively (but you can do whatever you want in that case.
$(document).ready(function() {
var navFixed = false;
var $box = $("#box");
var topHeight = 50;
$(document).scroll(function() {
if ($(document).scrollTop() >= topHeight && !navFixed) {
$box.css("position", "fixed");
navFixed = true;
}
else if ($(document).scrollTop() < topHeight && navFixed) {
$box.css("position", "relative");
navFixed = false;
}
});
});
You would have to write some additional CSS targeting the #box element that tells it what coordinates you'd like it to be fixed to.

scroll to a div when scrolling, and scroll to top when div disappear

I have 2 divs on my webpage. first div is "#pattern" (red one), and second on is "#projets".(blue one)
when use scrolls for the first time, the window scrolls automaticaly to the the second div "#projets". I'm using jquery scroll-To plugin.
it works nice, even if when the users scroll with a large amount of scroll there could be on offset from the "#projets" div... If someone has an idea to correct this would be nice, but that's not my main trouble...
Now i'm trying to scroll back to the top of the page ("#pattern" div) as soon as "#pattern" div reappears when scrolling, the red one. so basically it should be as soon as the offset from the top of my screen of my div "#projets" is supperior to 1.
I've tried so many solutions without results, using flags, multiple conditions... it can be the same kind of thing as on this page, but user should be abble to scroll freely inside the page, not scrolling from hash to hash :
http://www.thepetedesign.com/demos/onepage_scroll_demo.html
here is my html :
<div id="pattern"></div>
<div id="projets"></div>
my css :
#pattern {
height:300px;
width: 100%;
background-color:red
}
#projets {
height:800px;
width: 100%;
background-color:blue
}
and my jquery :
var flag=0 ;
$(window).on('scroll',function(){
var top_projets_position = $("#projets").offset().top - $(window).scrollTop();
if((flag==0) && $(window).scrollTop()>1){
$(window).scrollTo('#projets', 500);
flag=1;
}
if($(window).scrollTop()==0){
flag=0;
}
});
here is jsfiddle :
http://jsfiddle.net/jdf9q0sv/
hope someone can help me with this, I can't figure out what I'm doing wrong, maybe a wrong method ! thanks
It looks like you need to track 3 things:
The scroll direction occurs.
The area you are currently viewing.
If scroll animation is currently happening (we need to wait until it's done, or problems will occur).
http://jsfiddle.net/vx69t5Lt/
var prev_scroll = 0; // <-- to determine direction of scrolling
var current_view ="#pattern"; // <-- to determine what element we are viewing
var allowed = true; // <-- to prevent scrolling confusion during animation
var top_projets_position = $("#projets").offset().top + 1;
$(window).on('scroll',function(){
var current_scroll = $(window).scrollTop();
if(current_scroll < top_projets_position && current_view=="#projets" && current_scroll < prev_scroll){
scrollToTarget("#pattern");
}
if($(window).height() + current_scroll > top_projets_position && current_view=="#pattern" && current_scroll > prev_scroll){
scrollToTarget("#projets");
}
prev_scroll = current_scroll;
});
function scrollToTarget(selector){
if(allowed){
allowed = false;
$(window).scrollTo(selector, {
'duration':500,
'onAfter': function(){ allowed = true; current_view = selector;}
});
}
}
This is just a quick solution based on your original code. A better solution would be to do something more Object Oriented (OOP) and track values in an object. Perhaps take an array of elements on object creation, grab all the boundaries and use the boundaries in your scroll handler to determine when to scroll to the next div.

Javascript generated margin-top messes up placement content

Case:
I have a slider that scrolls through some images, while, when you scroll down, the menu and content moves over it. Once the menu gets to the top, it sticks to it, as it's changed to a fixed position.
Problem:
Once the menu snaps to place, it resets it's original position (a margin-top) from a generated ammount of pixels to the 0 value. This cases the page to jump that generated ammount of pixels down, which shouldn't happen. It shouldn't jump down at all, but I think it has to do with the ammount of pixels that is generated before it is set to 0, which cases on my screen a gap of 955 pixels. It jumps thus 955 pixels down after it applies the fixed state.
So my questio now is, how can i fix this. I tried applying instead of a margin a padding (no go, white screen), applying instead of a margin-top: 0px a top:0 so i dont have to use the margins, but also a no go.
Case link:
http://test.thewebfanatics.com/jellyweb/home
Code
$(window).scroll(function () {
if ($('.resolutionwrap').length == 1) {
var documentScrollTop = $(document).scrollTop() + 100;
var fixedToggle = $('#slides').height();
if (documentScrollTop > fixedToggle) {
$('#hoofdmenu').addClass('fixed');
$('#hoofdmenu').css("margin-top", "0px");
} else {
$('#hoofdmenu').removeClass('fixed');
$('#hoofdmenu').css("margin-top", $('#slides').height() - 100);
}
}
});
Hope someone can help me on this matter.
Okay, as I was posting the remark on the fiddle, I realized that if the content moved, I could also just simply return it to it's position by javascript by making a counter balanced value of it.
Shortly said: I countered the margin, by creating a different margin-top that balanced that scale. It's maybe not the most beautifull solution, but it did the trick.
$(window).scroll(function () {
if ($('.resolutionwrap').length == 1) {
var documentScrollTop = $(document).scrollTop() + 100;
var fixedToggle = $('#slides').height();
// console.log($('#slides').height());
// console.log($('.resolutionwrap').height());
if (documentScrollTop > fixedToggle) {
$('#hoofdmenu').addClass('fixed');
$('#hoofdmenu').css("margin-top", "0px");
$('.content').css("margin-top", $('#slides').height());
} else {
$('#hoofdmenu').removeClass('fixed');
$('#hoofdmenu').css("margin-top", $('#slides').height() - 100);
$('.content').css("margin-top", "0px");
}
}
})

Jquery when the user hits bottom of the page

I've been working on a scroll to top function for my website, and that part of it works fine. My problem is however that I have a fixed div that is overlapping my footer when it hits the bottom of the page.
Here is the function that I have working.
$(document).scroll(function (e) {
if (document.body.scrollTop >= 800) {
$('#beamUp').show(1000);
} else {
$('#beamUp').hide(1000);
return false;
}
});
Is there somehow I could detect when I hit that part of the page and stop the div from moving past that.Help is much appreciated!
jsFiddle: http://jsfiddle.net/zazvorniki/RTDpw/
Just get the height of the page, minus the height of the div in question, as well as the footer... make sure the top is never greater than that value... you'll also need an onresize event handler re-evaluate that value.
looking at your jsfiddle... here are my edits
In your scroll listener, I am checking for the position of the page, and adjusting the bottom position of the floater appropriately. I also set the initial display:none, so you don't need to call .hide() in your initial script. In addition, resizing the window has the effect of scrolling for your use, so I changed the listener for both events.
$(document).on('scroll resize', function (e) {
var viewHeight = $(window).height();
var viewTop = $(window).scrollTop();
var footerTop = $("footer").offset().top;
var baseline = (viewHeight + viewTop) - footerTop;
var bu = $("#beamUp").css({bottom: (baseline < 0 ? 0 : baseline) + 'px'});
if (viewTop >= 50) {
bu.show(1000);
} else {
bu.hide(1000);
}
});

Getting Coordinates of an element on page scroll

I am having this problem where i have a set of 6 UL's having a common class x.Each of them consist of a specific section of the page.Now i have 6 menus that are related to each of the section.What i have to do is highlight the menu when its related section is in users view.
For this i thought that may be jQuery position(); or offset(); could have helped but they give the top and left of the element.I also tried using jQuery viewport plugin but apparently view port is big it can show more than one UL at a time hence i cant apply element specific logic here.I am not familliar to this but does anything changes of an element on scrolling?If yes then how to access it?
Please share your views.
Regards
Himanshu Sharma.
Is very easy to do it using jQuery and a dummy fixed HTML block that helps you find the current position of the viewport.
$(window).on("scroll load",function(){
var once = true;
$(".title").each(function(ele, index){
if($(this).offset().top > $("#viewport_helper").offset().top && once){
var index = $(this).index(".title");
$(".current").removeClass('current')
$("#menu li").eq(index).addClass('current')
once = false;
}
});
})
Check out a working example: http://jsfiddle.net/6c8Az/1/
You could also do something similar with the jQuery plugin, together with the :first selector:
$(window).on("scroll load",function(){
$(".title:in-viewport:first").each(function(){
var index = $(this).index(".title");
$(".current").removeClass('current')
$("#menu li").eq(index).addClass('current')
});
})
You can get the viewport's width and height via $(document).width() and $(document).height()
You can get how many pixels user scrolls via $(document).scrollTop() and $(document).scrollLeft
Combining 1 and 2, you can calculate where the viewport rectangle is
You can get the rectangle of an element using $(element).offset(), $(element).width() and $(element).height()
So the only thing left to you is to determine whether the viewport's rectangle contains (or interacts) the elements's rectangle
So the whole code may look like:
/**
* Check wether outer contains inner
* You can change this logic to matches what you need
*/
function rectContains(outer, inner) {
return outer.top <= inner.top &&
outer.bottom >= inner.bottom &&
outer.left <= inner.left &&
outer.right >= inner.right;
}
/**
* Use this function to find the menu related to <ul> element
*/
function findRelatedMenu(element) {
return $('#menu-' + element.attr('id'));
}
function whenScroll() {
var doc = $(document);
var elem = $(element);
var viewportRect = {
top: doc.scrollTop(),
left: doc.scrollLeft(),
width: doc.width(),
height: doc.height()
};
viewportRect.bottom = viewportRect.top + viewportRect.height;
viewportRect.right = viewportRect.left + viewportRect.width;
var elements = $('ul.your-class');
for (var i = 0; i < elements.length; i++) {
var elem = $(elements[i]);
var elementRect = {
top: elem.offset().top,
left: elem.offset().left,
width: elem.width(),
height: elem.height()
};
elementRect.bottom = elementRect.top + elementRect.height;
elementRect.right = elementRect.left + elementRect.width;
if (rectContains(viewportRect, elementRect)) {
findRelatedMenu(elem).addClass('highlight');
}
}
}
$(window).on('scroll', whenScroll);
Let's see if i understood well. You have a page long enough to scroll, and there is an element that when it appears in the viewport, you wanna do something with it. So the only event that's is triggered for sure on the time the element gets in the viewport is the 'scroll'. So if the element is on the page and the scroll is on the viewport, what you need to do is bind an action to the scroll event to check if the element is in the view each time the event is trigger. Pretty much like this:
$(window).scroll(function() {
check_element_position();
});
Now, in order for you to know if the element is in the viewport, you need 3 things. The offset top of that element, the size of the viewport and the scroll top of the window. Should pretty much look like this:
function check_element_position() {
var win = $(window);
var window_height = win.height();
var element = $(your_element);
var elem_offset_top = element.offset().top;
var elem_height = element.height();
var win_scroll = win.scrollTop();
var pseudo_offset = (elem_offset_top - win_scroll);
if (pseudo_offset < window_height && pseudo_offset >= 0) {
// element in view
}
else {
// elem not in view
}
}
Here, (elem_offset_top - win_scroll) represent the element position if there was no scroll. Like this, you just have to check if the element offset top is higher then the window viewport to see if it's in view or not.
Finally, you could be more precise on you calculations by adding the element height (variable already in there) because the code i just did will fire the event even if the element is visible by only 1 pixels.
Note: I just did that in five minutes so you might have to fix some of this, but this gives you a pretty darn good idea of what's going on ;)
Feel free to comment and ask questions

Categories

Resources