jQuery sliding table header - javascript

My ASP.Net application generates an <asp:Table> from the codebehind. What I need is for the header row of that table to slide down the page as the user scrolls past it.
I've tried the following approach using JavaScript:
window.onscroll = function () {
//grab the current scroll position
var scrollY = document.body.scrollTop;
if (scrollY == 0) {
if (window.pageYOffset)
scrollY = window.pageYOffset;
else
scrollY = (document.body.parentElement) ? document.body.parentElement.scrollTop : 0;
}
//grab the position of the header row I want to slide
var head = $("tr[name='headerrow']").offset();
var headtop = head.top;
var headleft = head.left;
//if the user has scrolled past the top of the header row
if (scrollY > headtop) {
//code correctly reaches this point as alerts show
//alert('got here');
//position the header row to the same as the scroll position
$("tr[name='headerrow']").offset({ top: scrollY, left: headleft });
}
}
I can't get the row to move. There are no error message to be seen on the various browsers developer tools.
Any help would be appreciated.
EDIT: I tried calling the offset() function on the children of the row (i.e. all of the <th> elements) like this:
$("tr[name='headerrow']").children().offset({ top: scrollY, left: headleft });
This now works but of course, they're all pushed over to the left because I'm using the left value of the header row itself... I'll keep this updated with my progress but in the meantime any assistance is appreciated as always.

Solution:
Use the children() method on the table row to allow you to change the offset of each of the <th> elements. The left value can be omitted from the offset() method, i.e.
$("tr[name='headerrow']").children().offset({ top: scrollY });

You cannot set the offset to any element. You should use css method and set the top and left parameters.

Related

Get scroll value on element with position:fixed

I have a page with a header section. In it, two blocks that move sideways after scrolling or dragging on the mobile.
I am trying to set the scrolling for the header, but I want too that the rest of the page stays in place until the side blocks reach left: -50% and right:-50%.
I have an event scroll set to header, with pageYoffset values.
I tried to set the rest of the content the page gives to the section with the position:fixed, but then the scroll does not work anymore, and do not count pageYoffset.
Do you have any ideas how to get around it, so that the rest of the page would scroll only after the full unveiling of the header?
(in short, the pink section should be on top and wait until the header disappears)
let current = $(window).scrollTop();
let windowHeight = $(window).height();
let eleLeft = $(".cd-half-left");
let eleRight = $(".cd-half-right");
let currPositionLeft = eleLeft.position().left;
let currPositionRight = eleRight.position().right;
let headerHeaight = $(".cd-section").height();
let halfBlockWidth = $(".cd-half-block").width();
let windowWidth = $(window).width();
$(window).scroll(function (event) {
current = $(window).scrollTop();
console.log({total:total,current:current});
var newPosition = ((current / headerHeaight)*100) / 2;
console.log(newPosition);
eleLeft.css({left:"-"+newPosition+'%'});
eleRight.css({right:"-"+newPosition+'%'});
});
FIDDLE
A solution would be not to use window scroll but instead handle scroll gesture (from mousewheel and touchmove) to control left and right panel, and prevent actual scroll when the panels are not fully opened.
so instead of $(window].scroll(handler), try with $('.cd-block').bind('mousewheel', handler) and $('.cd-block').bind('mousewheel', handler)
The handler being:
function updateCurrent(event) {
if (current >= 50) {
current = 50;
} else {
if (current <= 0) {
current = 0;
}
// if below 50 we cancel the event to prevent the scroll
event.originalEvent.preventDefault();
}
eleLeft.css({left:"-"+current+'%'});
eleRight.css({right:"-"+current+'%'});
}
Here is a buggy but working solution (keyboard space, up and down should be handled too):
fiddle

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.

Making nav bar effects using scroll AND click in jQuery

