Please see JSFiddle. Essentially, I have 3 really long divs. At the end of the second div, I have a button that, on clicked, removes the first div. The problem is that removing this div makes the page scroll to the end. How do I prevent this behaviour and keep the viewport intact when this happens?
<div id="first">
<p>Some really long content ...</p>
</div>
<div id="second">
<p>Some really long content... </p>
</div>
<button onclick="$('#first').remove()">Remove First div</button>
<div id="third">
<p>Some really long content ...</p>
</div>
the behaviour explained by you is expected. To maintain back on the current position, you will need to adjust the viewport scroll's position. For example, updated in your jsfiddle: http://jsfiddle.net/d0fqts8p/1/
$('button').click(function () {
var firstElHeight = $('#first').height(); // get the height of element to be deleted
var currentHeight = $("body").scrollTop(); // get the current scroll position
$('#first').remove();
$("body").scrollTop( currentHeight - firstElHeight); //calculate and set back
});
Related
I've made a modal, and I am hiding the scroll bar on the body so the user can only scroll the modal content.
Issue is that when I set overflow-y:hidden the body scrolls to top, but I want the page position to be preserved.
<body>
Long content
</body>
scrollY is at 1000
<body style="overflow-y:hidden">
Long content
</body>
scrollY goes to 0
I've toyed with the idea of storing the current scrollY position and scrolling back there once overflow-y is revoked. But its not the effect I desired.
Does anyone else have a better solution?
Assuming this is a true modal, and that you are preventing further actions to the main content until it is actioned (closed), why not add your content to a div and place a mask over the div, which would prevent interactions until it it closed. E.g.
<body>
<div class='content'>
Long content
</div>
<div class="modal-mask">
<div class="modal">Modal content</div>
</div>
</body>
Give the modal mask absolute positioning and covering the screen, then position your modal where appropriate.
I'm trying to make a list filled with an unknown number of items animate out from underneath a div when it is being hovered over in such a way that it seems like the list is being pulled down rather than resized down. (The jquery slideDown() and slideToggle()-functions does the "pulled down" version nicely, but I want the list items to come down kinda like if you had written on roll-up curtains and were rolling it down.)
Lists, divs, or tables doesn't matter; as long as it looks like I want it to.
Here's a jsfiddle with the essentials of what I've tried. As in the real application, the only problem is that when it's in its up-rolled position, (sometimes) it's higher than the parent div and shows up above it.
In the code below (from jsfiddle), I want #popouter to only show when it's below #toggle, not when it sticks up above it when being "rolled up":
<div id="oneofmanyitems">
<div id="toggle"><h2>Click me to reveal the generated texts</h2></div>
<div id="popouter">
<div>Some generated text</div>
<div>Some generated text</div>
<div>Some generated text</div>
<div>Some generated text</div>
</div>
</div
I'd love for there to be a way to let the list items "float" down and just animate() up the height of the list until all of the items (starting with the top-most) popped out due to overflow: hidden, but that doesn't seem to be possible without having to give the items position:absolute and thus making them appear on top of each other in the bottom of the list.
Usually, I'd just Jquery-brute-force the divs to disappear after some arbitrary time of scrolling upp underneath the parent div, but in this case I also have the list-div that, in that case, would need to be partially (hidden in the top) as it goes up.
Anyone have any ideas on how to make this work? Maybe I'm just thinking into a corner by now and aren't seeing the obvious answer.
Thanks!
Try this code
DEMO
<div id="oneofmanyitems">
<div id="toggle" class="active">
<h2>Click me to reveal the generated texts</h2>
</div>
<div id="popouter">
<div>Some generated text</div>
<div>Some generated text</div>
<div>Some generated text</div>
<div>Some generated text</div>
</div>
</div>
$('#toggle').click(function(){
if ($(this).hasClass('active')){
$(this).removeClass('active');
$("#popouter").slideUp();
}else{
$(this).addClass('active');
$("#popouter").slideDown();
}
return false;
});
In place of using $("#popouter").animate({marginTop: -h}, 1000); why dont u try $("#popouter").slideToggle();..
In css ,
.popouter{display:none}
and in JS
$('.toggle').click(function(){
var $div = $(this).next('.popouter').slideToggle();
$(".popouter").not($div).hide();
});
the above script is for use in more than one div..use classes instead of id
I am trying to make something where I have a div that scrolls. Inside the div there are "title" elements and as I scroll I want the title element of that section to stick to the top of the div and remain there like a header.
Sort of like what people see on webpages where the menu sticks to the stop of a page as you scroll. This example can clearly be seen on the Mac OS X calendar in the "Day" view.
I think I can deal with the making the element stick part, I saw an interesting solution that I think I can adapt. However I was wondering if someone can help me figure out how to know if a title element has reached the top of a scrollable div.
The use case is as follows:
<div class="container">
<div class="floatLeft">
<div class="scrollingDiv" style="height:100px; overflow-y:scroll; overflow-x:hidden;">
<ul>
<li>
<div>
<h4>Title</h4>
<div>Content</div>
</div>
</li>
<li>
<div>
<h4>Title</h4>
<div>Content</div>
</div>
</li>
</ul>
</div>
</div>
<div class="floatRight"></div>
</div>
How would I know when the second "Title" has hit the top of my "scrollingDiv", not the top of the page itself?
Thanks!
You can make an element sticky by setting it's top property to zero and making setting position:absolute; via css.
.stickyTop {
position:absolute;
top:0px;
}
This will ensure the element stays at the top of the page always.
To identify if an element has reached the top of window you can use offset() to identify the current position and check if it's neared the top.
$('div.scrollingDiv').scroll(function() {
var active = null;
$('.scrollingDiv h4').each(function(idx, val) {
var topOffset = $(val).offset().top;
if (topOffset < 20) // elem is 20 px from top
{
// Element nearest the top
active = $(val);
}
console.log(active); // Element closest to the top
});
});
The above simply loops though all the h4 properties searching for the element closest to the top of the page, and logs it.
You can combine these together to create something like a Funky jsFiddle.
I'm struggling with a jquery or javascript problem.
It already got annoying which tells me I might think too complicated on this one.
So my markup (simplyfied) looks like this:
<div class="container">
My Content
scroll down
</div>
<div class="container">
My Content
scroll down
</div>
<div class="container">
My Content
scroll down
</div>
<div class="container">
My Content
scroll down
</div>
Basically just some containers.
Each one contains different content and a button.
The Plan:
1) After a click on a button the window should scroll down to the next container.
2) The last button scrolls to the first container again. So I need a loop.
3) The numbers of containers may change from page to page.
EDIT: 4) The containers may not always be direct siblings to each other (see markup below)
The Problem:
I could get this to work by giving each container a unique ID as a target for the scroll effect.
The problem with that is that it gets too messy quickly.
Cant I just somehow target "the next object with the class: container", and scroll to that?
I'm not sure if js or jquery is the right approach. My knowledge in both is somewhat limited.
I would be really grateful for a push in the right direction.
EDIT: The containers may not always be direct siblings of each other.
<div class="row">
<div class="container">
My Content
scroll down
</div>
<div class="container">
My Content
scroll down
</div>
</div>
<div class="container">
My Content
scroll down
</div>
<div class="container">
My Content
scroll down
</div>
<div class="row">
<div class="container">
My Content
scroll down
</div>
<div class="container">
My Content
scroll down
</div>
</div>
Simple solution:
To get the next container, try using next().
Basically, the <div> containers are siblings of each other, so calling .next() on one div container will give you the next.
$(".button").on("click", function(e) {
$(document).scrollTop($(this).parent().next().offset().top);
// $(this).parent().next() // this is the next div container.
return false; // prevent anchor
});
http://jsfiddle.net/Pm3cj/1/
You just use $(this) to get the link object, .parent() to get the parent of the link, which is the <div>, then .next() to get the next sibling (note it will wrap automatically, so the sibling after the last <div> is the first <div>!),.offset()to get its position relative to the page,.top` to get it relative to the top border.
Then you just use $(document).scrollTop() to scroll to that location.
For a completely general solution, use:
$(".button").on("click", function(e) {
container = $(this).parent();
// if I am the last .container in my group...
while ( document != container[0] // not reached root
&& container.find('~.container, ~:has(.container)').length == 0)
container = container.parent(); // search siblings of parent instead
nextdiv = container.nextAll('.container, :has(.container)').first();
// no next .container found, go back to first container
if (nextdiv.length==0) nextdiv = $(document).find('.container:first');
$(document).scrollTop(nextdiv.offset().top);
// $(this).parent().next() // this is the next div container.
return false;
});
The code basically uses container.find('~.container, ~:has(.container)') to find any sibling that has or is a .container. If nothing, then go up the DOM tree 1 step.
After it finds something which is or has a .container, it grabs it with nextdiv = container.nextAll('.container, :has(.container)').first();.
Lastly, if nothing is found, checked by nextdiv.length==0, just grab the first .container in the whole page.
Then scroll to whatever .container was grabbed.
http://jsfiddle.net/Pm3cj/3/
To animate the scroll, place the scrollTop property in an animate function:
// $(document).scrollTop(nextdiv.offset().top); // snaps to new scroll position
$('body').animate({scrollTop:nextdiv.offset().top},300); // animates scrolling
http://jsfiddle.net/Pm3cj/4/
JavaScript is not required for this. You can use HTML anchors.
<div class="container" id="first">
My Content
scroll down
</div>
<div class="container" id="second">
My Content
scroll down
</div>
<div class="container" id="third">
My Content
scroll down
</div>
<div class="container" id="fourth">
My Content
scroll down
</div>
What you want can be easily achieved through parent() and child().
If the number of containers on each page is different, then you should start ID'ing (don't know if that's a term) containers serially. Something like, class="container-1"
The click event on the last button should do something like:
var num = $('div[class^="container-"]').filter(function() {
return((" " + this.className + " ").match(/\scontainer-\d+\s/) != null);
});
num++;
var last_container = $(this).parent('.container' + num);
last_container .scrollTo();
Am sure you can figure out what the next button should do ;)
I have a DIV in the center of my page which has margin-left and margin-right both set to auto. I want to be able to enlarge or shrink that DIV. Unfortunately when I do so, the position of it on the screen does not change, meaning that it is no longer centered.
<div id="content" style="margin-left:auto;margin-right:auto;width:240px">
<p>Lots of text</p>
</div>
Meanwhile elsewhere:
$("#content").width(480);
At this point, I get my div no longer centered, but overbalanced to the right. Similarly if I set the width smaller than 240, it then becomes too far to the left.
How do I ensure that my margins actually adjust when the width changes? Needs to work in all modern browsers.
The div ist still centered. Just the text is aligned left.
Try this:
<div id="content" style="margin-left:auto;margin-right:auto;width:240px;border:1px solid red;text-align:center">
<p>Click here</p>
$('p').click(function(){$("#content").width(480)})
-
http://jsfiddle.net/nvzaw/1/
I have posted an answer to a similar problem (about window resize) here
Maybe this helps you!