I have an iframe from the middle to bottom on a page. When I load the page it scrolls to the bottom. I tried to body onload window.scroll(0,0) but it does an ugly effect because it first goes down and then immediately scrolls up.
What's the cause of this automatic scroll to bottom with iframe on the page?
This is just a random one, but possible doing something like this:
<iframe style="display: none;" onload="this.style.display='block';" src="..."></iframe>
The thinking being that if it is some focus stealing script on a remote page that you can't control, the browser won't focus a hidden element. And there's a good likelihood that your onload will fire after their focus changing script.
Or, one other option that might be a bit more reliable:
<iframe style="position: absolute; top: -9999em; visibility: hidden;" onload="this.style.position='static'; this.style.visibility='visible';" src="..."></iframe>
Here we're basically saying hiding the frame and moving it to a negative offset on the page vertically. When it does try to focus the element inside of the frame, it should scroll the page upward, then once loaded place the iframe back in it's intended position.
Of course, without knowing more, it's hard to say for sure which tradeoffs are okay, and both of these options have conditions that are a tad racy, so YMMV.
I hope that helps :)
I came up with a "hack" that works well. Use this if you don't want your webpage to be scrolled to anywhere except the top:
// prevent scrollTo() from jumping to iframes
var originalScrollTo = window.scrollTo;
window.scrollTo = function scrollTo (x, y) {
if (y === 0) {
originalScrollTo.call(this, x, y);
}
}
If you want to disable autoscrolling completely, just redefine the function to a no-op:
window.scrollTo = function () {};
Similar method but using classes.. I added a class to the iFrame's parent div of "iframe_display" with a style inside that of visibility: hidden. On page load I then used jQuery to remove the class
.iframe_display{visibility:hidden}
$(function(){
$('#iframe_wrapper').removeClass('iframe_display');
});
This takes the focus away from the iFrame and stops the scrolling down to the iFrame on page load
Simple. Use about:blank in src like
<iframe id="idName" name="idName" src="about:blank" style="display:none"></iframe>
The src="about:blank" trick provided by Leandro & edited by Spokey worked for me, but I'd like to share a workaround I was using before.
A temporary solution I found was to embed the iframe in the uppermost element on my page (nav, header etc), so that even if the browser wants to jump to focus, it 'jumps' to the top element. This still can cause a slightly perceptible jump, which might bug you.
To make sure the iframe remains hidden if you choose to place it near the top of a page, I applied an inline style of style="visibility:hidden; height: 0px; width: 0px;". I guess you could also use a z-index combo.
This seems to work well:
<iframe src="http://iframe-source.com" onLoad="self.scrollTo(0,0)"></iframe>
This is the solution I came up with and tested in Chrome.
We have an iframe wrapped by a div element. To keep it short, I have removed the class names related to sizing the iframe. Here, the point is onMyFrameLoad function will be called when iframe is loaded completely.
<div class="...">
<iframe onload="onMyFrameLoad()" class="..." src="..."></iframe>
</div>
Then in your js file, you need this;
function noscroll() {
window.scrollTo(0, 0);
}
// add listener to disable scroll
window.addEventListener('scroll', noscroll);
function onMyFrameLoad() {
setTimeout(function () {
// Remove the scroll disabling listener (to enable scrolling again)
window.removeEventListener('scroll', noscroll);
}, 1000);
}
This way, all the scroll events become ineffective till iframe is loaded.
After iframe is loaded, we wait 1 sec to make sure all the scroll events (from iframe) are nullified/consumed.
This is not an ideal way to solve your problem if your iframe source is slow. Then you have to wait longer by increasing the waiting time in setTimeout function.
I got the initial concept from https://davidwells.io/snippets/disable-scrolling-with-javascript/
Related
I want a jQuery function that removes the vertical scrollbar until the page has fully loaded but it doesn't seem to be working. Any insight on the problem would be great. Thanks!
$(window).on('load', function () {
$('body').addClass('stop-scrolling');
$('body').removeClass('stop-scrolling');
});
.stop-scrolling {
height: 100%;
overflow: hidden;
}
The issue here is that your JS doesn't run until after the page has finished loading. This means the scroll bar is visible the entire time the page is loading. Then, once the page loads, you add the stop scrolling class and then, milliseconds later, you remove it again. The net result of this is that nothing appears to happen.
To achieve what you need, put the .stop-scrolling class directly in the HTML source of your page on the <body> element and then only remove it in the window.load event handler.
My problem is very similar to this one except the thing that fixed element may change his height dynamically during application lifecycle (other data, viewport change, etc... ).
I'm using setInterval() function with 100ms interval to update offset of content element depending on header height.
jQuery(function($){
setInterval(function(){
$('article').css('padding-top', $('header').outerHeight());
}, 100)
});
Here is jsfiddle for it (change the width of the resulted page to see how it works).
For user experience it looks just great, but I'm curious is there a better way?
What are the disadvantages of this approach?
The major disadvantage is that you consume CPU every 100ms. And it doesn't do anything most of the time.
There is a better way. Just emit an event after the fixed element changes height and bind your css adjusment to it. Something like:
$(document).trigger('my_element_changed_height');
wherever the height changes and
$(document).on('my_element_changed_height', function() {
$('article').css('padding-top', $('header').outerHeight());
});
I suppose you can use jquery.ba-resize.js library. Here is a link: http://benalman.com/projects/jquery-resize-plugin
It allows you to use resize event on any DOM element. But if I'm not mistaken this library uses setTimeout functionality and I'm not sure that's better in performance.
UPDATE: time goes and web evolve, position: sticky
header{
position: sticky;
}
Old Answer:
Here is another solution that comes to my head. I was thinking how would be great have such position : fixed-relative :) (That fixed on viewport but doesn't desapear from normal flow) And here is an idea how to emulate this behaviour. Set header element position as relative.
header{
position: relative;
}
And add some listner to scroll event.
jQuery(function($){
$(window).scroll(function(){
$('header').css('top',$(this).scrollTop() );
});
});
It's much pretty than have infinity loop with setInterval or trigger some event across your application.
Unfortunately it will not work on most touch devices
I have my html page with a iframe, and when I put the mouse on the iframe and I use the mouse scroll button it will scroll the iframe page and I don't want that to happen. But I don't want the scroll to be totaly disable in this iframe because I have a fresque and I must be abble to zoom in with the scroll
How could I do ?
I have try to do scrollTo(0, 0); but it does it on the real page and not on the iframe.
You can try to use the mousewheel event to cancel the scroll.
Example code:
window.onload=function(){
setTimeout(function(){ //just to be sure that the document exists
document.onmousewheel=function(event){
event.preventDefault();
//add here your code to zoom
};
},300);
};
Notice that IE8 will always "internally" use event.preventDefault(); and the scroll won't work if you want to use a flag to enable/disable the scroll.
You can read more information here: http://www.quirksmode.org/dom/events/scroll.html
This is my old solution:
The question isn't specific enough, but I think I understood it.
Here is a piece of jQuery to fix what I understood:
(function($){
$(function(){
$(window).click(function(event){
if(event.which==3) //middle button
{
event.preventDefault();
//remaining code for the zoom(?)
}
});
});
})(jQuery);
This should disable using the scroll wheel to scroll the page (doesn't work on touch).
You can include the code for the zooming(?) inside the if block.
Include this code inside the iframe!
Try using the scrolling="no" option, as in
<iframe scrolling="no" src="http://www.google.com" width="400px" height="300"></iframe>
Assuming: "I want to disable the scroll of the page without disabeling the scroll (in the iframe)"
First, this CSS will turn off scrollbars on the page ...
<style type="text/css">
html, body {
overflow: hidden;
}
</style>
... and, this will disable scrolling anytime it is tried ...
$(window).scroll(function() {
scroll(0,0);
});
... although, this might be a better option ...
document.body.scroll = "no";
document.body.style.overflow = 'hidden';
document.height = window.innerHeight;
I'm trying to achieve a page with a certain number of divs, each of which has a bookmark (a name). The problem is, when I jump to one of the bookmarks, part of the text is gone, caused by the design. I'd like to know if there's a way to change the behaviour of the bookmark, so it won't set the start of it at the top of the page, but a set number of pixels below.
The page can be accessed here: Not longer online, sorry.
The behaviour occurs when you go to any of the bookmarks (except #6, because the document ends there), like on here: Not longer online, sorry.
Can this be solved by a css property or any other way? (update) I'd prefer this over a javascript solution because I'm planning to use javascript to tab them, and keep the bookmarks in case of disabled javascript
You can do it with JavaScript using scrollBy. Put this in a load listener or onload handler:
if(window.location.hash.length > 1) {
window.scrollBy(0, -60); // Adjust to suit your needs.
}
window.onhashchange = window.onload = function () {
if( window.location.hash.length && window.scrollY > window.pageYOffset ) {
window.scrollBy( 0, -100 ); // Scroll up 100 pixels on hash change
};
};
I got the answer myself, so this is basically for references.
To ignore the 100px offset that is caused by the header, I added a padding-top of 100px to each single div element, and then I changed the links to go to the div's instead of the a elements I added. This padding-top basically makes the text appear where it should and thus solved my problem.
I've got a page with a header and a content.
The header has position: fixed; height: 200px, the content is below.
In the header I have a link <a href="#work" ...> . In the content there is a <div id="work">. When I click the link, the browser scrolls to the work div - the problem is half of the content is covered (remains underneath) the header, because it has position fixed!
I then used the jQuery anchorAnimate plugin, that uses jQuery animate. Here I slightly modified the plugin to take into account that 200px-offset. This worked out fine, in Chrome and Safari.
Not in Firefox, however. The plugin works ok, slides to the correct position, until it calls window.location.hash = element. Firefox then falls back to the default behaviour of setting the element at the top of the page (thus ignoring the offset due to the header - the first problem I described).
I know Firefox 3.6 implements an onhashchange listener. I overrode as per the documentation window.onhashchange = function(){}, which it does call, but it keeps on firing the default action of setting the elements at the top of the window, ignoring my header. How can I fix this?
(Otherwise, would it be possible to set somewhere a window offset in these "fixed header" cases?)
If you can't find a way to prevent Firefox's ohhashchange behavior, then your best best is to approach the problem in a different way. A couple of suggestions:
Modify anchorAnimate to never set window.location.hash (comment out line 34). The problem with that is that the url will never be changed, and users won't be able to bookmark or copy a url which directly points to that div.
Write your own code (or modify anchorAnimate) to do something like this:
var currentScroll = $('html, body').scrollTop();
window.location.hash = 'myAnchor';
$('html, body').scrollTop(currentScroll)
.animate({ scrollTop: destination - 200 });
That will set the anchor, but immediately scroll you back to where the browser was previously. From there you can animate to any desired scroll position.
I checked in Firefox (and am pretty sure for other browers) that the user will not see a flash of scroll changes.