I want a nav to highlight (or something similar) once a user clicks on it AND when a user scrolls to the corresponding section.
However, on my computer when one clicks on any of the nav events after3, only nav event 3 changes. I'm guessing this is because after one clicks on 4 or 5, the scroll bar is already at the bottom of the page, so 4 and 5 never reach the top. The only div at the top is post 3, so my code highlights nav event 3 and ignores the click.
Is there any way I can fix this? Ive tried if statements (only highlight nav event if it's at the top AND the scrollbar isn't at the bottom or the top isn't the last item).
Here is a more accurate fiddle, using a fix below showing what I am talking about. The fix now highlights on scroll, but if you click option 5, it will not highlight.
$('.option').children('a').click(function() {
$('.option').css('background-color', '#CCCCCC;');
$(this).css('background-color', 'red');
var postId = $($(this).attr('href'));
var postLocation = postId.offset().top;
$(window).scrollTop(postLocation);
});
$(window).scroll(function() {
var scrollBar = $(this).scrollTop();
var allPosts = [];
var post = $('.content').offset();
var lastPost = allPosts.legnth-1
var windowHeight = $(window).height();
var bottomScroll = windowHeight-scrollBar;
$(".content").each(function(){
allPosts.push($(this).attr('id'));
});
i = 0;
for(i in allPosts){
var currentPost = "#"+allPosts[i];
var postPosition = $(currentPost).offset().top;
if (scrollBar >= postPosition){
$('.option').css('background-color', '#CCCCCC');
$('#nav'+allPosts[i]).css('background-color', 'red');
};
};
});
I think you've overdone your scroll() handler, to keep it simple you just needs to check if the scrollbar/scrollTop reaches the '.contents' offset top value but should not be greater than its offset().top plus its height().
$(window).scroll(function () {
var scrollBar = $(this).scrollTop();
$(".content").each(function (index) {
var elTop = $(this).offset().top;
var elHeight = $(this).height();
if (scrollBar >= elTop - 5 && scrollBar < elTop + elHeight) {
/* $(this) '.content' is the active on the vewport,
get its index to target the corresponding navigation '.option',
like this - $('.Nav li').eq(index)
*/
}
});
});
And you actually don't need to set $(window).scrollTop(postLocation); because of the default <a> tag anchoring on click, you can omit that one and it will work fine. However if you are looking to animate you need first to prevent this default behavior:
$('.option').children('a').click(function (e) {
e.preventDefault();
var postId = $($(this).attr('href'));
var postLocation = postId.offset().top;
$('html, body').animate({scrollTop:postLocation},'slow');
});
See the demo.
What you are trying to implement from scratch, although commendable, has already been done by the nice folks at Bootstrap. It is called a Scrollspy and all you need to do to implement it is include Bootstrap js and css (you also need jquery but you already have that) and make some minor changes to your html.
Scrollspy implementation steps.
And here is a demonstration. Notice only one line of js. :D
$('body').scrollspy({ target: '.navbar-example' });

Active state not being set by smooth-scroll plugin (JS modification)

I'm having some trouble with a script which takes care of smooth scrolling as well as the active state on my main navigation. Plugin: http://tinyurl.com/amz4kob
Please note that the navigation bar is fixed so effectively has no height.
I've got two issues which I can't seem to overcome:
On page load the active state is applied to the contact link. If you scroll down 1px the active state is correctly applied to the home link.
I can't for the life of me figure out how to modify the script to pay attention to anchors within an element with a certain ID? i.e. I only want this script to apply the active state to the elements within the tag.
Any help would be greatly appreciated.
#rrfive
To make life easy here is the commented script:
$(document).ready(function() {
//Get Sections top position
function getTargetTop(elem){
//gets the id of the section header
//from the navigation's href e.g. ("#html")
var id = elem.attr("href");
//Height of the navigation
var offset = 0;
//Gets the distance from the top and subtracts the height of the nav.
return $(id).offset().top - offset;
}
//Smooth scroll when user click link that starts with #
$('a[href^="#"]').click(function(event) {
//gets the distance from the top of the section refenced in the href.
var target = getTargetTop($(this));
//scrolls to that section.
$('html, body').animate({scrollTop:target}, 500);
//prevent the browser from jumping down to section.
event.preventDefault();
});
//Pulling sections from main nav.
var sections = $('a[href^="#"]');
// Go through each section to see if it's at the top.
// if it is add an active class
function checkSectionSelected(scrolledTo){
//How close the top has to be to the section.
var threshold = 54;
var i;
for (i = 0; i < sections.length; i++) {
//get next nav item
var section = $(sections[i]);
//get the distance from top
var target = getTargetTop(section);
//Check if section is at the top of the page.
if (scrolledTo > target - threshold && scrolledTo < target + threshold) {
sections.removeClass("active");
section.addClass("active");
}
};
}
//Check if page is already scrolled to a section.
checkSectionSelected($(window).scrollTop());
$(window).scroll(function(e){
checkSectionSelected($(window).scrollTop())
});
});
The plugin you're using checks the position of the <div class="section"></div> elements on the page, but because you've made them display:none;, all the sections are returning "0 pixels" from the top of the page, and since the "CONTACT" section is the last on the page, it's stopping there.
So, simply remove display:none; from .section in your CSS and it'll work fine.
.section {
/*display: none; <-- Comment this line out. */
height: 100%;
min-width: 990px;
}

Categories

Resources