I've got a page I'm coding, and it's supposed to run this Javascript on every page load. The problem is, it seems to load completely randomly. Sometimes it runs, sometimes it just doesn't. Every reload seems totally random on whether it will work or not. This is very frustrating as I can't imagine it's an issue with the code at this point.
function randombg() {
var random = Math.floor(Math.random() * 6) + 0;
var bigSize = ["url('http://lh4.googleusercontent.com/-dsFg9OnYo5Q/T0hK7b0-xoI/AAAAAAAABL4/9_CPzXBCMfw/s800/animated%2520blue%2520stars.gif')",
"url('https://background-tiles.com/overview/blue/patterns/large/1026.gif')",
"url('https://78.media.tumblr.com/395d407e0762d7041cbe0197e3ea288c/tumblr_o3fxwiIAq61v8fqfeo1_540.gif')",
"url('http://backgroundcheckall.com/wp-content/uploads/2017/12/seamless-repeating-background-gif-12.gif')",
"url('https://other00.deviantart.net/b3aa/o/2009/312/0/8/143009517_95116_animated_starfield_tile.gif')",
"url('http://backgroundcheckall.com/wp-content/uploads/2017/12/seamless-repeating-background-gif-10.gif')"
];
document.getElementById("random").style.backgroundImage = bigSize[random];
alert("Success");
}
window.onload = randombg;
window.onresize = randombg;
#random {
width: 100%;
height: 450px;
border: 1px solid black;
background-image: url('http://placehold.it/300&text=banner1');
background-position: center center;
background-size: cover;
background-repeat: no-repeat;
}
<body onload="randombg">
<div id="random"></div>
<body>
This is taken from this pen, which works flawlessly. So I'm very confused as to why it's not working consistently for me.
I'm running Chrome (67.0.3396.99) in Windows 10 (1803), and this code is being run in the extension Super Evil New Tab, which has a section for HTML, CSS, and JS.
Thank you for any feedback or advice.
EDIT: I forgot to mention that the extension seems to just stick the HTML into a body.
The simplest, non-library-dependent way to fix inconsistent JavaScript initialization execution is to change <body onload="randombg"> to just <body> and insert your JavaScript before your script tag like so:
<script src="path/to/your/js/file/here.js"></script>
<body>
<div id="random"></div>
</body>
And then in your JavaScript file, instead of using window.onload = ..., do:
// This method of attaching a function to a DOM event allows for more flexibility down the line.
window.addEventListener('load', randombg);
window.addEventListener('resize', randombg);
If you use this addEventListener way, if you choose to do more than just randombg on load and resize events, you could just do
window.addEventListener('load', () => {
randombg();
// more code to perform on load here...
});
window.addEventListener('resize', () => {
randombg();
// more code to perform on window resize here...
});
I've got a minor problem I'm trying to resolve on my website. I have it currently so that a loading screen div appears above the page when the user visits and then fades away after a set time/the page is loaded, whichever comes latest. I want this div only to appear on first visit and would prefer to avoid cookies or anything server side. From what I understand I want to utilize session storage or referrer but have not had success with implementing that. Also, subsequent pages have a less prominent and faster loading screen that will have to go away only when each individual page has been visited once during the session. The applicable code is:
css:
.js div#preloader {
position: fixed;
left: 0;
top: 0;
z-index: 1000;
width: 100%;
height: 100%;
overflow: visible;
background-color: #202020;}
#preloader {
z-index: 1000; }
js:
jQuery(document).ready(function ($) {
$(window).load(function () {
setTimeout(function(){
$('#preloader').fadeOut(1500, function () {
});
},5000);
});
});
So it's likely obvious that I'm not well informed; I'm teaching myself as I go and needless to say I have a lot to learn about javascript. If I've done something horribly wrong here, which is entirely plausible, or a working demo is required, please let me know.
Thanks!
You can probably accomplish what you want using the sessionStorage object. In that object, you can track which pages have been visited in the current session.
The issue you can run into with JavaScript (and the reason I said it may not be the best approach) is that, when using a library, there is always a finite amount of time that passes while the library is loaded, parsed, and executed. This makes your "only appear on the first visit" requirement somewhat difficult to accomplish in JavaScript. If you show it by default and hide it with library code, it will show briefly each time you go to the page. If you hide it by default and show it with library code, it will be briefly hidden the first time you go to the page.
One way to handle this is to use embedded JavaScript that is executed immediately after the DOM for the preloader is defined. The downside to this is that you have to know how to write cross-browser JavaScript without assistance from a library like jQuery. In your case, the JavaScript required to simply hide the preloader is simple enough that it shouldn't have any cross-browser issues.
I created a simple page that demonstrates the technique. The source for this page is:
<html>
<head>
<style>
#preloader {
position: fixed;
left: 0;
top: 0;
z-index: 1000;
width: 100%;
height: 100%;
overflow: visible;
color: white;
background-color: #202020;
}
</style>
</head>
<body>
<div id="preloader">Preloader</div>
<script>
if (sessionStorage[location.href]) {
document.getElementById('preloader').style.display = 'none';
}
sessionStorage[location.href] = true;
</script>
<p>This is the text of the body</p>
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<script>
$(function () {
setTimeout(function(){
$('#preloader').fadeOut(1500);
}, 5000);
});
</script>
</body>
</html>
I also created a fiddle for it: http://jsfiddle.net/cdvhvwmm/
I'm facing an issue with the scrollTo function when the body has an dir=rtl attribute. here is a jsfiddle for my case.
HTML:
window.scrollTo(-200, 0);
<html>
<head>
</head>
<body dir="rtl">
<div width="100%" style="width: 3000px; height:200px; overflow: hidden">
<div style="width: 1000px; height: 100px; border: 2px solid black; display: inline-block"></div>
<div style="width: 1000px; height: 100px; border: 2px solid red; display: inline-block"></div>
</div>
<script type="text/javascript">
window.scrollTo(-200, 0);
</script>
</body>
</html>
So if I pass a positive value for the xpos parameter, it works on IE (sort of) naturally, it scrolls from the right side of the screen for an amount of 200px. but on chrome and firefox it doesn't work, I have to pass a negative value for the scrolling to work as expected.
My question, is how I can handle this case in my code, should I do browser sniffing? or is there a better way? some feature I can test if its supported?
as othree explains in his jQuery rtl scroll type plugin there are 3 main implementations for horizontal scrolling when dir is set to rtl: WebKit, Firefox/Opera and IE
the difference between these implementations is as follows:
because you can't use jQuery I've modified othree code in this plunker and it works fine in chrome, firefox and IE11
This snippet worked for me on IE and Chrome
http://jsfiddle.net/05w4tr0g/4/
var m = -1;
var pos = window.pageXOffset;
window.scrollTo(0,0);
window.scrollTo(1, 0);
if (-1 == window.pageXOffset) m = 1;
window.scrollTo(pos, 0);
window.scrollTo(m*200, 0);
Hope that helps. The idea is that that the pageXOffset is with IE and Chrome always negative if there was scrolling. The snippet will cause a little flicker because of the test scroll to x=0 and x=-1.
You could store the m value on a page load and reuse it in a wrapper function for scrollTo (or scrollBy for that matter). You could also overload the two methods and keep it all in the window context.
I've got a simple setup to allow a "help"-style window to be loaded and scrolled to a particular point on the page. More or less the code looks like this:
var target = /* code */;
target.offsetParent().scrollTop(target.offset().top - fudgeValue);
The target of the scroll and the fudge value are determined by a couple of hints dropped on the page, and I'm having no problems with that part of this mechanism anywhere. In Firefox and IE8, the above code works exactly like I want: the scrolled box (in this case, the page body) correctly scrolls the contained stuff to the right point in the window when it's told to do so.
In Chrome and Safari, however, the call to scrollTop() apparently does nothing at all. All the numbers are OK, and the target refers to the right thing (and the offsetParent() is indeed the body element), but nothing at all happens. As far as I can tell from googling around, this is supposed to work. Is there something funny about the renderer under Safari and Chrome?
This is jQuery 1.3.2 if that matters.
Test page: http://gutfullofbeer.net/scrolltop.html
I was having this problem in Safari and Chrome (Mac) and discovered that .scrollTop would work on $("body") but not $("html, body"), FF and IE however works the other way round. A simple browser detect fixes the issue:
if($.browser.safari)
bodyelem = $("body")
else
bodyelem = $("html,body")
bodyelem.scrollTop(100)
The jQuery browser value for Chrome is Safari, so you only need to do a detect on that.
Hope this helps someone.
Yeah, there appears to be a bug in Chrome when it comes to modifying the body, trying to make it into an offsetParent. As a work-around, I suggest you simply add another div to wrap the #content div, and make that scroll:
html, body { height: 100%; padding: 0; }
html { width: 100%; background-color: #222; overflow: hidden; margin: 0; }
body
{
width: 40em; margin: 0px auto; /* narrow center column layout */
background-color: white;
position: relative; /* allow positioning children relative to this element */
}
#scrollContainer /* wraps #content, scrolls */
{
overflow: auto; /* scroll! */
position:absolute; /* make offsetParent */
top: 0; height: 100%; width: 100%; /* fill parent */
}
#header
{
position: absolute;
top: 0px; height: 50px; width: 38.5em;
background-color: white;
z-index: 1; /* sit above #content in final layout */
}
#content { padding: 5px 14px 50px 5px; }
Tested in FF 3.5.5, Chrome 3.0.195.33, IE8
Live demonstration:
$(function() {
$('#header').find('button').click(function(ev) {
var button = $(this), target = $('div.' + button.attr('class'));
var scroll = target.offsetParent().scrollTop();
target.offsetParent().scrollTop(target.offset().top + scroll - 50);
});
});
html, body { height: 100%; padding: 0; }
html { width: 100%; background-color: #222; overflow: hidden; margin: 0; }
body { width: 40em; margin: 0px auto; background-color: white; position: relative; }
#scrollContainer { overflow: auto; position:absolute; top: 0; height: 100%; width: 100%; }
#header { position: absolute; top: 0px; height: 50px; width: 38.5em; background-color: white; z-index: 1; }
#content { padding: 5px 14px 50px 5px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id='header'>
Header Box
<button class='A'>A</button>
<button class='B'>B</button>
<button class='C'>C</button>
</div>
<div id='scrollContainer'>
<div id='content'>
<div style='height: 50px'> </div>
<div class='A'>
<h1>A</h1>
<p>My name is Boffer Bings. I was born of honest parents in one of the humbler walks of life, my father being a manufacturer of dog-oil and my mother having a small studio in the shadow of the village church, where she disposed of unwelcome babes. In my boyhood I was trained to habits of industry; I not only assisted my father in procuring dogs for his vats, but was frequently employed by my mother to carry away the debris of her work in the studio. In performance of this duty I sometimes had need of all my natural intelligence for all the law officers of the vicinity were opposed to my mother's business. They were not elected on an opposition ticket, and the matter had never been made a political issue; it just happened so. My father's business of making dog-oil was, naturally, less unpopular, though the owners of missing dogs sometimes regarded him with suspicion, which was reflected, to some extent, upon me. My father had, as silent partners, all the physicians of the town, who seldom wrote a prescription which did not contain what they were pleased to designate as _Ol. can._ It is really the most valuable medicine ever discovered. But most persons are unwilling to make personal sacrifices for the afflicted, and it was evident that many of the fattest dogs in town had been forbidden to play with me--a fact which pained my young sensibilities, and at one time came near driving me to become a pirate.
</div>
<div class='B'>
<h1>B</h1>
<p>
Looking back upon those days, I cannot but regret, at times, that by indirectly bringing my beloved parents to their death I was the author of misfortunes profoundly affecting my future.
<p>
One evening while passing my father's oil factory with the body of a foundling from my mother's studio I saw a constable who seemed to be closely watching my movements. Young as I was, I had learned that a constable's acts, of whatever apparent character, are prompted by the most reprehensible motives, and I avoided him by dodging into the oilery by a side door which happened to stand ajar. I locked it at once and was alone with my dead. My father had retired for the night. The only light in the place came from the furnace, which glowed a deep, rich crimson under one of the vats, casting ruddy reflections on the walls. Within the cauldron the oil still rolled in indolent ebullition, occasionally pushing to the surface a piece of dog. Seating myself to wait for the constable to go away, I held the naked body of the foundling in my lap and tenderly stroked its short, silken hair. Ah, how beautiful it was! Even at that early age I was passionately fond of children, and as I looked upon this cherub I could almost find it in my heart to wish that the small, red wound upon its breast--the work of my dear mother--had not been mortal.
</div>
<div class='C'>
<h1>C</h1>
<p>It had been my custom to throw the babes into the river which nature had thoughtfully provided for the purpose, but that night I did not dare to leave the oilery for fear of the constable. "After all," I said to myself, "it cannot greatly matter if I put it into this cauldron. My father will never know the bones from those of a puppy, and the few deaths which may result from administering another kind of oil for the incomparable _ol. can._ are not important in a population which increases so rapidly." In short, I took the first step in crime and brought myself untold sorrow by casting the babe into the cauldron.
</div>
<div style='height: 75em;'> </div>
</div>
</div>
$("body,html,document").scrollTop($("#map_canvas").position().top);
This works for Chrome 7, IE6, IE7, IE8, IE9, FF 3.6 and Safari 5.
2012 UPDATE
This is still good but I had to use it again. Sometimes position doesn't work so this is an alternative:
$("body,html,document").scrollTop($("#map_canvas").offset().top);
The browser support status is this:
IE8, Firefox, Opera: $("html")
Chrome, Safari: $("body")
So this works:
bodyelem = $.browser.safari ? $("body") : $("html") ;
bodyelem.animate( {scrollTop: 0}, 500 );
For the scroll : 'html' or 'body' for setter (depend on browser)... 'window' for getter...
A jsFiddle for testing is here : http://jsfiddle.net/molokoloco/uCrLa/
var $window = $(window), // Set in cache, intensive use !
$document = $(document),
$body = $('body'),
scrollElement = 'html, body',
$scrollElement = $();
var isAnimated = false;
// Find scrollElement
// Inspired by http://www.zachstronaut.com/posts/2009/01/18/jquery-smooth-scroll-bugs.html
$(scrollElement).each(function(i) {
// 'html, body' for setter... window for getter...
var initScrollTop = parseInt($(this).scrollTop(), 10);
$(this).scrollTop(initScrollTop + 1);
if ($window.scrollTop() == initScrollTop + 1) {
scrollElement = this.nodeName.toLowerCase(); // html OR body
return false; // Break
}
});
$scrollElement = $(scrollElement);
// UTILITIES...
var getHash = function() {
return window.location.hash || '';
},
setHash = function(hash) {
if (hash && getHash() != hash) window.location.hash = hash;
},
getWinWidth = function() {
return $window.width();
},
// iphone ? ((window.innerWidth && window.innerWidth > 0) ? window.innerWidth : $window.width());
getWinHeight = function() {
return $window.height();
},
// iphone ? ((window.innerHeight && window.innerHeight > 0) ? window.innerHeight : $window.height());
getPageWidth = function() {
return $document.width();
},
getPageHeight = function() {
return $document.height();
},
getScrollTop = function() {
return parseInt($scrollElement.scrollTop() || $window.scrollTop(), 10);
},
setScrollTop = function(y) {
$scrollElement.stop(true, false).scrollTop(y);
},
myScrollTo = function(y, newAnchror) { // Call page scrolling to a value (like native window.scrollBy(x, y)) // Can be flooded
isAnimated = true; // kill waypoint AUTO hash
var duration = 360 + (Math.abs(y - getScrollTop()) * 0.42); // Duration depend on distance...
if (duration > 2222) duration = 0; // Instant go !! ^^
$scrollElement.stop(true, false).animate({
scrollTop: y
}, {
duration: duration,
complete: function() { // Listenner of scroll finish...
if (newAnchror) setHash(newAnchror); // If new anchor
isAnimated = false;
}
});
},
goToScreen = function(dir) { // Scroll viewport page by paginette // 1, -1 or factor
var winH = parseInt((getWinHeight() * 0.75) * dir); // 75% de la hauteur visible comme unite
myScrollTo(getScrollTop() + winH);
};
myScrollTo((getPageHeight() / 2), 'iamAMiddleAnchor');
There is a bug in Chrome (not in Safari at the time we checked) that gives unexpected results in Javascript's various width and height measurements when opening tabs in the background (bug details here) - we logged the bug in June and it's remained unresolved since.
It's possible you've encountered the bug in what you're attempting to do.
setTimeout(function() {
$("body,html,document").scrollTop( $('body').height() );
}, 100);
This probably should work even if time is 10ms.
how about
var top = $('html').scrollTop() || $('body').scrollTop();
Works for Safari, Firefox, and IE7 (haven't tried IE8). Simple test:
<button onclick='$("body,html").scrollTop(0);'> Top </button>
<button onclick='$("body,html").scrollTop(100);'> Middle </button>
<button onclick='$("body,html").scrollTop(250);'> Bottom </button>
Most examples use either one or both, but in reverse order (i.e., "html,body").
Cheers.
(And semantic purists out there, don't bust my chops -- I've been looking for this for weeks, this is a simple example, that validates XHTML strict. Feel free to create 27 layers of abstraction and event binding bloat for your OCD peace of mind. Just please give due credit, since the folks in the jQuery forums, SO, and the G couldn't cough up the goods. Peace out.)
Which element is the offsetParent of another is not well-specified and may vary across browsers. It is not guaranteed to the be the scrollable parent you are looking for.
The body itself also shouldn't be the page's main scrollable element. It only is in Quirks Mode, which in general you would want to avoid.
The offsetTop/offsetLeft/offsetParent measurements aren't terribly useful by themselves, they're only really reliable when you use them in a loop to get the total page-relative co-ordinates (as position() in jQuery does). You should know which is the element you want to scroll and find out the difference in page co-ordinates between that and the descendant target to find out how much to scroll it by.
Or if it's always the page itself you're talking about scrolling, just use a location.href= '#'+target.id navigation instead.
This appears to be working in FF and WebKit; IE not tested so far.
$(document).scrollTop();
It worked for me, just leave it to the jQuery.
$("html,body").animate({ scrollTop: 0 }, 1);
Basically you should know the browser and write the code considering browser differences. Since jQuery is cross-browser it should handle the first step. And finally you fake the js-engine of the browser by animating the scrolling in 1 millisecond.
There is not a big choice of elements that might get auto-assigned with a scrollTop value as we scroll a webpage.
So I wrote this little function to iterate through the probable elements and return the one we seek.
var grab=function (){
var el=$();
$('body#my_body, html, document').each(function(){
if ($(this).scrollTop()>0) {
el= ($(this));
return false;
}
})
return el;
}
//alert(grab().scrollTop());
In Google chrome it would get us the body, in IE - HTML.
(Note, we don't need to set overflow:auto explicitly on our html or body that way.)
I was facing this problem, I created this link at the bottom and implemented the jQuery scrollTop code and it worked perfectly in Firefox, IE, Opera but didn't work in Chrome and Safari. I'm learning jQuery so I don't know if this solution is technically perfect but this worked for me. I just implemented 2 ScrollTop codes the first one uses $('html') which works for Firefox, etc. The second one uses $('html body') this works for Chrome and Safari.
$('a#top').click(function() {
$('html').animate({scrollTop: 0}, 'slow');
return false;
$('html body').animate({scrollTop: 0}, 'slow');
return false;
});
Indeed, seems like animation is required to make it work in Safari. I ended up with:
if($.browser.safari)
bodyelem = $("body");
else
bodyelem = $("html,body");
bodyelem.animate({scrollTop:0},{queue:false, duration:100, easing:"linear", complete:callbackFunc});
I am not sure if this is the case:
I was using Google's CDN for jQuery i.e.
Putting "https:" before //ajax.google.......
worked, it seems Safari recognized it as a local path (checked it by - Inspect Element)
Sorry, only tested in Safari 7.0.3 :(
I my case, the button was working for two of 8 links. My solution was
$("body,html,document").animate({scrollTop:$("#myLocation").offset().top},2500);
This created a nice scroll effect as well
To summarise solutions from a couple of questions/answers:
If you want to get the current scroll offset use:
$(document).scrollTop()
To set the scroll offset use:
$('html,body').scrollTop(x)
To animate the scroll use use:
$('html,body').animate({scrollTop: x});
It's not really a bug, just a difference in implantation by the browser vendors.
As a rule avoid browser sniffing. There is a nifty jQuery fix which is hinted at in the answers.
This is what works for me: $('html:not(:animated),body:not(:animated)').scrollTop()