Iframe loading spinner/progress bar using javascript - javascript

I have an iframe which is referencing a Google Sheets tab, and its quite slow loading. I'm looking to have a spinner graphic or loader % progress bar (even more ideal) whilst the iframe is loading. Would you know an approach for this using Javascript and/or CSS please?

No need to use jquery for this. If you would like to use an actual progress bar, you'd have to use ajax to load the content.
function closeIndicator(){
var s = document.getElementById('spinner');
console.log(s);
s.style.display = "none";
}
#spinner{
z-index:99999;
position:absolute;
top: 0;
left: 0;
}
<iframe id="documentIFrame" onload="closeIndicator()" src="https://stackoverflow.com/" >
</iframe>
<img id="spinner" src="spinnder.gif" />

If jQuery is an option. -> Not perfectly styled but I hope you get the idea.
$('#myIframe').on('load', function(){
$('#loader').fadeOut();
});
iframe {
height:500px;
width:500px;
}
#loader {
position:absolute;
height:500px;
width:500px;
background:#000;
margin-top:-500px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<iframe src="https://www.brotherops.com" id="myIframe"></iframe>
<div id="loader"><img src="https://i.giphy.com/media/FaAxdPWZ7HKGmlnku7/giphy.webp" alt="Loading" /></div>

Related

I'm having a problem including the position of an image within a conditional

The problem is in the snippet that begins with the "mouseup' event. I'm trying to get the alert to show when I drag and drop a .tile image, snapping it onto the .amherst div. The image snaps onto the div, but no alert shows.
I'm a real beginner programming in Javascript/jQuery. I did not know how to include the position() function in a conditional, but found examples on the web--but I'm still not sure that I've got that part of it right. And I'm not sure about the use of 'this' here.
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
.container{
position:relative;
}
.tampa{
position:absolute;
top:418px;
left:907px;
width:250;
}
.tile{
width:47px;
height:47px;
}
#tile0{
position:absolute;
top:590px;
left:328px;
}
#tileH{
position:absolute;
top:590px;
left:375px;
}
#tileF{
position:absolute;
top:590px;
left:422px;
}
#tileR{
position:absolute;
top:590px;
left:469px;
}
.img{
width:100%;
height:auto;
}
.amherst{
position:absolute;
top:417px;
left:827px;
}
</style>
<script src="jQ/jQuery.js"></script>
<script src="jQ/jquery-ui-1.12.1/jquery-ui.js"></script>
<script>
$("document").ready(function(){
$('.tile').mouseup(function(){
if ($(this).position().top==417 &&
$(this).position().left==827){
alert("Hello");
}
});
$('.tampa').click(function(){
if ($('.tampa').attr('src')== 'GamePremiseOff.jpg'){
$('.tampa').attr('src', 'GameConclusionOff.jpg');
} else if ($('.tampa').attr('src')== 'GameConclusionOff.jpg'){
$('.tampa').attr('src', 'GamePremiseOff.jpg');
}
});
$('#tile0').draggable({snap:".amherst"});
$('#tileH').draggable({snap:".amherst"});
$('#tileF').draggable({snap:".amherst"});
$('#tileR').draggable({snap:".amherst"});
});
</script>
</head>
<body>
<div class="amherst"></div>
<div class="container">
<img src='GameboardCompleteDemo.jpg' width='1620' height='740'>
<img class='tampa' src='GamePremiseOff.jpg'>
<img id='tile0' class='tile' src='GameTile0.jpg'>
<img id='tileH' class='tile' src='GameTileH.jpg'>
<img id='tileF' class='tile' src='GameTileF.jpg'>
<img id='tileR' class='tile' src='GameTileR.jpg'>
</div>
</body>
</html>
I wanted the alert to show, but it doesn't, and I get no error messages
Your $('.tile').mouseup (with that very strict positioning), is very likely to never call an alert.
If you want to, you need to call it after draggable has finished, meaning either callbacks or jQuery stop event like in this the demo: http://www.tutorialspark.com/jqueryUI/jQuery_UI_Draggable_Start_Stop_Events.php . Try writing the alert in the stop function, like so:
stop: function() {
alert('hi')
}

Load Iframe with spinner

