Can I force scrolling to end at certain points? - javascript

I have this plunker in which I try to demo what I am doing with my project (warning requires flex-box). I have it so the bootstrap nav pill changes when I reach the header. The problem is scrolling appears to be chaotic (depending on screen size but also just randomly goes to different places with each scroll). So sometimes the section header is 10px from the top, others it is 50px. Is there a way I can manipulate the scroll using either CSS or JS?
See Issue
It will depend on browser, screen size and a variety of factors, however, if you scroll up and down some sections should get missed. This will only happen occasionally, but it does happen regularly.
Code
My Angular code for finding the offset...
function elementInViewport(el) {
var top = el.getBoundingClientRect().top - 90;
return (
top >= 0 && top <= 20
);
}

Consider setting the overflow css of your body element to hidden and the height to whatever you want the user to be able to scroll. I don't know why you'd want to do this, though.

Related

Hold element in place at specific offset to top then release after 1000px scroll

I'm trying to do something that I think has to do with parallax or sticky libraries but having a bunch of trouble.
I'd like to let the user scroll normally, and then when a particular div is a particular value (lets say 232px) from the top of the screen, I want to hold the element in place (ie give it position:fixed). This part is easy to get the offset:
$('element')product1[0].getBoundingClientRect().top;
Then, let the user continue to scroll with the element in place so they can see the background continue to move with the scroll (I have a large height background with a nice linear-gradient).
Then after the user scrolled for about 1000px I want to release the element and let it continue to move up with the scroll. The same should happen when the user scrolls back up - it holds for a bit then releases.
I've tried a bunch of different things and combinations of libraries, pure css, JS, etc. Nothing works well. Everything has an issue. Would love to see a clean solution.
Things I've tried:
-JQuery sticky libraries (could not find one that does or is customizable to what I need)
-Vanilla JS tracking position (had jumping issues on release - element would fly far away on release, not continue from release position)
-CSS, specifically translateZ
The ideal setup is:
<div style="height: 230vh; background: linear-gradient(coolOne)">
<div class="containerToStickTemporarily">
<p class="textOnLeft">Hi</p>
<img src="myImage.png"/>
</div>
</div>
And I'd like to have multiple of these in a row.
Something like that.. I guess
$(window).scroll(function(){
var top = $(window).scrollTop();
$('element').css({ position: top > 230 && top < 1000 ? 'fixed' : 'relative' });
})

Vertically Scrolling in Window 8 store app

I am developing a windows 8 store app using HTML5 and Javascript. And I want to scroll some div content vertically. I am using following inline css to do so
<div style="height:100%;overflow-y:scroll;">
//Content
</div>
But Its only showing scrolling bar and i am not able to scroll the content.
This is how i am getting my scrolling bar, as you can see last input box is showing half and i cant scroll it.
I think i found a quick solution for this problem. Instead of giving height as 100%. Just give height in pixels that will cover your current window till bottom.
For example:
If your screen height is 780px, and you have 80px height covered by header. So if you want to use scrolling in remaining 700px. Use following code :-
<div style="height:700px;overflow-y:scroll;">
//Content
</div>
Hope it ll work for you as well. But Stil looking for alternate solution , if there is any.
In general, this is not a Windows Universal App problem, but simply an HTML/javascript one. By default, browsers scroll the body content that exceeds the browser window, but in the UWP JS app, no scrolling is provided by default. So, to make the content scrollable, you do need to provide a height, but the height may be dynamic. Using javascript, you can set the height more appropriately based on the user's screen size.
Basically, in the main javascript file, you can set the height of the scrollable region.
body {
overflow-y: scroll;
}
function setElementToRemainingWindowHeight(selector, usedHeight) {
$(selector).height($(window).innerHeight() - usedHeight);
}
function calculateUsedHeight() {
return $('.header').innerHeight() + $('footer').innerHeight();
}
$(function(){
setElementToRemainingWindowHeight('#scrollingRegion', calculateUsedHeight());
window.resize(function() {
setElementToRemainingWindowHeight('#scrollingRegion', calculateUsedHeight());
});
});
You can move the code to respond to whatever event in your app that would cause the scrollable area to change (maybe things are entering and exiting the surrounding layout, or whatever).
Depending on when the items in the list are added, and how that adding occurs, your requirements may change. See this post (which I wrote) about how to do this more dynamically...

Content's padding-top based on fixed header's height

