jQuery scroll to sections in button click - javascript

I'm having problem to scroll in each section separately by using the same button. If I click for the first time, this should send me to section2, and then If i click again the same button, this should send me to section3
I have tried to make it by every click to scroll 500px to bottom or something like that but seems that this is not good solution for me.
$(document).ready(function() {
$('.scroller').click(function() {
var fuller = $(this).closest('.fullscreen').next(),
section = $(this).closest('.section');
section.animate({
scrollTop: section.scrollTop() + fuller.offset().top
}, 700);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="section">
<a href=# class="scroller">Scroll</>
<div class="section1">
<div class="section1">Content2</div>
</div>
<div class="section2">
<div class="half-screen">
<div class="s">Content 2</div>
</div>
</div>
<div class="section3">
<span>
<div class="">Content 3</div>
</span>
</div>
<div class="section4">
<div class="half-screen">
<div class="s">Content 4</div>
</div>
</div>
</div>
This kind of code send me just to the section2 and then doesn't work.

You can use a counter to achieve your task. When the button is clicked, we check if counter hasn't reached the sections (those to be scrolled to) length (the number of the sections in the page), scroll to the next section and increment the counter otherwise scroll to the first section and assign 0 to the counter so we can click again and have the same functionality.
But before digging into the code (logic), I have some points to talk about :
your HTML is semantically wrong : an inline level element (a span in your case) can't host block level elements (a div in your case).
the button (the a.scroller element) is the only one component that has the scrolling functionality, select it (in jQuery) based on it's ID (we'll give it one) seems more better than a class (that's faster as jQuery will use the native getElementByID to select the element, you can read the jQuery code and get how it does the selecting job).
as I tried to say, classes are used to select more than one element in the page. The sections (to be scrolled to) should have a common class (also to be used in jQuery).
So building on those points above, I prepared a demo example for you in which you can extend to achieve your desired end results. Also, the example has a wealth of helpful comments to help you when reading the code.
$(() => {
/**
* select the main elements having affect in the process.
* sections: the sections to be scrolled to.
* btn: the "a" element that that triggers the scrolling effect.
* idx: the counter that used to distinguish which section should we scroll to.
**/
let sections = $('.scroll-to'),
btn = $("#scroller"),
idx = 1;
/** adding the click listener to the "a" element **/
btn.on('click', e => {
e.preventDefault(); /** preventing the jump to top (and adding "#" to the URL) **/
idx >= sections.length && (idx = 0); /** if the counter reaches the number of the section in the page we must decrement it to 0 **/
/** scroll effect: the "body" and the "html" elements should scroll not a section but the scroll destination is based on the section with the index "idx" offset from the top of the page (all the page not only the viewport) **/
$("html, body").animate({
scrollTop: $(sections[idx++]).offset().top
}, 700);
});
});
/** basic styling for the demo purposes and to allow the scroll effect to be seen **/
.scroll-to {
height: 100vh;
border: 2px solid blue;
}
#scroller {
position: fixed;
top: 0;
left: 50%;
transform: translate3d(-50%, 0, 0);
background-color: #000;
color: #fff;
padding: 8px 15px;
border-radius: 0 0 4px 4px;
text-align: center;
box-shadow: 0 0 25px -1px rgba(18, 18, 18, .6);
z-index: 999;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- no "span" elements having "div" ones which is semantically wrong -->
<!-- the sections to be scrolled to have a common class "scroll-to" which will be used to select all these section in "jQuery" -->
<!-- the "a" element now have an ID of "scroller" to select it rapidly with "jQuery" -->
<div class="section">
Scroll
<div class="scroll-to fullscreen">
Some content
</div>
<div class="scroll-to section2">
<div class="half-screen">
<div class="s">Content 2</div>
</div>
</div>
<div class="scroll-to section3">
Content 3
</div>
<div class="scroll-to section4">
<div class="half-screen">
<div class="s">Content 4</div>
</div>
</div>
</div>
I'm here for any clarifications.
Hope I pushed you further.

Related

Toggle or Show/Hide

I need help toggling overlays with multiple divs. I don't want to have a separate function for each one (there's 6 with 6 different overlay popups). The onclick div will reveal the overlay popup. Help is appreciated!
I need help toggling overlays with multiple divs. I don't want to have a separate function for each one (there's 6 with 6 different overlay popups). The onclick div will reveal the overlay popup. Help is appreciated!
function on() {
document.getElementById("overlay").style.display = "block";
}
function off() {
document.getElementById("overlay").style.display = "none";
}
#overlay {
position: fixed;
display: none;
width: 100%;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0,0,0,0.8);
z-index: 2;
cursor: pointer;
}
#text{
position: absolute;
top: 50%;
left: 50%;
font-size: 1rem;
color: white;
transform: translate(-50%,-50%);
-ms-transform: translate(-50%,-50%);
}
<!-- //DIV -->
<div class="row ">
<div class="col-md-6 col-lg-4 d-flex align-items-stretch" onclick="on()">
<div class="card mb-3">
<img src="img/ballet.jpg" class="embed-responsive w-100 classpic" alt="...">
<div class="card-body">
<h5 class="card-title">BALLET</h5>
</div>
</div>
</div>
<!-- //POPUP -->
<div id="overlay" onclick="off()">
<div id="text">
<h3>Ballet</h3>
<p>Ballet is an artistic dance form performed to music using precise and highly formalized set steps and gestures.
Classical ballet, which originated in Renaissance Italy and established its present form during the 19th century,
is characterized by light, graceful, fluid movements and the use of pointe shoes.
</p>
<h4>Shedule:</h4>
<p>Ages 4-8: Thursdays • 4PM<br>
Ages 9-14: Fridays • 7PM</p>
</div>
</div>
There's a problem with your approach, namely, when an element has display:none it is removed from the html tree and cannot receive a click event. Also, no two elements can share the same id attribute and so your function cannot be applied by reference to an id directly.
I've made a working snippet that achieves what I think you are after. There are undoubtedly others that would work but it's quite straight forward and works.
Firstly, arrange each of your alternative div pairs (one hidden, one visible) inside a parent div and give it a class name. This has the advantage that, if you size the container div appropriately, the content will not jump about when you swap the hidden div for visible and vice versa. Next, give classes to distinguish the (initially) hidden content from the visible div. Your markup pattern then will be repeats of:
<div class='container'>
<div class='main'>my first main content</div>
<div class='hidden'>my first hidden content </div>
</div>
In the style sheet, set the class display properties:
.hidden {
display: none;
}
.main {
display: block;
}
Then, set up a click event listener in javascript. This will take a click event from anywhere on the page.
document.addEventListener('click', event => {
})
inside the event listener, place an if block to test whether the click event was received by an element that was inside a div of .container class:
if (event.target.parentElement.className=='container') {
}
I slightly modified this, see edit note and bottom.
If the click event got that far, the click must have been recieved by the visible div inside that container (since the hidden one cannot receive click events and they are the only two elements present.
So you can go ahead and swap the classes applied to the visible div that received the click:
event.target.classList.add('hidden');
event.target.classList.remove('main');
You now have to do the opposite to the other div in the container class to make that sibling visible. The problem is, you don't know whether the hidden class was the first child, or the second child of the container div. What you do know for sure, is that the other div is a sibling of the div you just made invisible.
So we can test to see if there is a next sibling using a conditional:
if (event.target.nextElementSibling) {
event.target.nextElementSibling.classList.add('main');
event.target.nextElementSibling.classList.remove('hidden');
}
If the hidden div followed the visible one, a nextElementSibling will be found and the classes swapped. If no nextElementSibling was found, we know the other div had to come before the one we already hid.
so, an else extension of that if block can be added to switch the classes on the previousElementSibling:
...} else {
event.target.previousElementSibling.classList.add('main');
event.target.previousElementSibling.classList.remove('hidden');
} // end else;
And you're done!
I wanted to explain the logic in detail to make sure you know what's going on, but it's not that complicated.
The advantage of an approach like this is that the single event listener will cope with 1, 2, or 1,000 pairs of divs and none need any special IDs or anything other than an initial class of .main or .hidden (and that they be grouped inside a .container div.
document.addEventListener('click', event => {
if (event.target.parentElement && event.target.parentElement.className=='container') {
event.target.classList.add('hidden');
event.target.classList.remove('main');
if(event.target.nextElementSibling) {
event.target.nextElementSibling.classList.add('main');
event.target.nextElementSibling.classList.remove('hidden');
} else {
event.target.previousElementSibling.classList.add('main');
event.target.previousElementSibling.classList.remove('hidden');
} // end else;
} // end parentElement if;
}) // end click listener;
.hidden {
display: none;
border: 1px solid red;
margin: 5px;
}
.main {
display: block;
border: 1px solid black;
margin: 5px;
}
<div class='container'>
<div class='main'>my first main content</div>
<div class='hidden'>my first hidden content </div>
</div>
<div class='container'>
<div class='main'>my second main content</div>
<div class='hidden'>my second hidden content </div>
</div>
Edit the conditional to detect whether the parent element of the click event was a .container div was modified to check that the event target has a parent AND that the parent is a .container div. This prevents an error if a click is received anywhere outside of the container div.
** Displaying an Opaque Overlay in Response to Click **
Again, this solution allows the functionality to be applied to limitless div elements without the need for independent ids. Again, two classed .main and .hidden are used to decide which div has been clicked from a single event listener applied to the document rather than to multiple divs.
The basic process of displaying, and then re-hiding the (originally hidden) .overlay div is very simple:
if (element.className == 'main') {
element.parentElement.getElementsByClassName('overlay')[0].classList.remove('hidden');
}
if (element.className == 'overlay') {
element.classList.add('hidden');
}
However, a problem arises because of the use of class names, rather than ids. Namely, when the overlay is displayed, a click on it may be received by a descendent element that does not have the class name .hidden. To work properly, every descendent of the overlay div would have to be given the .hidden class and the class swapped applied for ever element inside the .hidden div. This could get very complicated if the div had many child elements (perhaps with their own descendents).
Instead, when a click is received, the target element is inspected to see if it has a relevant class (main or hidden). If it does, the script flows to the simple class switching blocks. If it has no, or a different class name however, a do-while loop examined the parent element of the click to see if it was contained in a relevant (main or hidden) class. The loop continues searching up the document tree until either a relevant element is found, or there are no more parent elements to examine.
If a parent is found to have the required class name, a reference to the element is passed onto the class switching block.
do {
if (element && (element.className == 'overlay' || element.className == 'main')) {
// foundElementClassName = element.className;
break;
} // end if;
if (element.parentElement) {
element = element.parentElement;
} else {
break;
}
} while (element.className != "overlay" || element.className != "main");
The following working snippet demonstrates the functionality. In it, three divs (coloured pink) have an associated (initially) hidden overlay div, while a fourth div has no associated overlay and should ignore clicks.
If a click is made on a pink div, it's specific overlay appears. A click anywhere on the overlay dismisses it, regardless of whether the click was received by the overlay div itself, or by a child element or deeper descendent (e.g. clicking on the text of the overlay (which is in a child h2 element still allows the correct .overlay div to have its styles switched to hide it again.
document.addEventListener('click', (event) => {
let element = event.target;
do {
if (element && (element.className == 'overlay' || element.className == 'main')) {
// foundElementClassName = element.className;
break;
} // end if;
if (element.parentElement) {
element = element.parentElement;
} else {
break;
}
} while (element.className != "overlay" || element.className != "main");
// end do-while loop;
// if a relevant element was found, the element object is stored in element variable;
if (element.className == 'main') {
element.parentElement.getElementsByClassName('overlay')[0].classList.remove('hidden');
}
if (element.className == 'overlay') {
element.classList.add('hidden');
}
}) // end click event listener;
.main {
display: block;
width: 50%;
margin: 10px;
border: 1px solid black;
background: pink;
}
.overlay {
position: absolute;
display: flex;
align-items: center;
justify-content: center;
top: 0px;
left: 0px;
width: 100%;
min-height: 100%;
bottom: auto;
z-index: 1;
background: rgba(255,255,0,0.7);
padding: 20px;
}
.hidden {
display: none;
}
.other {
display: block;
width: 50%;
margin: 10px;
border: 1px solid black;
background: yellow;
}
<div class="container">
<div class="main">Content of div 1. Content of div 1. Content of div 1. Content of div 1. Content of div 1. Content of div 1. Content of div 1. Content of div 1 </div>
<div class="overlay hidden"><h1>overlay for first pink div</h1> </div>
</div>
<div class="other">
some other content that doesn't have an associated overlay and that should ignore clicks.
</div>
<div class="container">
<div class="main">Content of div 2. Content of div 2. Content of div 2. Content of div 2. Content of div 2. Content of div 2. Content of div 2. Content of div 2. Content of div 2. Content of div 2.</div>
<div class="overlay hidden"><h1>overlay for SECOND pink div</h1> </div>
</div>
<div class="container">
<div class="main">Content of div 3. Content of div 3. Content of div 3. Content of div 3. Content of div 3. Content of div 3. Content of div 3. Content of div 3. Content of div 3. Content of div 3. </div>
<div class="overlay hidden"><h1>overlay for Third pink div</h1> </div>
</div>

How to use css bootstrap list-group with affix to create a sticky menu in a column?

I am trying to create a sticky menu using CSS Bootstrap affix and list-group menu.
I manage to get most of it to work except for when the user scrolls down.
When the user scrolls down, the menu seems to take the entire with of the page.
I tried to set it up via data attributes
using something like this
<div class="container">
<div class="row">
<div class="col-md-3" id="leftCol">
<div data-spy="affix">
<div class="list-group list-group-root well">
<a class="list-group-item" href="#introduction">Introduction</a>
<a class="list-group-item" href="#features">Features</a>
<a class="list-group-item" href="#dependencies">Dependencies</a>
</div>
</div>
</div>
<div class="col-md-9" id="mainCol">
Some long text for the body along with some tables.
</div>
</div>
</div>
But the data attribute did not make the menu stick! it just kept it on the top.
So I tried to use JS to get the job done like this
$(function(){
$('#leftCol').affix({
offset: {
top: 100,
bottom: function () {
return (this.bottom = $('.footer').outerHeight(true))
}
}
});
});
I created jsFiddle to show you the current behavior.
How can I fix this affix so when the user scrolls down the menu maintain the same shape?
First of all, you should use either data-attributes or JS.
I updated your jsFiddle. The position of id="leftCol" was changed:
<div class="col-md-3" >
<div id="leftCol">
...
</div>
</div>
and style was added:
#leftCol {
width: 220px;
}
Also, you should add media queries to remove affix from mobile view.
As an "unacceptable" workaround, I set a max width of the menu to 250px like so
.list-group.list-group-root {
padding: 0;
max-width: 250px;
}
I am not sure how to get it to work without adding a max-with the max with should be defined by the parent. In this case class="col-md-3"
UPDATED
javascript to the rescue!
I added the following JS code to solve this problem once an for all.
It basically resize the menu everytime affix.bs.affix event is fired
$(document).on('affix.bs.affix', '#docs-menu', function() {
$(this).width($(this).width());
});
From the docs
affix.bs.affix => This event fires immediately before the element has
been affixed.
Ok I believe I got most of the code working like you want it to. The main changes I made were adding this CSS:
#leftCol {
display: block;
height: auto;
padding: 0;
width: 100%;
}
.navbar-fixed-top-again {
position: static;
top: 60px;
z-index:1031;
}
.navbar-inner {
background: red;
padding: 5px;
}
.affix {
position: fixed !important;
}
and I changed up some of the structure on your HTML:
<div class="container body-content">
<div>made up content to allow the navigation to scroll more before it becomes sticky. This height will need to be set in the data-offset-top which is in the leftCol DIV just below this content. The same will apply if you need to set it for a footer offset.</div>
<!-- new nav section -->
<div class="col-md-3 navbar-fixed-top-again" id="leftCol" data-spy="affix" data-offset-top="80">
<div class="navbar-inner">
<div class="list-group list-group-root well">
*the rest of your code*
</div>
</div>
</div>
</div>
The main problem now is having a sticky navigation menu with variable height. If you notice when you scroll your reading content underneath jumps up and gets hidden. It seems that it is possible to fix this using JavaScript (link to SO question).
Heres the link to your updated Fiddle. Hope that helps.