This code loads correctly the spinner, but how do I hide it after loading completes?
iframe {
background-image: url("http://jimpunk.net/Loading/wp-content/uploads/loading2.gif");
background-repeat: no-repeat;
background-position: 50% 50%;
}
As an alternative solution, you can do this as well:
<div id="spinner">
<div>
<img src="http://www.ajaxload.info/images/exemples/25.gif" />
</div>
</div>
<iframe border=0 name=iframe src="http://www.w3schools.com" width="950" height="633" scrolling="no" noresize frameborder="0" onload="document.getElementById('spinner').style.display='none';"></iframe>
Style the position of the spinner absolute to the page container to center it appropriatedly
Try jQuery:
$( document ).ready(function() {
$( "iframe .load" ).hide();
});
and create a second css-class for the loading-action:
.load{
background-image: url("http://jimpunk.net/Loading/wp-content/uploads/loading2.gif");
background-repeat: no-repeat;
background-position: 50% 50%;
position: absolute;
width:100%;
height:100%;
}
iframe{
position:relative;
}
Let me know if it works.
Here it is, using font-awesome and jQuery:
$(document).ready(function () {
showSpinnerWhileIFrameLoads();
});
function showSpinnerWhileIFrameLoads() {
var iframe = $('iframe');
if (iframe.length) {
$(iframe).before('<div id=\'spinner\'><i class=\'fa fa-spinner fa-spin fa-3x fa-fw\'></i></div>');
$(iframe).on('load', function() {
document.getElementById('spinner').style.display='none';
});
}
}
You could listen to when the iframe is loaded, and then put a class on the iframe, setting background image to nothing.
iframe.onload = function() {
// remove spinner
};
Sorry for the short answer, but I'm on a phone atm :)
I just wanted to add that another way to do this without Javascript is to have the spinner appear behind the iframe, and give the iframe an initially transparent background; so long as the iframe's content has a background colour it will cover the spinner once it loads.
This is a great way to do this if your iframe is "single-use", i.e- it loads embedded content only once and contains no clickable links, or if you don't care about displaying the spinner once the initial content has loaded.*
There are two easy ways to do this:
CSS Background
HTML:
<div class="iframe_container">
<iframe src="http://example.org"></iframe>
</div>
CSS:
.iframe_container {
background-image: url('path/to/spinner.gif');
background-position: center;
background-repeat: no-repeat;
}
.iframe_container iframe {
background: transparent;
}
Basically the spinner is a background for .image_container, positioned in the center, and visible because the iframe's background is initially transparent. When the iframe content loads it covers the image, even if an error occurs.
Z-Index
HTML:
<div class="iframe_container">
<img class="spinner" src="path/to/spinner.gif" />
<iframe src="http://www.example.org"></iframe>
</div>
CSS:
.iframe_container {
position: relative;
}
.iframe_container .spinner {
position: absolute;
top: 50%;
left: 50%;
}
.iframe_container iframe {
background: transparent;
z-index: 1;
}
In this case we have our spinner embedded as a specific element (which you may need to do for Bootstrap spinners and such), which is positioned using CSS. The iframe in this case covers the image because it has been given a z-index (you may need to use a higher number, if other elements with z-indexes) but the trick is essentially the same.
Notes
As long as it doesn't bother you that the spinner is still technically in the background this works great for a single page-load iframe, or when you only care about the first load.
This is also a good trick to use if you want your site to support users with Javascript disabled, as they won't be left with a spinner that won't disappear.
*If you want to re-use a spinner via Javascript you can still do-so using the z-index option, by setting the spinner's z-index to be higher than the iframe's, like so:
var e = getElementById('my_iframe');
e.onload = function() {
var e = getElementById('my_spinner');
e.style.zIndex = 0;
}
e.onunload = function() {
var e = getElementById('my_spinner');
e.style.zIndex = 100;
}
This works by pushing the spinner above the iframe when unloading (source is changed) and behind it again on load (new content is visible).
You can use jquery on load
$('#showFrame').on("load", function () {
console.log('iframe loaded completely'); //replace with code to hide loader
});
================================================================
=========================2022 Answer==========================
Iframes have a onLoad attribute that you can set to a function
In react you could do something as such:
const spinner = async () => {
document.getElementById('spinner').style.display = 'none';
}
Rendered in a Modal as such:
<div
id="spinner"
style={{
backgroundColor: '#ECECFE',
borderRadius: '8px',
padding: '20px',
}}
>
<Loading
spinnerColor="#2E7DAF"
text="Loading...."
/>
</div>
<iframe id="iframeid" src="" width="650px" height="650px" onLoad={spinner} ></iframe>
</div >

