have <iframe> work asynchronously - javascript

Is there a good article or how can have an iframe or frame work asynchronously with every page? I have a bottom/fixed div wrapped in jquery to slide up on hover containing an mp3 player. I referenced the player with an iframe. I renderes fine, but how can it keep playing without a reload on page refresh or navigation to another page? I want it to be fixed at the bottom of every page and play continuously without refresh. I tried putting the iframe in each page, but that still didn't work. Any ideas? Thank you.

If it must stay in the browser ( not downloading an application or read stream in a music/video player ), the only way should be to don't really change page, and load content that must change with ajax or javascript ( or have it itself in a (i)frame ).
But it would be a lot easier to do a page with only the lector and put a link on your website to open it in another tab :
Text or what you want
Edit :
So with javascript it would be the same result than ajax, but that means not changing page so for the SEO if it's somewhat important it's not good.
What I meant by javascript was for example if you click on link "home" just adding dynamically a <script type="text/javascript" src="/homepage.js"></script> wich modify content of the page ( while keeping the mp3 player ).
Otherway, maybe with a cookie if it's possible with the player to know by javascript :
at know to wich mp3 file the player is
at wich time in the mp3 playing the player is
to go at a specified mp3 file
to go at a specified time in an mp3
(and if it is possible to pause the player, there should to be the ability to know if the player is playing or not )
It would be possible when changing page to get at the good time ( but there will be the time to load the page and mp3 player without music ).
Or there could be mp3 player which can save a the time at wich we are, and begin at this time on another page ( but still while changing page no sound for several seconds ).
With these methods there would be too the issue of opening several pages.
Edit :
I tried the way with the content of the page in iframe, it works rather well but needs the membre to switch in the mp3 mode.
Here is mp3.html ( to put in root folder, if it's not possible it would need some changes ) :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>MP3 Player</title>
<style type="text/css">
html {
font-size: 100%;
}
body {
margin: 0;
padding: 0em;
}
#frame { width: 100%; height: 100%; border: none; }
#player { position: absolute; right: 20px; bottom: 20px; }
</style>
<script type="text/javascript">
if ("onhashchange" in window) {
var h='';
var command= false;
window.onhashchange = function(){
if(location.hash==h) return;
command= true;
window.frames['frame'].location.replace(location.hash.replace(/^#/,""));
h= window.location.hash;
}
}
</script>
</head>
<body>
<iframe id="frame" onLoad="if(this.src=='')return;if(command)command=!1;else window.location.replace(h='#'+window.frames['frame'].location.href.replace(new RegExp('^'+document.location.origin),''));document.title=window.frames['frame'].document.title;"></iframe>
<script type="text/javascript">
document.getElementById("frame").src=document.location.hash.replace(/^#/,"");
</script>
<div id="player">
<object type="application/x-shockwave-flash" data="http://s301826463.onlinehome.fr/so/dewplayer.swf?mp3=http://s301826463.onlinehome.fr/so/Tokyo.mp3" width="200" height="20" id="dewplayer"><param name="wmode" value="transparent"><param name="movie" value="http://s301826463.onlinehome.fr/so/dewplayer.swf?mp3=http://s301826463.onlinehome.fr/so/Tokyo.mp3"></object>
remove mp3 player
</div>
</body>
</html>
And to put a link that open the current page in an iframe and with an mp3 player, it only needs a link :
add mp3 player
An example using that here.

Either you have an independent Flash/Java/Unity etc player outside the browser window.
Or, You use frames, two frames, one where the main site pages appear, and one where the player resides.
Other way is making the entire navigation in your site (where you want the player to be continuous) using async calls (Ajax).
Google b.t.w uses iframes/frames

Related

Chrome 75 - setting iFrame src attribute causes iFrame parent to load the iFrame content

Chrome v75 appears to have introduced a bug whereby if you replace an iFrame's src programatically, it will replace the entire page instead of the iFrame.
This didn't happen on v74 and I can't get a test case to work (yet), it just fails in our site. (The site hasn't changed since going from v74 to v75, only Chrome has changed)
It appears to work fine the first time but then when you change it again (in our case viewing report drill downs) it causes the entire page (i.e. the iFrame's Parent) to load the src you were trying to load into the iFrame.
It also doesn't matter if you use pure Javascript or (in our case) JQuery, both cause the same issue.
EDIT: After a few hours detective work, I've found the bug. Setting the tag in the iFrame's content causes Chrome to load the iFrame's content into it's parent rather than the iFrame itself.
I've setup a Plunker account with a demo: https://plnkr.co/edit/UQ0gBY?plnkr=legacy&p=info
Just so I can post the link to Plunker, here is the code for the main file & the iframe content
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
function onLoaded() {
// find element
let button = document.getElementById("button");
button.addEventListener("click",function(e){
// Add a random number on the end as a cache buster
document.getElementById('frame-finance-custom').src = 'test2.html?rnd=' + Math.random();
},false);
};
document.addEventListener('DOMContentLoaded', onLoaded, false);
</script>
</head>
<body>
<div>IFrame Src Changing Test</div>
<div>
<div id="div-frame-finance-custom" style="float:left;width:33%">
<iframe id="frame-finance-custom" name="frame-finance-custom" class="iframe"
style="border:1px solid black; width: 100%; height: 350px; overflow-y: scroll; vertical-align: top;">
no data
</iframe>
</div>
<div style="float:left;margin-left:1em;">
Detail: Loading an iframe page with a <Base> tag in it with target set to "_parent" will cause any refresh of that frame to replace the parent document<BR>
<BR>Instruction: <UL><LI>Click the 'Update Frame' Button, this will load test2.html into the frame. <LI>Click it again & it will replace the iframe's parent with the content of the iFrame.</UL>
<BR>Confirmation: Remove the <Base> tag from the header of test2.html & reload, it will work as expected.
</div>
</div>
<br clear=both>
<div>
<button id="button">
Update Frame
</button>
</div>
</body>
</html>
IFrame Content (test2.html):
<!DOCTYPE html>
<html lang="en">
<head>
<base target="_parent"/>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>This is the frame content</div>
</body>
</html>
Note, using their new layout it doesn't work, but using their legacy layout it does. Feel free to save the files locally and use chrome directly too.
Ok, so this turned out to be a bug in Chrome rather than anything else, so yes, strictly not a SO question, but seeing as SO ranks so well in Google (other search engines are available), I thought it better to leave it here as a solution rather than simply delete it, just incase anyone else has a similar problem.
The reason is outlined as an edit in my question, the solution is to remove the <base target="_parent"> tag from the iFrame and programatically add the 'target="_parent"' attribute to any links in the iFrame.
We do this via jQuery, I'm sure its just as easy via vanilla Javascript.
$('a').attr('target','_parent');
Add that to the javascript that runs when a page has loaded and it'll replace add target="_parent" to any links on the page.
e.g.
<script>
function onLoaded() {
// find all links and add the target attribute
$('a').attr('target','_parent');
};
document.addEventListener('DOMContentLoaded', onLoaded, false);
</script>
As #Kaiido says in his comment, its apparently fixed in Chrome v77, but this isn't the current (as of June 2019) stable release, so we've had to add the workaround into production so that our CRM works with Chrome v75. Thanks to #Kaiido for confirming that.

SCORM Course in Iframe can't find API

(I'm new to SCORM and Web Development, pardon me if I do not explain something too well.)
I'm trying to run some SCORM courses and have been following this tutorial to do so: http://www.vsscorm.net/2009/05/31/getting-started-the-rte-frameset/
However, in this tutorial they use a frameset and frames to establish this connection from the course to the API implementation. I need to run my course in an iframe, and do not know where/how to place my API document so my SCORM course can find it and connect to it, does anybody know how?
In a typical SCORM course, the API connection is maintained in the parent frame while the course content is loaded into a child frame (iframe). The content in the iframe can be loaded and unloaded at will; the content in the iframe will tend to contain the important SCORM calls you'd want to make through the lifespan of a course, such as score and completion status, but they will do so by relaying the info to the parent frame, which owns the communication with the LMS.
Here's quick example using SCORM 1.2 (not tested in an LMS, barebones, would need to be fleshed out)
index.html (parent frame)
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Course Title</title>
<style>
/* Use CSS to make the iframe fill the parent frame,
giving impression no frames are being used */
body { padding: 0; margin: 0; overflow: hidden; }
iframe { position: absolute; top: 0; right: 0; bottom: 0; left: 0; overflow: auto; }
</style>
</head>
<body>
<iframe src="" id="course-content" frameborder="0"></iframe>
<script>
//Place initialization routine here.
//Connect to SCORM API, run API.LMSInitialize()
var SCORM_API = window.API; //shortcut reference
function setScore(score){
SCORM_API.LMSSetValue("cmi.core.score.raw", score);
}
function setStatus(status){
SCORM_API.LMSSetValue("cmi.core.lesson_status", status);
}
function endCourse(){
SCORM_API.LMSCommit();//Save, just in case
SCORM_API.LMSFinish();//Close API connection
}
SCORM_API.LMSInitialize();
//Load child frame once SCORM_API is ready
document.getElementById("course-content").setAttribute("src", "content.html");
</script>
</body>
</html>
content.html (child frame)
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Course Content</title>
</head>
<body>
<p>This is the content of the course. Add scripts to make it do something.</p>
<script>
//Place course functionality here, such as setting a bookmark or score.
//'parent' is the parent frame.
//This is a very arbitrary example of what you can do when a course loads
parent.setScore("100");
parent.setStatus("completed");
parent.endCourse();
</script>
</body>
</html>
You'd typically want to use a SCORM wrapper to handle some of the heavy lifting, and you'd want to use an abstraction layer to improve code maintainability and centralize your SCORM commands in the parent frame. The endCourse() function is a very simple example of an abstraction layer. Instead of invoking the API directly in the child frame, you invoke a function.

Wistia background video

I'm trying to replicate this: http://wistia.com/blog/fullscreen-video-homepage
on my site, but even working with just the base demo that they give, is running me into issues. If I simply download the sample from that page and open the video, it works fine, but if I do anything as seemingly simple as swapping the background video with the foreground video, it breaks, let alone replacing those videos with my own videos (which is my eventual goal with all of this).
Here's what I'm doing.
Replacing this in the javascript:
overlayVideo: 'fji9juvptr',
overlayVideoDiv: '#wistia_fji9juvptr',
backgroundvideo: 'z1ggfo8f86',
backgroundideoDiv: '#wistia_z1ggfo8f86'
with this:
overlayVideo: 'z1ggfo8f86',
overlayVideoDiv: '#wistia_z1ggfo8f86',
backgroundvideo: 'fji9juvptr',
backgroundideoDiv: '#wistia_fji9juvptr',
and replacing this in the HTML:
<div id="wistia_z1ggfo8f86" class="wistia_embed backgroundVideo" style="width:920px;height:518px;"></div>
<div id="wistia_fji9juvptr" class="wistia_embed overlayVideo" style="width:1920px;height:1080px;"></div>
with this:
<div id="wistia_fji9juvptr" class="wistia_embed backgroundVideo" style="width:920px;height:518px;"></div>
<div id="wistia_z1ggfo8f86" class="wistia_embed overlayVideo" style="width:1920px;height:1080px;"></div>
And that's enough to break it. My guess is that something about the two videos is different that causes the z1ggfo8f86 video to work as the background but not the fji9juvptr video, but I can't tell what that difference is.
I also tried just changing the names of the divs (I changed the "a" in "wistia" to an "o"), but that also broke it so I assume those div names are processed somehow by Wistia.
Any ideas on what I'm missing?
I never wanted an overlay video or buttons or any of that garbage - all I wanted was the background video - I simplified this code so it makes better sense - just change the wistiaVideoID in the javascript object and make sure the id="wistia_q4bmpyxfll" on the DIV in the HTML matches it which is important. Also change the settings for that wistia video on their website so there is no sound, autoplay, and loop...
<!doctype html>
<html lang="en">
<head>
<style>
body {
margin: 0;
padding: 0;
}
#video_container {
width: 100%;
height: 100%;
overflow: hidden;
position: relative;
z-index: 1;
opacity: 1;
}
</style>
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<div id="video_container">
<div id="wistia_q4bmpyxfll"></div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script charset='ISO-8859-1' src='https://fast.wistia.com/assets/external/E-v1.js'></script>
<script charset='ISO-8859-1' src='https://fast.wistia.com/labs/crop-fill/plugin.js'></script>
<script type="text/javascript">
var fullScreenVideo = {
wistiaVideoID: 'q4bmpyxfll',
embedVideo: function(){
var videoOptions = {};
Wistia.obj.merge(videoOptions, {plugin: {cropFill: {src: "//fast.wistia.com/labs/crop-fill/plugin.js"}}});
wistiaEmbed = Wistia.embed(this.wistiaVideoID, videoOptions);
},
fixTextPosition: function(){
var width = $(window).width();
var height = $(window).height();
$("#video_container").css("width", width).css("height", height);
}
};
$(document).ready(function() {
fullScreenVideo.fixTextPosition();
});
$(window).resize(fullScreenVideo.fixTextPosition);
fullScreenVideo.embedVideo();
</script>
</body>
</html>
Are your videos the same aspect ratio as the ones in the Tutorial?
To double check, in Wistia, follow these steps on the video content page where you found your video ID.
Video Actions > Embed & Share >
Choose any of the embed options and inspect the code for "height" and "" values, and update your style values for #backgroundVideo and #overlayVideo
I ended up figuring this out.
Of the two videos they use in the Tutorial, the Background one had configured (in Wistia) auto-play and loop, whereas the overlay video (for good reason) did not. Swapping them thus broke auto-play, and since the background video has no way to make it play, it'd just appear to not work at all (and the overlay video would auto-play when the page was loaded, so you'd hear it in the background despite no video being visible.
The solution is to either edit the video in Wistia's configuration properties to have the background one load and the foreground one not, or use the Embed API to set the settings in the JavaScript itself so you don't have to worry about what the video's default settings are.

Preload in html

I've made a simple google search code like this:
<div style="text-align:center">
<form method="get" action="http://www.google.com/search">
<img src="http://www.google.com/images/srpr/logo3w.png"><br><input style="width:300px"name="q">
<input type="submit" value="Google Search" >
</form></div>
and in this , code(including the form) and image(google image) loads at the same time.
How can I make the form(input) to load firstly, and than the image?
You can set the src of the image once the DOM is ready..
<div style="text-align:center">
<form method="get" action="http://www.google.com/search">
<img id="googleimage" data-src="http://www.google.com/images/srpr/logo3w.png"/><br>
<input style="width:300px"name="q">
<input type="submit" value="Google Search" >
</form>
</div>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function(){
var img = document.getElementById('googleimage');
img.src = img.getAttribute('data-src');
}, false);
</script>
Demo at http://jsfiddle.net/gaby/mpEeF/
Just adding that in case that the problem is that as images are loaded (that might be before the form) the form is being pushed down, making hard to locate and edit it, the only solution would be to add actual sizes (width/height through the style attribute) to the images, so that the browser can correctly calculate the final look of the page, even before the images have loaded..
What do you mean by
they are loaded at the same time
because they are not loaded at same time, first the page is loaded and in parallel as img tag are parsed images are loaded. So actually browser almost does what you want, you can test that by having a img which loads slowly you will see your form will load first.
Anyway what is the actual problem you are trying to solve.
Check this code . You should include jquery in your page or convert jquery code to normal javascript
http://jsfiddle.net/pt4DT/
I want form(input) to load first (and users to be able to write earlier), because images are not important, I want them to load at the end(after all html, css and js loads)
Ok, first of all let me say that this only is true for all the newer browser up from about IE6 I think (not sure when exactly), but that still should be the vast majority.
Below you can see an image of how a typical page load containing html (the first line being the html, the second js, the third and fourth css and the last the image).
As you can see the html is loaded first as it needs to know which js and css needs to be loaded. Now - and this depends on the browser and blocking/non blocking javascript - the image itself is sometimes loaded in parallel with the js/css or it's loaded once the css and javascript is finished downloading (as per the image above). Either way, whatever the browser decides to do, it will be the most optimal solution (e.g. there is a limit on the number of https request most browser will do in parallel which is solved by the spdy protocol, but that's another story). Now, looking more closely at the graph you can see two lines, one blue line which shows when the page is displayed to the user (with the form, but without the image) and a green line once the DOM is finished loading (including the image). Thus the browser is already doing exactly what you want it to do. However, as there are only about 100ms between the two points you probably don't conciously see this except if you have a lot of images.
The only important thing is to not lock the loading of your page in your javascript which can speed the loading of the page up incredibly (for example by loading most javascript after the page finishes loading by injecting it dynamically into the page). Either way, any optimizations benefit greatly from taking a look at the waterfall of your page load (the image above) in either firefox (with firebug and go to the net tab) or chrome (hit F12 and go to the network tab) showing what is loaded when and trying to get the blue line to move as much as possible to the left.
Try this one :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>Untitled 1</title>
<script type="text/javascript">
function Addimg()
{
document.getElementById("googleimg").src = "http://www.google.com/images/srpr/logo3w.png";
}
</script>
</head>
<body onload="Addimg()">
<div style="text-align:center">
<form method="get" action="http://www.google.com/search">
<img id="googleimg" src=""><br><input style="width:300px"name="q">
<input type="submit" value="Google Search" >
</form></div>
</body>
</html>
Yet another one:
Try This
HTML:
<div id="google-search-container">
<form method="get" action="//www.google.com/search">
<div id="google-logo"></div>
<input id="q" name="q" />
<input type="submit" value="Google Search" />
</form>
</div>
JavaScript:
function addLogo() {
document.getElementById('google-logo').style.backgroundImage = "url('//www.google.com/images/srpr/logo3w.png')";
}
window.onload = function() {
addLogo();
}
CSS:
#google-search-container {
text-align: center
}
#google-logo {
margin: 10px auto;
background-repeat: no-repeat;
background-size:275px 95px;
height: 95px;
width: 275px
}
#q {
width: 300px
}

JWplayer Javascript interaction not working

this problem is going to make me bald. Save my hair plz.
i have been trying every possible way to stop and pause and play the JWplayer latest version using its JavaScript API and nothing works.
here is the code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>JW Player 5 playlist</title>
<script src="jquery-1.3.2.min.js" type="text/javascript"></script>
<script type="text/javascript" src="jwplayer.js"></script>
<script type="text/javascript" src="swfobject.js"></script>
</head>
<body>
<!-- START OF THE PLAYER EMBEDDING TO COPY-PASTE -->
<div id="mediaplayer">JW Player goes here</div>
<script type="text/javascript">
jwplayer("mediaplayer").setup({
flashplayer: "player.swf",
file: "lounge warmup.3gp",
skin: "simple/simple.zip",
image: "http://content.bitsontherun.com/thumbs/nPripu9l-480.jpg",
controlbar: "bottom",
width: "400",
height: "8"
});
</script>
<!-- END OF THE PLAYER EMBEDDING -->
<br>
Stop playback
</body>
</html>
why this is not working??
Your code works for me (after I adjusted the "file" to something I had locally). Some possibilities:
Are you loading this with a "file://" URL, or are you loading it from an actual web server? (If from a file:// URL, there might be Flash security restrictions.)
Do you intend to have a height of 8px as you've currently specified? I don't know what your custom skin looks like. In order to see things using default skin I had to specify a larger height.
I'm not very familiar with JWPlayer, but is it possible the file parameter needs to be URL encoded? (If not sure, maybe trying removing the space from the file name and renaming it on the server as well.)
In any case, your code works for me using default skin and different media file. I can play and then click your "stop" link to stop playback. If ideas above don't help, then you'll need to specify exactly what is not working for you.

Categories

Resources