How to make visible and hide particular divs?

All div are generated dynamically, and having same class class="bucket". This div had one more div inside class="restPart" rest part, which will hide, when page load first time.
What I want, I have more than one div,
1. Each divs hides the rest part, when page load first time.
2. Each div are diving into two part, one part will always show and rest part will not show.
3. Rest part will appear only when we click the link "show more",
4. When div are fully shown It will show link "show less", when we click on it, will hide the rest part.
5. This should work only for one div on which we are clicking, other divs should be unaware.
_data_grid.html
<script language="javascript" type="text/javascript">
$(document).ready(function(){
$("#restPart").hide();
$('#grid_content').on('click','.more', function(){
//$("#restPart").show();
$("div").children("div").show();
$("#showRest").hide();
});
$('#grid_content').on('click','.less', function(){
//$("#restPart").hide();
$("#showRest").show();
$(this).closest("div").hide();
});
});
</script>
#grid_content {
overflow: hidden; clear: both;
}
#grid_content .bucket {
width: 290px; float: left; margin: 0 0 48px 20px;
border: 1px solid #262626;
background: $gray-lighter;
}
#grid_content .bucket ul {
margin: 0 0 0 0; padding: 0 0 0 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<section id="grid_content">
<!--1st -->
<div class="bucket">
... Content of visible part of bucket...
Show More.
<!--Below is the rest part when we click on the above link, Showrest it will show-->
<div class="restPart" id="restPart">
... Content of Rest Part and click on the Show Less It will hide this div...
Show Less.
</div>
</div>
<!--2nd -->
<div class="bucket">
... Content of visible part of bucket...
Show More.
<!--Below is the rest part when we click on the above link, Showrest it will show-->
<div class="restPart" id="restPart">
... Content of Rest Part and click on the Show Less It will hide this div...
Show Less.
</div>
</div>
</section>
What I want
In the like following figures, more div will be generated dynamically, previously all will hide, when I click on first div show the rest content, but rest will not show, please see the figure 2,
Figure 1
Figure 2
As noted by others, remove duplicate IDs.
Judging by your image,
your button Show more, (once clicked - reveals the content and) becomes: Show less so...
change button text (So use a single toggle button!)
toggle/slide the previous DIV
$(function() { // DOM is now ready
$("#grid_content").on("click", ".toggle", function(evt) {
evt.preventDefault(); // Prevent window following #hash / jump
var more = $(this).text() === "Show More";
$(this).text(more ? "Show Less" : "Show More").prev(".restPart").slideToggle();
});
});
.bucket {
width: 290px;
float: left;
margin: 0 0 48px 20px;
border: 1px solid #262626;
background: lightgray;
}
.restPart{
overflow:auto;
display:none; /* hide initially */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section id="grid_content">
<div class="bucket">
<p>Visible part....</p>
<div class="restPart">
<p>Content...</p>
</div>
Show More
</div>
<div class="bucket">
<p>Visible part....</p>
<div class="restPart">
<p>Content...</p>
</div>
Show More
</div>
</section>
First of all - your naming strategy is a bit wrong. HTML document can contain (by standards) only one object with one ID - that's the purpose of ID as such. So, you can't have many objects with id="showRest" or id="restPart" or id="showless".
Possible solution for your problem.
Design your HTML something like
<div class="bucket">
<div class="mininfo">
<div class="intro">some intro bucket 1...</div>
Show more
</div>
<div class="maxinfo" style="display: none;">
<div class="intro">Here is full content 1 of everything</div>
Show less
</div>
</div>
<div class="bucket">
<div class="mininfo">
<div class="intro">some intro bucket 2...</div>
Show more
</div>
<div class="maxinfo" style="display: none;">
<div class="intro">Here is full content 2 of everything</div>
Show less
</div>
</div>
Next, in JavaScript part you can use selectors such as:
$(".bucket .showmore").on('click', function(){
var $bucket = $(this).parents('.bucket');
$bucket.find('.mininfo').hide();
$bucket.find('.maxinfo').show();
});
$(".bucket .showless").on('click', function(){
var $bucket = $(this).parents('.bucket');
$bucket.find('.mininfo').show();
$bucket.find('.maxinfo').hide();
});
Updated 1: added two buckets to example.
Updated 2: example in JSFiddle
Updated 3: update in JSFiddle with some content kept

Prevent parent div from resizing when child div resizes

What I want to accomplish is after calling jQuery $().hide(), the animation to hide a child div on a current page and then show a new div in its place.
When I call the .hide(), the parent div resizes and I do not want that.
The parent has two divs in it, a text filled div, and the div in question so when I call the hide, only the text-only div remains. I want the height to remain the same because the new content is going to be the same height.
Here is what I have:
<div class="adminContent"> //Wrapper div, this should not change in height of 668px
<div class="adminTitle"> // Text only div, remains after .hide is called
Admin > Manage Class Roster
</div>
<div class="resetBody" id="manageClassBody1"> // Div that is being hidden/replaced
... // div contents
</div>
CSS
.adminContent {
background: #F7F7F7;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
min-height: 668px;
}
How should I have it so that its height is static after I hide the child div? Thanks!
EDIT: I want to do an in place swap of the two divs with an animation to switch between the two. I looked at the replaceWith() provided by jQuery but I'm not sure how to use it for my needs.
I would suggest using the animation features of JQuery to accomplish your task.
I created a sample JSBin for you.
Example:
$(document).on("click", "#togglebtn", function() {
var divs = $('.resetBody, .resetBody2');
var hiddenDiv = divs.filter(":not(:visible)");
var visibleDiv = divs.filter(":visible");
visibleDiv.fadeToggle({
complete: function() {
hiddenDiv.fadeToggle();
}
});
});
.adminContent {
background-color: lightgreen;
padding: 10px;
}
.resetBody {
background-color: #880000
}
.resetBody2 {
background-color: lightblue
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="adminContent">//Wrapper div, this should not change in height of 668px
<div class="adminTitle">much text wow! much text wow! much text wow! much text wow! much text wow!
Admin > Manage Class Roster
</div>
<div class="resetBody">Div 1
<br/>Div 1
<br/>Div 1
<br/>Div 1
<br/>Div 1
<br/>Div 1
<br/>
</div>
<div class="resetBody2" style="display:none">Div 2 is taller
<br/>Div 2
<br/>Div 2
<br/>Div 2
<br/>Div 2
<br/>Div 2
<br/>Div 2
<br/>
</div>
</div>
<div style="margin-top:10px;">
<button id="togglebtn">Toggle</button>
</div>

Scrolling a DIV to Specific Location

There is a plethora of similar questions around but none of them seem to be looking for what I'm looking for, or else none of the answers are useful for my purposes.
The jsfiddle: http://jsfiddle.net/tumblingpenguin/9yGCf/4/
The user will select an option and the page will reload with their option applied. What I need is for the "option list" DIV to be scrolled down to the selected option such that it is in the center of the option list.
The HTML...
<div id="container">
<a href="#">
<div class="option">
Option 1
</div>
</a>
<!-- other options -->
<a href="#">
<div class="option selected"> <!-- scroll to here -->
Option 4
</div>
<!-- other options -->
<a href="#">
<div class="option">
Option 7
</div>
</a>
</div>
The selected option is marked with the selected class. I need to somehow scroll the DIV down to the selected option.
The CSS...
#container {
background-color: #F00;
height: 100px;
overflow-x: hidden;
overflow-y: scroll;
width: 200px;
}
a {
color: #FFF;
text-decoration: none;
}
.option {
background-color: #c0c0c0;
padding: 5px;
width: 200px;
}
.option:hover {
background-color: #ccc;
}
.selected {
background-color: #3c6;
}
I've seen this done on other websites so I know it's possible—I just haven't a clue where to begin with it.
P.S. jQuery solutions are acceptable.
Something like this http://jsfiddle.net/X2eTL/1/:
// On document ready
$(function(){
// Find selected div
var selected = $('#container .selected');
// Scroll container to offset of the selected div
selected.parent().parent().scrollTop(selected[0].offsetTop);
});
Without the jQuery (put this at the bottom of the < body > tag:
// Find selected div
var selected = document.querySelector('#container .selected');
// Scroll container to offset of the selected div
selected.parentNode.parentNode.scrollTop = selected.offsetTop;
demo: http://jsfiddle.net/66tGt/
Since you said JQuery answers are acceptable, here's an example of what you're looking for:
$('body, html').animate({ scrollTop: div.offset().top-210 }, 1000);
Replace div for whatever element you want to scroll to.
Here is one possible solution that may work for you:
Demo Fiddle
JS:
$('#container').scrollTop( $('.selected').position().top );
Take a look at this fiddle : http://jsfiddle.net/9yGCf/8/
As requested it scrolls to the middle of the div (you can change the offset by however much you want to make little adjustments). I would probably suggest setting either a line height with some padding and whatnot and then do the math to change the offset that I have at -40 so that it does put it in the middle.
But I used jquery and came up with this quick little code... also added some code to change the selected option
$('.option').click(function(){
$('.selected').removeClass('selected');
$(this).addClass('selected');
$(this).parent().parent().scrollTop(selected[0].offsetTop - 40);
});
This magical API will automatically scroll to the right position.
element.scrollIntoView({ block: 'center' })
See more details:
https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView

Categories

Resources