Jquery make Youtube video stop playing when clicking outside popup

I have this Jquery popup where I store an iframe with a youtube video. When I click the link, the popup opens and the User can click on the video and play it. Even though, when I click outside the popup, the popup closes, but the video/sound keeps playing! How can I avoid this?
Here's my HTML
CLICK
<div class="bg" style="display:none"></div>
<div class="popup" style="display:none">
<iframe width="480" height="360" src="//www.youtube.com/embed/Q_WHGV5bejk" frameborder="0" allowfullscreen></iframe>
</div>
my JS:
$(function(){
$("#showPopup").click(function(e){
e.stopPropagation();
$(".bg").toggle();
$(".popup").toggle();
});
$("body").click(function(){
$(".bg").toggle();
$(".popup").hide();
});
});
And the CSS:
.popup{
background-color:#E6E9F2;
position:absolute;
min-height:auto;
width:auto;
border: solid 2px #B9EAF0;
z-index: 1002;
}
.bg {
background-color:#111;
opacity: 0.65;
position:absolute;
z-index: 1000;
top:0px;
left:0px;
width:100%;
min-height:100%;
overflow:auto;
}
I alos created a Fiddle http://jsfiddle.net/nLBZa/6/
so, does anyone have a suggestion?
thanks in advance...
Try adding the following into your Jquery
$('#playerID').get(0).stopVideo();
EDIT:
OK, so I thought that would work according to the API, anyways... Here is another solution:
var video = $("#player").attr("src");
$("#player").attr("src","");
$("#player").attr("src",video);
and your fiddle updated.
Assume, I have several different YT videos embedded in CSS only modals, like this:
<div id="video1" class="modalDialog">
<div>
X
<div id="video1_content"><iframe width="420" class="yvideo" id="video1_iframe" height="315" src="https://www.youtube.com/embed/_Qc4V_vEXdY?rel=0&showinfo=0&enablejsapi=1" frameborder="0" allowfullscreen></iframe></div>
</div>
I can dynamically unload (and therefor stop playing) a single video like so:
$('.videoclose').click(function( e ){
var contentdiv = $(this).next('div');
var iframe = $(contentdiv).find('iframe:first');
var video = $(iframe).attr("src");
$(iframe).attr("src","");
$(iframe).attr("src",video);
});
Thanks to Mike for the ignition ;-)

Determine HTML element position change

