Scroll to element in flexbox container - javascript

I am trying to autoscroll to an element in a flexbox container.
<div class="nav">
<div class="items">
<div ng-repeat="i in items" scroll-on-click>
{{i}} click me to scroll to me!
</div>
</div>
</div>
app.directive('scrollOnClick', function() {
return {
restrict: 'A',
link: function(scope, $element) {
$element.on('click', function() {
$(".items").animate({scrollTop: $element.offset().top}, "slow");
});
}
}
});
It scrolls to the top of the first item clicked, but after that it has a hard time scrolling. I have had something very similar in a non-flexbox container working.
Here is a plunk:
http://plnkr.co/edit/kq40NiTqBI81KlRJBLHu?p=preview
Any ideas?

Use the offsetTop property to capture the scroll value of embedded (non-root) DOM elements, like a flexbox. Good discussion here. I'm subtracting 10 to stop the divs from being cut off, do as you wish.
$(".items").animate({scrollTop: $element.prop('offsetTop') - 10}, "slow");
Working Plunker
EDIT:
To handle a header or other element, flexbox or not, just subtract its height from scrollTo (assigning an id to the header):
$(".items")
.animate(
{
scrollTop: $('#' + id).prop('offsetTop') -
document.getElementById('header').offsetHeight -
10 // Store this as a .constant if it won't change
}, "slow");
Working Plunker

Related

Angular Infinite Scroll: scroll bar on body not on div

I implementing infinite scroll in my web app using angularjs. I found this useful directive on net Infinite Scroll, but the problem is this can only be implemented inside div not in the scroll bar body:
app.directive('infinityscroll', function () {
return {
restrict: 'A',
link: function (scope, element, attrs) {
element.bind('scroll', function () {
if ((element[0].scrollTop + element[0].offsetHeight) == element[0].scrollHeight) {
//scroll reach to end
scope.$apply(attrs.infinityscroll)
}
});
}
}
});
Here is my html codes:
<div infinityscroll="NextPage()" style="height:700px; overflow:auto;" >
<div ng-repeat="item in listItems">
<img ng-src="{{item.picture}}" alt="broken" style="">
</div>
</div>
when i remove the inline css it won't work.so how can i change the infinite scroll in the body instead of div?
Try this:
<body infinityscroll="NextPage()" style="height: 1000px; overflow:auto;">
and remove infinitescroll initialization from your div.
You might need to adjust height a bit, based on your screen-size.
Hope this solves your issue.. :)

Add class to appropriate nav tab when cooresponding div is scrolled into