I'm making a layout using fixed header, with a main nav and another nav called #sub_nav. The thing is the #sub_nav got many items to choose, so when I reduce the width of the browser, the last item breaks the line, and a portion of the content hides behind the flexible header.
Here's an illustration:
And here the jsfiddle
I wonder if there's a CSS / JS solution for that. I also accept jquery solutions.
Apologise if the image is annoying but I hope you understand what do I want to solve.
[UPDATED]
Because the header is fixed, it overlaps on top of the main contents. You need to use jquery to increase the top padding of your #mid when #sub_nav height gets greater than it's actual height. Try something like this:
$(document).ready(function(){
var subNav = $("#sub_nav");
var main = $("#mid");
if(subNav.height() > 25){
main.css({"padding-top": "220px"});
}
else{
main.css({"padding-top": "190px"});
}
$(window).resize(function(){
if(subNav.height() > 25){
main.css({"padding-top": "220px"});
}
else{
main.css({"padding-top": "190px"});
}
});
});
You can't have header be fixed (or absolutely) positioned AND have the div#mid element be positioned relative to it with the wrapping content from the header pushing it down.
I would suggest reducing the words in the subnav links if possible. From a design stand-point, it looks bad and it's bad UX to be as hard to read as it is. You can also try a responsive layout where if the browser width gets too narrow, you change the design of the menu.

Attempt to keep element in center of screen but contained in parent element

We have a script used to edit certain files inline. Basically, each file is broken down into sections, and hovering over a section will bring up a set of tools (just a div with image buttons) that you can use to edit that particular section. We have the parent elements (sections) set as position: relative, and the set of tools set as position:absolute which are set to the right side of the section. This all works fine, especially since many of these are rather small.
However, we do have many of these sections which can become quite large, reaching lengths of two screens or even more. In these cases we would like for the tools to sort of flow with the user's scrolling, so say if the user is looking at the vertical-middle of the section, the buttons will rest at the vertical middle as well, however, if the vertical center of the user's screen scrolls past the section but the user is still hovering over the section, we would like for the tools to remain within their parent element and not be able to pop out.
We already have a script to move an element with the user's scroll if it goes out of the screen, so I was thinking I could modify that a bit to do that, I'm just not sure how to bound the element by it's parent.
TL;DR: How would I create an element that attempts to be vertically centered in the user's window, but cannot leave it's parent element.
Keeping it vertically aligned but only displayed when the section is hovered wouldn't do the trick?
This sounds like a manual positioning. You could use jquery to get the size of the browserwindow, get the scroll offset of the parent and calculate the top of the tools acording to screensize and scrolloffset value of the parent.
I don't thin css can handle this alone.
You could also just use one toolbox for all sections and pass the parent element as parameter.
Best wishes
Here's a quick implementation I came up with based on Andreas's suggestion
$(window).scroll(function(){
var a = $(window).scrollTop() + ($(window).height() * .35);
var b = $("#movedelement");
var c = $(window).scrollTop() + ($(window).height() * .48);
if (a < (b.parent().offset().top + 8))
b.css({position: "absolute", top: "1em" });
else if (c > (b.parent().offset().top + b.parent().height() - 8))
b.css({position: "absolute", top: b.parent().height() - 100 });
else
b.css({position: "fixed", top: "35%" });
}
Tweak some numbers around for the element height. Dirty, but works.

How to make an element slide with the viewport as it scrolls?

I've Googled for this but must be using the wrong keywords.
Basically I want to use the effect that Magento and now Stack Overflow uses. That is, there is an element in a column, and when you scroll down, it sticks to the top of the viewport. And once scrolled up again, it goes back into the normal page flow.
This Ask A Question is a good page for example. Scroll down and watch the "How to Format" element come down (might need to make your viewport smaller if you have a large screen to see the effect).
I've noticed it is setting position: fixed in the CSS. The JavaScript however is obfuscated.
What's the easiest way to achieve this effect? Is there a jQuery plugin available?
Here is an article that should help: http://www.wduffy.co.uk/blog/keep-element-in-view-while-scrolling-using-jquery/comment-page-1/
I noticed google doing this in certain places, like here http://news.google.com/nwshp?hl=en (the left side navigation bar). From what I can tell, they checking the position on the page and then setting the item to a fixed position once the page is scrolled down enough for the element to start scrolling off the screen.
It looks like the other method, using jQuery to set the top margin will allow the element to lag behind and get choppy (if you don't use animation) since the javascript must continue to position the element.
Here is an example in Ext, it would probably help a lot if I didn't have the select in the event handler, but it works.
Ext.fly(document).on("scroll", function(e,t,o){
Ext.select(".pinnable").each(function(el,c,idx){
var y = window.scrollY;
if(!el.hasClass("pinned")){
var ypos = el.getY();
if(y>ypos){
el.addClass("pinned");
el.set({
originalY:ypos
});
}
} else {
var origy = el.getAttribute("originalY");
if(origy && y<origy){
el.removeClass("pinned")
}
}
});
});

Categories