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
Related
How would I be able to simplify this jquery code. I feel like I am repeating myself and just wondering if there is a shorter way to write this which I'm sure there is. I am a bit new to javascript and jquery. I have created a two tabs with their own containers with miscellaneous information in them. Basically I want the container to open when it's related tab is clicked on. I also would like the tab to be highlighted when it's active. Also, how would I be able to write code to make all tab containers disappear when you click off from the tab containers.
<!-- HTML Code -->
<div class="sort-filters">
<span class="sort-by active">SORT BY</span>
<span class="filter">FILTER</span>
</div>
<div class="sort-containers">
<div class="sort-by-container">Sort by click me here</div>
<div class="filter-container">Filter click me here</div>
</div>
/* CSS */
.sort-filters {
display: flex;
width: 500px;
height: 30px;
}
.sort-by,
.filter {
background: #CCC;
color: #756661;
flex: 1;
display: flex;
justify-content: center;
align-items: center;
font-family: 'Arial', sans-serif;
cursor: pointer;
}
.sort-by-container,
.filter-container {
width: 500px;
background: #756661;
color: #FFF;
height: 100px;
display: none;
}
.active {
background: #756661;
color: #FFF;
transition: 0.2s;
}
// Jquery Code
js = $.noConflict();
var sort = js('.sort-by');
var filter = js('.filter');
var sortContainer = js('.sort-by-container');
var filterContainer = js('.filter-container');
js(sort).click(function() {
js(filterContainer).hide();
js(sortContainer).show();
js(sort).addClass('active');
js(filter).removeClass('active');
});
js(filter).click(function() {
js(sortContainer).hide();
js(filterContainer).show();
js(filter).addClass('active');
js(sort).removeClass('active');
});
In order to avoid such repetitive actions I like to stick to naming conventions, so that I can apply the ID's, classes or attributes from one element to select other elements, for instance:
<div id="tabs">
<span class="active" data-type="sort-by">SORT BY</span>
<span data-type="filter">FILTER</span>
</div>
Now, all you need is one click handler on #tabs span, and get the data-type of the span you clicked on. You can use that to filter on the classes of the other container elements.
The second thing is that you can attach handler to more than 1 element at the same time. So in your example, js('#sort-containers div').hide(); will hide all the div's that match the selector at once.
results
I changed some classes to ID's, and some classes to data attributes. Here's a fiddle: https://jsfiddle.net/mq9xk29y/
HTML:
<div id="tabs">
<span data-type="sort-by">SORT BY</span>
<span data-type="filter">FILTER</span>
</div>
<div id="sort-containers">
<div class="sort-by-container">Sort by click me here</div>
<div class="filter-container">Filter click me here</div>
</div>
JS:
js = $.noConflict();
var $tabs = js('#tabs span');
$tabs.click(function() {
var $clicked = js(this); //get the element thats clicked on
var type = $clicked.data('type'); //get the data-type value
$tabs.removeClass('active'); //remove active from all tabs
$clicked.addClass('active'); //add active to the current tab
js('#sort-containers div').hide(); //hide all containers
js('.' + type + '-container').show().addClass('active'); //add active to current container
});
As long as you follow the naming convention of data-type: bla in the tabs, and bla-container on the classes in sort-container, you never have to worry about coding for additional tabs.
There might still be things that could be further optimised, but at least it'll take care of the repetition.
I have issue with jQuery sortable.
Here is live example: JSFiddle
HTML:
<div class="a">
<div class="b">
a<br>
b<br>
c<br>
d<br>
e<br>
f<br>
g<br>
h<br>
i<br>
j<br>
k<br>
l<br>
m<br>
n<br>
o<br>
</div>
</div>
JS:
$(function(){
$('.a').sortable();
});
CSS:
.b {
border: 1px solid;
width: 100px;
height: 100px;
overflow-y: scroll;
overflow-x: hidden;
text-align: center;
}
In this case I have div with scroll. I scroll to the end of the div and I try to sort element using drag&drop. After this action, scroll in div jumps to beginning of this div. How I can "remember" position of scroll and "revert" it after sortable?
You need to save the scroll position and then reapply it when you stop moving the object.
JSFIDDLE: JSFIDDLE
$(function(){
var scrollTop = 0;
$('.a').sortable({
start: function(event, ui){
scrollTop = ui.item.scrollTop();
},
stop: function(event, ui){
ui.item.scrollTop(scrollTop);
}
});
});
You should use the sortable() method on the inner <div id="b"> and put every element you want to sort inside a <div> tag so they can be treated as DOM elements.
Here's a working solution JSFiddle
You might want to check THIS topic.
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
G'day!
I have a page which has Horizontally Scroll feature going on there.
I have a side bar and a content box
In side bar I have 5 links, say LINK1 - LINK5
In the content box, I have 3500px of width which contains 5 sections of divs of 700px each.
So the page initially loads in the first 700px div. So if I click on Link 3, it will smoothly scrolling to 3rd div section.
However, I would like to load the page in the 2nd div.
I was able to do this using scrollLeft()
<script>$("div.content1").scrollLeft(700);</script>
But the horizontal scrolling will be messed up. The second div will act as first div, which means when I click LINK1, it won't be scrolled back.
Help?
*I think this code is needed
<script>
function goto(id, t){
//animate to the div id
$(".contentbox-wrapper").stop().animate({"left": -($(id).position().left)}, 1200);
}
</script>
This is sample of HTML code
<div id="sidebar1">
<span class="upper">Foods</span><br />
<span class="lower">Rice, Noodles & Pasta</span><br />
<span class="lower">Snacks & Tidbits</span><br />
<span class="lower">Canned & Ready to Eat</span><br />
<span class="lower">Breakfast Cereal</span><br />
<br />
This is sample of my content box
<div class="content1">
<div class="contentbox-wrapper">
<div id="rice" class="contentbox" align="center">
<h2>
Rice, Noodles & Pasta
</h2>
<section id="product">
<ul class="clear">
<li data-id="1">
<div href="#">
<img src="images/products/f1/_DSC4640.jpg" width="200" height="200" />
<h3>Maggi Curry Flavour</h3>
<p>(5 + 1) x 79 G</p>
<h2>Price:$2.40</h2>
</div>
</li>
I've created an example based a little on your markup. I hope, that it is, what you're looking for. I also made some minor changes on your JavaScript. See the explanation below.
HTML
<nav>
<a>Item 1</a>
<a>Item 2</a>
</nav>
<div class="contentbox-wrapper">
<div>
<h2>Item 1</h2>
</div>
<div>
<h2>Item 2</h2>
</div>
</div>
If you can apply a markup like this, where the index of each link corresponds with the index of each content container, then you can get rid of all the ids that you need in the JavaScript part.
CSS
div.contentbox-wrapper {
position: relative;
width: 400px;
height: 200px;
overflow: hidden;
overflow-x: scroll;
font-size: 0;
line-height: 0;
white-space: nowrap;
}
div.contentbox-wrapper > div {
display: inline-block;
width: 400px;
height: 200px;
text-align: center;
}
div.contentbox-wrapper > div:last-child {
margin-right: 0;
}
JavaScript
var container = $('div.contentbox-wrapper');
var boxes = container.children();
$('nav > a').click(function() {
container.stop().animate({
scrollLeft: boxes.eq($(this).index()).get(0).offsetLeft
}, 350);
});
Try to store selectors that you use multiple times in variables. The advantage is, that you don't need to re-query them again. This JavaScript does nothing else, then getting the offset of the box that corresponds with the clicked link, using .index() and .eq(). This value is then used in the .animate()-function to scroll to this position.
Demo
Try before buy
A few notes
If you have an ampersand within normal content like "Rice, Noodles & Pasta" you must escape it like: &.
Don't use align="center". It is deprecated since HTML4. Use CSS for this purpose.
I'm struggling to find the right Jquery to show/hide a div at a height that is parallel to the trigger button. I attempted to offset the show/hide div to the right, but because the footnotes appear in different left/right positioning, each would be different. Instead, I will need to place the divs inside of another div along the right.
My hope is to add hyperlinked footnotes to some text, so that readers will not have to search for the footnotes, but also won't be overwhelmed with too much text. I would prefer to have more than one footnote open at a time, but if it needs to be one at a time to properly display, so be it.
EDIT:
#rohan-kumar helped with this code
$('.a_footnote').on('click',function(e){
e.preventDefault();
var divId=$(this).data('divid');
console.log(divId);
$('#'+divId).toggle();
});
So here's the way it stands: http://jsfiddle.net/6n28t/21/
However, my primary problem remains -- how can I make the footnote appear at the same height as the trigger? These will be long pieces of text and I want the footnotes to appear at the same height as the corresponding mark. How can I made [2] appear farther down on the page?
So, basically combining the other answers leads to this Fiddle
Html is the same as what you have in your fiddle.
CSS
.wrapp{
border:1px solid red;
height:100%;
}
.clear{
clear:both;
}
.footnotes div {
position: relative;
display: none;
}
JavaScript
$('.a_footnote').on('click',function(e){
e.preventDefault();
var divId=$(this).data('divid');
var height = $(this).position().top;
console.log(divId);
$(".footnotes div").hide();
$('#'+divId).toggle().css("top", height - 10);
});
You don't need the floats, I am assuming that you would want this text to appear inline in your paragraphs. You need to position the notes absolutely and then set the top/left according to the position of your clicked element + width of element + offset.
jsFiddle Demo
HTML:
<div class="content">
<p> Lorem ipsum ([1]).</p>
<p> Lorem ipsum ([2]).</p>
</div>
<div class="footnotes">
<div class="footnote1">1. Foo Bar</div>
<div class="footnote2">2. Foo Bar</div>
</div>
CSS
.footnotes > div { display: none; position: absolute; border: solid 1px red; }
JavaScript
$('.footnote').on('click', function(e) {
e.preventDefault();
var $note = $('.' + this.id);
var $position = $(this).position();
$('.footnotes > div').hide();
$note.css({
top : $position.top,
left: $position.left + $(this).width() + 5
}).show(); })
Try this,
HTML
<div class="wrapp">
<div class="content" style="float:left;">
<div> Lorem ipsum (<a class="a_footnote" href='javascript:;' data-divid="footnote1">[1]</a>).</div>
</div>
<div class="footnotes" style="float:right">
<div id="footnote1">1. Foo Bar</div>
</div>
<div class="clear"></div>
</div>
CSS
.wrapp{
border:1px solid red;
height:50px;
}
.clear{
clear:both;
}
SCRIPT
$('.a_footnote').on('click',function(e){
e.preventDefault();
var divId=$(this).data('divid');
console.log(divId);
$('#'+divId).toggle();
});
If you want the div.footnotes will be hidden initially, then you need to add a css like
div.footnotes {display:none;}
Fiddle http://jsfiddle.net/6n28t/7