I have a div with it's own scroll bar which is being reloaded by AJAX (php file). When I scroll inside this div and reload it, the inner scrollbar gets sent back to the top. I would like for the scroll bar to remain at the position where I originally scrolled to.
<style>
#div2 {
height: 400px;
width: 100%;
overflow-y:scroll;
}
</style>
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript">
setInterval(function () {
$('#div1').load('shownic8.php');
},7000);
</script>
<div id="div1">
</div>
Here is the code from "shownic8.php" file
<div id="div2">
...
</div>
Can you help me keep the position of my scroll bar? Thank you very much.
Check https://api.jquery.com/scrolltop/
Before .load() store current scroll position:
var pos = $('#your-container').scrollTop();
Use .load() callback (http://api.jquery.com/load/) to restore scroll position:
$('#your-container').scrollTop(pos);
Using your code:
setInterval(function () {
var scrollTarget = $('#div1');
var pos = scrollTarget.scrollTop();
scrollTarget.load('shownic8.php', function() {
$('#div1').scrollTop(pos);
});
},7000);
You can either use DOM element's scrollTop property or jQuery function of the same name.
But I don't advice you to do so because saving and restoring scroll position you couldn't avoid a slight blinking effect every time you reload contents.
So, instead, I would recommend to update items that actually change instead of reloading the whole contents, so the scrollTop property gets never changed.
Of course, (to do it the right way) it implies modifying your shownic8.php page (or implementing another different route instead) to return some structured data and use them to fill or update your div contents.
On the other hand, you can try another, slightly dirty, approach to hide that blinking efect (replacing it by a less obvious side effect). That is:
Instead of loading your contents directly into #div1 element, create a new div inside it (appending through .append() or .appendTo()) and load into it.
After that (at least in reloading operations), remove previous contents so that new content climbs up to the top position (and not altering scroll position).
Example: (untested)
setInterval(function () {
var prevContents = $("#div1>*");
$('<div></div>')
.load('shownic8.php')
.appendTo('#div1')
;
prevContents.remove();
},7000);
Related
I'm trying to fix an element when I scroll down.
The code works fine but as you can see at the following link, the bar with the 3 yellow buttons jumps when it is about to reach the Top!
There seems to be some template css class causing this problem,
but I can't figure out which one
This is the code
var fixmeTop = $('.pulsanti').offset().top;
$(window).scroll(function() {
var currentScroll = $(window).scrollTop();
if (currentScroll >= fixmeTop) {
$('.pulsanti').css({
position: 'fixed',
top: '0',
zIndex: '1020'
});
} else {
$('.pulsanti').css({
position: 'relative'
});
}
});
thank you everyone
I think the problem is that fixmeTop is assigned before some elements are loaded:
var fixmeTop = $('.pulsanti').offset().top;
My chrome console outputs this:
> fixmeTop
< 2314.3374633789062
> $('.pulsanti').offset().top;
< 3207.5623779296875
You can see that the fixmeTop variable is not the real element position.
Maybe you need to assign it in body.onload()?
Update
After executing fixmeTop = $('.pulsanti').offset().top; in the chrome console after the page is loaded, I can verify that the element is sticking smoothly to the top of the page.
Adding this code fragment will create a handler function to be called when the window's load event fires. That will happen after everything (divs, images) is loaded. This way the fixmeTop will contain the true element position.
window.onload = function () {
fixmeTop = $('.pulsanti').offset().top;
}
You can keep the variable declaration in the original script, or remove it and add var here.
Also, bear in mind that it will not work until everything on the page is loaded and that it will not be valid when anything on the page moves - eg. page resize, divs rearranged. You would have to add listeners for every such event to adjust the value accordingly. Something like this may be useful:
function updateFixmeTop() {
fixmeTop = $('.pulsanti').offset().top;
}
window.addEventListener("resize", updateFixmeTop);
edit: changed element body to window in event listener
Hope it helps!
Update2
Let's say you added the code for resize event listener and scrolled past the point where the element should stick to the top. If you were to resize window fixmeTop would be assigned a value that corresponds to the element being on top of the page, and not the original element position.
To fix this you may want to add a dummy element without any margin or padding:
<div id="elementJustBeforeFixmeTop"></div> <! -- dummy element -->
<div class="pulsanti"> <! -- sticky element -->
...
</div>
And refer to its position instead of the sticky element
fixmeTop = $('#elementJustBeforeFixmeTop').offset().top;
This way you will store the scroll position at which you want the element to stick and it will not be different if the element is already at the top.
You may want to check if your page doesn't change its layout somewhere else and also update the fixmeTop value there to ensure it's always pointing at the right element.
So I am using jQuery to position the footer absolutely on pages where there isnt much content.
The problem I have noticed is that the footer loads in it's normally position and then visibily jumps to the bottom of the page when the jQuery adds the class. Is there anyway to get around this jump?
/* Position footer bottom of all pages */
positionFooter: function () {
var windowHeight = jQuery(window).height();
var content = jQuery("#content").height() + jQuery("#footer-wrapper").height();
if (windowHeight > content){
jQuery("#content").css("padding-bottom", jQuery("#footer-wrapper").height());
jQuery("#footer-wrapper").addClass("fixed-bottom");
}
}
I am using window.load:
jQuery(window).load(function()
How about this
positionFooter: function ()
{
var windowHeight = jQuery(window).height();
var content = jQuery("#content").height() + jQuery("#footer-wrapper").height();
jQuery("#footer-wrapper").addClass("fixed-bottom");
jQuery("#footer-wrapper").hide();
if (windowHeight > content)
{
jQuery("#content").css("padding-bottom", jQuery("#footer-wrapper").height());
jQuery("#footer-wrapper").show();
}
}
If you can change the html, maybe you should use a css sticky footer
http://ryanfait.com/sticky-footer/
I've used this in a lot of websites and works just fine
A quick dirty fix would be to give the body { opacity: 0} before the document loads, and then animate the opacity back up to 1 over a period of, say, 1 second. That way, the whole body will fade in after the footer has already jumped.
simple fiddle
This is how a lot of people deal with Flashes Of Unstyled Content (or FOUC).
Edit: As Freeeeez pointed out below, using body as the animatee isn't necessary, but in my opinion the effect is pleasing :)
If you set it to display:none as default with a specific class. You could then use jQuery to remove the class after the document has finished loading with something like this:
$(document).ready(function(){
$('.hideMe').removeClass('hideMe');
});
I'm displaying some images on a webpage and I want it to be scrolled all the way to the bottom as soon as the page loads, then fade the image in. This is what my code looks like thus far:
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
$(document).ready(function(){
// fade in initial image
$("#lower").fadeIn(3000);
$("#lower").css("display", "block;");
// show only initial image at mid-page
var margin = ( $(window).height() - $("#lower").height() ) * (0.5);
$("#lower").css("margin-top", margin);
// set scroll position to bottom of page
$(document).scrollTop( $(document).height() );
});
</script>
and my html looks like this:
<body>
<div id="view">
<img id="upper" src="pages/2.gif">
<img id="lower" src="pages/1.gif">
</div>
</body>
(#upper has opacity 0 and I plan to fade it in later, when the user scrolls up to the image)
the problem I'm having is that the page doesn't scroll all the way to the bottom on load. Ive tried a number of things including changing the selector for the .scrollTop function to body and/ or html tag as well as document or window. I even tried overshooting the scrollTop value excessively but to no avail.
Can anyone tell me me why The page is not scrolling all the way to the bottom upon load?
[EDIT]
Sorry sorry, sloppy code. Finals week and little sleep. Heres a no-typo version of the same thing with the same problem. I even overshot the scrollTop parameter here, but the result is the same.
An observation: scroll location persists after refresh. Could this have anything to do with the obstinate scroll position here?
You have a typo here:
var margin = ($(window).hieght() - $("#lower").height())/2;
//----------------------^^^^^^^---a spelling typo
which should be:
var margin = ($(window).height() - $("#lower").height())/2;
Because of this the script execution stops and it never goes to the line where you have done the scrollTop. so all in all it gets stopped at an error and does not go further for execution.
Also i want to add that this is not a correct way of doing:
$("#lower").attr("style", "display: block;")
instead you can use .css() method:
$("#lower").css("display", "block");
or with simple .show(), fadeIn(), .toggle('show') etc. too.
This is how I call it
document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
document.addEventListener('DOMContentLoaded', function () { setTimeout(loaded, 200); }, false);
/**/
$(document).ready(function() {
//Created an array for adding n iScroll objects
var myScroll = new Array();
$('.content').each(function(){
if($(this).attr('id')==null){
$(this).attr('id') = $(this).attr('class');
}
id = $(this).attr('id');
console.log(id);
$(this).html('<div class="scroller">'+$(this).html()+'</div>');
myScroll.push(new iScroll(id));
});
});
I modified it a little bit so you can use it with a class and not only id.
It seems to work (to be enabled) because I can drag the container and its content (but it wont keep position, it will restore on mouse release)
If you want to see it happening please visit http://toniweb.us/grano and click on any item in the menu, the new shown has the effect.
Any idea why it is working but not as expected?
The reason I want to do this is because the container has several subcontainers that will be hidden or shown depending on the content selection.
CSS:
#nvl1{
padding:0px 25px;
z-index:10;
position:absolute;
left:0px;
background:url("../img/fondoNivel2.jpg") no-repeat scroll right 0 #79797B ;
height:100%;
}
#nvl1 .content{
width:650px;
z-index:11;
display:none;
color:#6666b6b;
position:relative;
line-height:30px;
}
I had a look at your code on: http://toniweb.us/grano
I think what you would like to do is use iScroll on your class with "scrolling". That is not what you are doing in the following code but instead you are actually setting iScroll to use the parent of your scroller DIV:
id = $(this).attr('id');
$(this).html('<div class="scroller">'+$(this).html()+'</div>');
myScroll.push(new iScroll(id));
For reference: iScroll uses an ID rather than a class
The effect this is having is that it is causing the "snap" effect on the immediately following block level element - your scroller DIV.
Consider this example where there is a DIV (id="scroller") containing an OL which contains a number of (block level) LIs:
http://cubiq.org/dropbox/iscroll4/examples/simple/
Long story short, give your DIV with the scroller class an id and create your iScroll from that instead.
if you set the style on the div tag you put the scroller on to (example)
style="position:relative;overflow: hidden;height:350px;
i think it's setting the height explicitly that should solve the dragging problem
Don't you just want:
.content {overflow-y:scroll;}
Is that not what you're saying mate?
The elements within the scroll div can't be floating. If they are floating and not cleared the flow of the page will mean your scrolling div is not the correct height. Try avoiding any floats within your scrolling and div and see how that goes. This was the problem for me.
I also found Matthews answer to be helpful as I was also calling iscroll on the wrong div. I think the confusing thing about the iScroll example is that it's easy to assume iScroll is called on the div with the ID scroller, but it's called on the wrapper div. The div with the ID scroller doesn't actually need an ID and I think for the examples sake this would be clearer without that. e.g.
<div id="wrapper">
<div>
<p>Whatever you want here</p>
<ul>
<li>1</li>
</ul>
</div>
</div>
...
myScroll = new iScroll('wrapper');
This question already has answers here:
How can I make a div stick to the top of the screen once it's been scrolled to?
(22 answers)
Closed 10 years ago.
I have a div which, when my page is first loaded, is about 100px from the top (it holds some buttons etc. for the page).
When a user scrolls past it, I would like the div to "follow" the user in that it attaches to the top of the screen. When the user returns to the top of the page, I want it back in its original position.
Visualization - xxxxx is the div:
Default (page load) User vertically scrolled well past it
--------- ---------
| | |xxxxxxx| < after div reaches top of screen when
|xxxxxxx| | | page is scrolled vertically, it stays
| | | | there
--------- ---------
The trick is that you have to set it as position:fixed, but only after the user has scrolled past it.
This is done with something like this, attaching a handler to the window.scroll event
// Cache selectors outside callback for performance.
var $window = $(window),
$stickyEl = $('#the-sticky-div'),
elTop = $stickyEl.offset().top;
$window.scroll(function() {
$stickyEl.toggleClass('sticky', $window.scrollTop() > elTop);
});
This simply adds a sticky CSS class when the page has scrolled past it, and removes the class when it's back up.
And the CSS class looks like this
#the-sticky-div.sticky {
position: fixed;
top: 0;
}
EDIT- Modified code to cache jQuery objects, faster now.
The trick to make infinity's answer work without the flickering is to put the scroll-check on another div then the one you want to have fixed.
Derived from the code viixii.com uses I ended up using this:
function sticky_relocate() {
var window_top = $(window).scrollTop();
var div_top = $('#sticky-anchor').offset().top;
if (window_top > div_top)
$('#sticky-element').addClass('sticky');
else
$('#sticky-element').removeClass('sticky');
}
$(function() {
$(window).scroll(sticky_relocate);
sticky_relocate();
});
This way the function is only called once the sticky-anchor is reached and thus won't be removing and adding the '.sticky' class on every scroll event.
Now it adds the sticky class when the sticky-anchor reaches the top and removes it once the sticky-anchor return into view.
Just place an empty div with a class acting like an anchor just above the element you want to have fixed.
Like so:
<div id="sticky-anchor"></div>
<div id="sticky-element">Your sticky content</div>
All credit for the code goes to viixii.com
There was a previous question today (no answers) that gave a good example of this functionality. You can check the relevant source code for specifics (search for "toolbar"), but basically they use a combination of webdestroya's solution and a bit of JavaScript:
Page loads and element is position: static
On scroll, the position is measured, and if the element is position: static and it's off the page then the element is flipped to position: fixed.
I'd recommend checking the aforementioned source code though, because they do handle some "gotchas" that you might not immediately think of, such as adjusting scroll position when clicking on anchor links.
Use position:fixed; and set the top:0;left:0;right:0;height:100px; and you should be able to have it "stick" to the top of the page.
<div style="position:fixed;top:0;left:0;right:0;height:100px;">Some buttons</div>