I have read similar questions and researched scrollspy, but I don't believe it will do quite what I'm looking for, since as far as I can tell it can only use bootstrap style highlighting. (If it can do more please let me know!)
I have a 4-tab navbar (usually fixed top) and a single-page site. Each tab corresponds to a different section of the page, and each section has a different background color. What I'd like to do is change the tab color to be the same as the corresponding section's background color whenever that region is scrolled to (so it will only change color once the new section's top reaches the navbar's bottom.) I have achieved this effect only when the tab is clicked, triggering a scroll event and adding an active class, however the active tab will then remain if clicking is not used, creating the problem.
Is there a way to change a variable based off the current scroll location? I have tried what I can think of but it hasn't worked yet.
JS
$(window).on('scroll', function () {
if ($(window).scrollTop() >= $('#homeContainer').height()) {
$('.menuDiv').addClass('fixed');
} else {
$('.menuDiv').removeClass('fixed');
}
});
$("#menuHomeButton").click(function(e){
$('html, body').animate({
scrollTop: $('#homeContainer').offset().top
}, 'slow');
});
$("#menuAboutButton").click(function(e){
$('html, body').animate({
scrollTop: $('#aboutContainer').offset().top + 1
}, 'slow');
});
$("#menuPortfolioButton").click(function(e){
$('html, body').animate({
scrollTop: $('#portfolioContainer').offset().top - $('.menuDiv').height() + 1
}, 'slow');
});
$("#menuContactButton").click(function(e){
$('html, body').animate({
scrollTop: $('#contactContainer').offset().top - $('.menuDiv').height() + 1
}, 'slow');
});
HTML
<div class="mainContainer">
<div class="container blue" id="homeContainer">
</div>
<div class="menuDiv"><!--
--><div class="menuItem" id="menuHomeButton" ng-class="{'active':selectedTab === 'home'}" ng-click="selectedTab = 'home'">
<div class="menuTextDiv"><p>Home</p></div><div class="menuItemColor blue"></div>
</div><!--
--><div class="menuItem" id="menuAboutButton" ng-class="{'active2':selectedTab === 'about'}" ng-click="selectedTab = 'about'">
<div class="menuTextDiv"><p>About</p></div><div class="menuItemColor blue2"></div>
</div><!--
--><div class="menuItem" id="menuPortfolioButton" ng-class="{'active3':selectedTab === 'portfolio'}" ng-click="selectedTab = 'portfolio'">
<div class="menuTextDiv"><p>Portfolio</p></div><div class="menuItemColor blue3"></div>
</div><!--
--><div class="menuItem" id="menuContactButton" ng-class="{'active4':selectedTab === 'contact'}" ng-click="selectedTab = 'contact'">
<div class="menuTextDiv"><p>Contact</p></div><div class="menuItemColor blue4"></div>
</div><!--
--></div>
<div class="container blue2" id="aboutContainer">
</div>
<div class="container blue3" id="portfolioContainer">
</div>
<div class="container blue4" id="contactContainer">
</div>
<div class="container">
</div>
</div>
Here is a fiddle, but for some reason I couldn't get the ng-click and ng-class to work on it, which changes the tab color.
Here are some images of what it looks like not on js fiddle:
What I want and have:
http://i.gyazo.com/3c7d6d80a9a490b31e795cacebbaa1a0.png
http://i.gyazo.com/1bd597080bdba6ffa34fe18cf5462b74.png
What I don't want but still also have:http://i.gyazo.com/d066effabd276d978e4775666a3b5d6c.png
If anyone has a solution I'd be extremely greatful! Thank you!
Get the distance of the div from top:
distance = $("div").scrollTop()
note: do not use var when declaring distance because than you can't access it inside a function
Then check if div has reached the top and add class:
$(window).on('scroll', function () {
if(distance - $("div").scrollTop() >= distance ){
//do something
}
});

ScrollTo() in jquery