EDIT: See update!
I have the following html:
<body>
<span id="milestone1">
</span>
<img id="image1" src="blabla.jpeg" style="width:400px;height:200px;" />
<div id="divOverlayOverImage1" style="position:absolute; top:100px; left:40px; width:400px;height:200px;" onclick="DoFunkyStuff();"><div>
</body>
At first the divOverlayOverImage1 is positioned over Image1, covering it, but if I run the code below, the #divOverlayOverImage1 element will no longer covering the #image1 element.
$("#milestone1").after('<div style="width:500px; height:500px; background-color:blue;">');
I want to have an event that notifies me when #image1 changes its position, so I can update the position of #divOverlayOverImage1.
NOTE: I do not have full control over the dom. the $("#milestone1").after('<div style="width:500px; height:500px; background-color:blue;">'); command is run by a third party.
UPDATE: I do not have full control of the DOM, so I cannt put a callback to the element add function, as it is not me making this call.
Also, I cannot modify HTML like crazy. I just come to a set of websites, append and overlay to a specific image throung JavaScript and that's it. There are other competitiors that change the HTML as well.
If you have full control over the DOM, and I assume you have, you can add a call to every change you make in the DOM that will affect that <span>.
function yourFunction() {
$("#milestone1").after('<div style="width:500px; height:500px; background-color:blue;">');
updateMyOverlayPosition();
}
if that doesnt work, you might try this one here: Detect changes in the DOM
edit
if you want events:
$('#image').on('adjustOverlay',function(e) {
// adjust the position of the overlay
}
$("#milestone1").after('<div style="width:500px; height:500px; background-color:blue;">');
$('#image').trigger('adjustOverlay', {extra: "info", some: "parameters"});
edit2
Since you don't have full control over changes in the DOM and you can get surprised you can either go with the link I already provided above or check in an interval if the overlay is still where it needs to be. This doesn't solve the problem in the way you want it, but there is no native event on DOM-changes, so you have to stick with some sort of work-around.
var checkTime = 100; //100 ms interval
var check = setInterval(function() {
// adjust overlay position
}, checkTime);
edit3
next possible solution: if you know how affecting code is inserted in the DOM, you can try to change that method so that it always runs your adjustOverlayPosition() or fires an event, if you like events. Example: if it is inserted with jQuery's .after() you can modify that function:
jQuery.fn.extend({
// since the .after() function already exists, this will
// actually overwrite the original function. Therefore you need
// the exact code that was originally used to recreate it.
after: function() {
return this.domManip( arguments, function( elem ) {
if ( this.parentNode ) {
this.parentNode.insertBefore( elem, this.nextSibling );
}
// call the function directly
adjustOverlayPosition();
// or call an event
$('#image').trigger('adjustOverlay', {extra: "info", some: "parameters"});
}
});
Drawback: this solution can be risky and works only if you know the code that is used originally. So it would also depend on the jQuery version.
One workaround is to reorganize your layout.
Wrap your image and overlay into a div. That way they will always remain that way.
<div id="wrap">
<img id="i1" src="..." />
<div id="overlay" />
</div>
#wrap {
position: relative;
width: 400px;
height: 200px;
}
#overlay {
position: absolute;
top: 100px;
left: 40px;
width: 400px;
height: 200px;
}
If wrapping the img with a ovelay is only your requirement, I think you can go with a pure css Solution:
Try the demo
HTML
<p id="milestone1">
First Overlay
</p>
<div class="img-overlay-container" style="width:400px;height:200px;">
<img id="image1" src="blabla.jpeg"/>
<div id="overlay1" onclick="alert('clicked');">
</div>
</div>
<p id="milestone2">
Second Overlay
</p>
<div class="img-overlay-container" style="width:100px;height:400px;">
<img id="image2" src="blabla.jpeg"/>
<div id="overlay2" onclick="alert('clicked');">
</div>
</div>
CSS
.img-overlay-container{
position: relative;
display:inline-block;
}
.img-overlay-container > img{
}
.img-overlay-container > div{
position:absolute;
top:0px;
left:0px;
width:100%;
height:100%;
background: rgba(3,3,3,.1);
}
function changePosition(callback) {
$("#milestone1").after('<div style="width:500px; height:500px; background-color:blue;">');
callback();
}
Then you can call changePosition(function() {// Add your event handler function}).
Hope this will help you!

How to display loading message when an iFrame is loading?

I have an iframe that loads a third party website which is extremely slow to load.
Is there a way I can display a loading message while that iframe loads the user doesn't see a large blank space?
PS. Note that the iframe is for a third party website so I can't modify / inject anything on their page.
I have done the following css approach:
<div class="holds-the-iframe"><iframe here></iframe></div>
.holds-the-iframe {
background:url(../images/loader.gif) center center no-repeat;
}
I think that this code is going to help:
JS:
$('#foo').ready(function () {
$('#loadingMessage').css('display', 'none');
});
$('#foo').load(function () {
$('#loadingMessage').css('display', 'none');
});
HTML:
<iframe src="http://google.com/" id="foo"></iframe>
<div id="loadingMessage">Loading...</div>
CSS:
#loadingMessage {
width: 100%;
height: 100%;
z-index: 1000;
background: #ccc;
top: 0px;
left: 0px;
position: absolute;
}
If it's only a placeholder you are trying to achieve: a crazy approach is to inject text as an svg-background. It allows for some flexbility, and from what I've read the browser support should be fairly decent (haven't tested it though):
Chrome >= 27
FireFox >= 30
Internet Explorer >= 9
Safari >= 5.1
html:
<iframe class="iframe-placeholder" src=""></iframe>
css:
.iframe-placeholder
{
background: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 100% 100%"><text fill="%23FF0000" x="50%" y="50%" font-family="\'Lucida Grande\', sans-serif" font-size="24" text-anchor="middle">PLACEHOLDER</text></svg>') 0px 0px no-repeat;
}
What can you change?
Inside the background-value:
font size: look for font-size="" and change the value to anything you want
font color: look for fill="". Don't forget to replace the # with %23 if you're using hexadecimal color notation. %23 stands for a # in URL encoding which is necessary for the svg-string to be able to be parsed in FireFox.
font family: look for font-family="" remember to escape the single quotes if you have a font that consists of multiple words (like with \'Lucida Grande\')
text: look for the element value of the text-element where you see the PLACEHOLDER string. You can replace the PLACEHOLDER string with anything that is url-compliant (special characters need to be converted to percent notation)
Example on fiddle
Pros:
No extra HTML-elements
No js
Text can easily (...) be adjusted without the need of an external program
It's SVG, so you can easily put any SVG you want in there.
Cons:
Browser support
It's complex
It's hacky
If the iframe-src doesn't have a background set, the placeholder will shine through (which is not inherent to this method, but just standard behaviour when you use a bg on the iframe)
I would only recommend this only if it's absolutely necessary to show text as a placeholder in an iframe which requires a little bit of flexbility (multiple languages, ...). Just take a moment and reflect on it: is all this really necessary? If I had a choice, I'd go for #Christina's method
An alternative solution.
<iframe srcdoc="Loading..." onload="this.removeAttribute('srcdoc')" src="https://example.com"></iframe>
Note that srcdoc attribute can have any HTML markup. So you can apply custom styles to the message.
<iframe id="example" src="https://example.com"></iframe>
<script>
const iframe = document.getElementById('example');
iframe.srcdoc = '<!DOCTYPE html><p style="color: green;">Loading...</p>';
iframe.addEventListener('load', () => iframe.removeAttribute('srcdoc'));
</script>
Here's a quick solution for most of the cases:
CSS:
.iframe-loading {
background:url(/img/loading.gif) center center no-repeat;
}
You can use an animated loading GIF if you want to,
HTML:
<div class="iframe-loading">
<iframe src="http://your_iframe_url_goes_here" onload="$('.iframe-loading').css('background-image', 'none');"></iframe>
</div>
Using the onload event you can remove the loading image after the source page is loaded inside your iframe.
If you are not using jQuery, just put an id into the div and replace this part of code:
$('.iframe-loading').css('background-image', 'none');
by something like this:
document.getElementById("myDivName").style.backgroundImage = "none";
All the best!
$('iframe').load(function(){
$(".loading").remove();
alert("iframe is done loading")
}).show();
<iframe src="http://www.google.com" style="display:none;" width="600" height="300"/>
<div class="loading" style="width:600px;height:300px;">iframe loading</div>
Yes, you could use a transparent div positioned over the iframe area, with a loader gif as only background.
Then you can attach an onload event to the iframe:
$(document).ready(function() {
$("iframe#id").load(function() {
$("#loader-id").hide();
});
});
You can use below code .
iframe {background:url(../images/loader.gif) center center no-repeat; height: 100%;}
I have followed the following approach
First, add sibling div
$('<div class="loading"></div>').insertBefore("#Iframe");
and then when the iframe completed loading
$("#Iframe").load(function(){
$(this).siblings(".loading-fetching-content").remove();
});
<!DOCTYPE html>
<html>
<head>
<title>jQuery Demo - IFRAME Loader</title>
<style>
#frameWrap {
position:relative;
height: 360px;
width: 640px;
border: 1px solid #777777;
background:#f0f0f0;
box-shadow:0px 0px 10px #777777;
}
#iframe1 {
height: 360px;
width: 640px;
margin:0;
padding:0;
border:0;
}
#loader1 {
position:absolute;
left:40%;
top:35%;
border-radius:20px;
padding:25px;
border:1px solid #777777;
background:#ffffff;
box-shadow:0px 0px 10px #777777;
}
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
</head>
<body>
<div id="frameWrap">
<img id="loader1" src="loading.gif" width="36" height="36" alt="loading gif"/>
<iframe id="iframe1" src="https://bots.actcorp.in/ACTAppChat/chat?authtext=test#user8.com&authToken=69d1afc8d06fb97bdb5a9275edbc53b375c3c7662c88b78239ba0cd8a940d59e" ></iframe>
</div>
<script>
$(document).ready(function () {
$('#iframe1').on('load', function () {
$('#loader1').hide();
});
});
</script>
</body>
</html>
You can use as below
$('#showFrame').on("load", function () {
loader.hide();
});

Categories