I have a code in which when a button is clicked the corresponding div is scrolling up along with the button. I want a code in which when a button is clicked the button must be in its respective position i.e, the buttons must be fixed, but the corresponding div must scroll up. The same should be applied to all the buttons and their respective divs
Here is my code in which I used scrollTo()
<div class="submit-buttons">
<input id="example1" type="submit" name="script" value="Sample1"/>
<input id="example2" type="submit" name="script" value="Sample2"/>
<input id="example3" type="submit" name="script" value="Sample3"/>
</div>
<div id="output1" style="margin-top:200px">This is output1</div>
<div id="output2" style="margin-top:600px">This is output2</div>
<div id="output3" style="margin-top:800px">This is output3</div>
<script>
$("#example1").click(function() {
$.scrollTo( '#output1', 800);
});
$("#example2").click(function() {
$.scrollTo( '#output2', 800);
});
$("#example3").click(function() {
$.scrollTo( '#output3', 800);
});
</script>
When I executed the above code the output1,2,3 are scrolling up but along with example1,2,3. I want a code in which the buttons must be fixed but the divs must move to the position below the buttons div
Make position:fixed for submit-buttons class.
add css and make changes according to your need.
.submit-buttons{
position:fixed;
top:10px;
width:100%;
}
I hope it helps you. http://jsfiddle.net/56P4T/
EDIT:
You can use this script(Ref: ek_'s answer).I hope it helps you.
$(document).ready(function (){
$("#example1").click(function() {
var val = $("#output1").offset().top - ($(".submit-buttons").height()+10);
$("html, body").animate({scrollTop: val}, 800);
});
$("#example2").click(function() {
var val = $("#output2").offset().top - ($(".submit-buttons").height()+10);
$("html, body").animate({scrollTop: val}, 800);
});
$("#example3").click(function() {
var val = $("#output3").offset().top - ($(".submit-buttons").height()+10);
$("html, body").animate({scrollTop: val}, 800);
});
});
Sumit Raghav gave you the right answer about fixed-positioning your buttons.
If you want your outputs to move just below the .submit-buttons div (in fact, it is your entire body which is moving) you may consider animating the scrollTop property, which is, I guess, what your scrollTo plug-in is doing:
$("#example1").click(function() {
// your get the position of #output1 with respect to the top of the document
// and you remove the height of the .submit-buttons div to scroll just below
var val = $("#output1").offset().top - $(".submit-buttons").height();
// animate the scrollTop property
$("html, body").animate({scrollTop: val}, 800);
});

jquery prevent redirect until after animation

This code works perfectly except when you click on a link, The page is redirected before jquery has a change to visually animate the margin back to zero. Is there a way to prevent the redirect until after jquery animates the margin back to zero?
HTML
<div id="sidebar">
<div class="navigation">
<ul>
<li><img src="dbs/images/home.png" title="" width="40" height="38" />به عقب</li>
<li>فیلم ها</li>
<li>وزارتخانه ها ایران زنده</li>
<li>پرستش</li>
<li>جوانان</li>
<li>کودکان</li>
<li>پزوهش ها</li>
<li>دانشکده مسیح</li>
<li>زنان</li>
<li>کلیپ های سری</li>
</ul>
</div>
</div>
JS
$('.navigation a li').click(function () {
$('.slider').animate({
marginLeft: 0
}, 500);
});
.animate() takes a callback function like so:
$('.navigation a li').click(function () {
$('.slider').animate({
marginLeft: 0
}, 500,function() {
//thing to do when you animation is finished e.g.
location.href = 'http://redirect.to.url';
});
});
For complete documentation, check out the (extremely useful) jQuery docs:
http://api.jquery.com/animate/
Firstly, your HTML is invalid. Put the links inside the list items, not the other way around. Adjust your selector accordingly (.navigation li a).
Next, now that you're setting the event on the link rather than the list item, make your handler:
Prevent the default event
Add a callback to the animation, so that when the animation is over the page goes to this.getAttribute('href').
That should do it.
Stop the event propagation from li click handler.
$('.navigation a li').click(function (e) {
$('.slider').animate({
marginLeft: 0
}, 500);
e.stopPropagation();
});

How to scroll to specific item using jQuery?

I have a big table with vertical scroll bar.
I would like to scroll to a specific line in this table using jQuery/JavaScript.
Are there built-in methods to do this?
Here is a little example to play with.
div {
width: 100px;
height: 70px;
border: 1px solid blue;
overflow: auto;
}
<div>
<table id="my_table">
<tr id='row_1'><td>1</td></tr>
<tr id='row_2'><td>2</td></tr>
<tr id='row_3'><td>3</td></tr>
<tr id='row_4'><td>4</td></tr>
<tr id='row_5'><td>5</td></tr>
<tr id='row_6'><td>6</td></tr>
<tr id='row_7'><td>7</td></tr>
<tr id='row_8'><td>8</td></tr>
<tr id='row_9'><td>9</td></tr>
</table>
</div>
Dead simple. No plugins needed.
var $container = $('div'),
$scrollTo = $('#row_8');
$container.scrollTop(
$scrollTo.offset().top - $container.offset().top + $container.scrollTop()
);
// Or you can animate the scrolling:
$container.animate({
scrollTop: $scrollTo.offset().top - $container.offset().top + $container.scrollTop()
});​
Here is a working example.
Documentation for scrollTop.
I realise this doesn't answer scrolling in a container but people are finding it useful so:
$('html,body').animate({scrollTop: some_element.offset().top});
We select both html and body because the document scroller could be on either and it is hard to determine which. For modern browsers you can get away with $(document.body).
Or, to go to the top of the page:
$('html,body').animate({scrollTop: 0});
Or without animation:
$(window).scrollTop(some_element.offset().top);
OR...
window.scrollTo(0, some_element.offset().top); // native equivalent (x, y)
I agree with Kevin and others, using a plugin for this is pointless.
window.scrollTo(0, $("#element").offset().top);
I managed to do it myself. No need for any plugins. Check out my gist:
// Replace #fromA with your button/control and #toB with the target to which
// You wanna scroll to.
//
$("#fromA").click(function() {
$("html, body").animate({ scrollTop: $("#toB").offset().top }, 1500);
});
You can use scrollIntoView() method in javascript.
just give id.scrollIntoView();
For example
row_5.scrollIntoView();
You can use the the jQuery scrollTo plugin plugin:
$('div').scrollTo('#row_8');
Scroll element to center of container
To bring the element to the center of the container.
DEMO on CODEPEN
JS
function scrollToCenter() {
var container = $('.container'),
scrollTo = $('.5');
container.animate({
//scrolls to center
scrollTop: scrollTo.offset().top - container.offset().top + scrollTo.scrollTop() - container.height() / 2
});
}
HTML
<div class="container">
<div class="1">
1
</div>
<div class="2">
2
</div>
<div class="3">
3
</div>
<div class="4">
4
</div>
<div class="5">
5
</div>
<div class="6">
6
</div>
<div class="7">
7
</div>
<div class="8">
8
</div>
<div class="9">
9
</div>
<div class="10">
10
</div>
</div>
<br>
<br>
<button id="scroll" onclick="scrollToCenter()">
Scroll
</button>
css
.container {
height: 60px;
overflow-y: scroll;
width 60px;
background-color: white;
}
It is not exact to the center but you will not recognice it on larger bigger elements.
You can scroll by jQuery and JavaScript
Just need two element jQuery and this JavaScript code :
$(function() {
// Generic selector to be used anywhere
$(".js-scroll-to-id").click(function(e) {
// Get the href dynamically
var destination = $(this).attr('href');
// Prevent href=“#” link from changing the URL hash (optional)
e.preventDefault();
// Animate scroll to destination
$('html, body').animate({
scrollTop: $(destination).offset().top
}, 1500);
});
});
$(function() {
// Generic selector to be used anywhere
$(".js-scroll-to-id").click(function(e) {
// Get the href dynamically
var destination = $(this).attr('href');
// Prevent href=“#” link from changing the URL hash (optional)
e.preventDefault();
// Animate scroll to destination
$('html, body').animate({
scrollTop: $(destination).offset().top
}, 1500);
});
});
#pane1 {
background: #000;
width: 400px;
height: 400px;
}
#pane2 {
background: #ff0000;
width: 400px;
height: 400px;
}
#pane3 {
background: #ccc;
width: 400px;
height: 400px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="nav">
<li>
Item 1
</li>
<li>
Item 2
</li>
<li>
Item 3
</li>
</ul>
<div id="pane1"></div>
<div id="pane2"></div>
<div id="pane3"></div>
<!-- example of a fixed nav menu -->
<ul class="nav">
<li>
Item 1
</li>
<li>
Item 2
</li>
<li>
Item 3
</li>
</ul>
Not sure why no one says the obvious, as there's a built in javascript scrollTo function:
scrollTo( $('#element').position().top );
Reference.
I did a combination of what others have posted. Its simple and smooth
$('#myButton').click(function(){
$('html, body').animate({
scrollTop: $('#scroll-to-this-element').position().top },
1000
);
});
Contrary to what most people here are suggesting, I'd recommend you do use a plugin if you want to animate the move. Just animating scrollTop is not enough for a smooth user experience. See my answer here for the reasoning.
I have tried a number of plugins over the years, but eventually written one myself. You might want to give it a spin: jQuery.scrollable. Using that, the scroll action becomes
$container.scrollTo( targetPosition );
But that's not all. We need to fix the target position, too. The calculation you see in other answers,
$target.offset().top - $container.offset().top + $container.scrollTop()
mostly works but is not entirely correct. It doesn't handle the border of the scroll container properly. The target element is scrolled upwards too far, by the size of the border. Here is a demo.
Hence, a better way to calculate the target position is
var target = $target[0],
container = $container[0];
targetPosition = $container.scrollTop() + target.getBoundingClientRect().top - container.getBoundingClientRect().top - container.clientTop;
Again, have a look at the demo to see it in action.
For a function which returns the target position and works for both window and non-window scroll containers, feel free to use this gist. The comments in there explain how the position is calculated.
In the beginning, I have said it would be best to use a plugin for animated scrolling. You don't need a plugin, however, if you want to jump to the target without a transition. See the answer by #James for that, but make sure you calculate the target position correctly if there is a border around the container.
For what it's worth, this is how I managed to achieve such behavior for a general element which can be inside a DIV with scrolling (without knowing the container)
It creates a fake input of the height of the target element, and then puts a focus to it, and the browser will take care about the rest no matter how deep within the scrollable hierarchy you are. Works like a charm.
var $scrollTo = $('#someId'),
inputElem = $('<input type="text"></input>');
$scrollTo.prepend(inputElem);
inputElem.css({
position: 'absolute',
width: '1px',
height: $scrollTo.height()
});
inputElem.focus();
inputElem.remove();
I did this combination. its work for me. but facing one issue if click
move that div size is too large that scenerio scroll not down to this
particular div.
var scrollDownTo =$("#show_question_" + nQueId).position().top;
console.log(scrollDownTo);
$('#slider_light_box_container').animate({
scrollTop: scrollDownTo
}, 1000, function(){
});
}

Categories

Resources