Here is the JavaScript:
function unhide(divID) {
var item = document.getElementById(divID);
if (item) {
item.className=(item.className=='hidden')?'unhidden':'hidden';
}
}
Here is the HTML:
<a href="javascript:unhide('verizon');">VERIZON<br>
SAP<br>
<div id="sap" class="hidden">
<embed src="videos/sap.mov" height="270" width="480" scale="tofit"></embed>
</div>
<div id="verizon" class="hidden">
<embed src="videos/verizon.mov" height="270" width="480" scale="tofit"></embed>
</div>
When I click on SAP the video plays. When I click on Verizon it also plays but the SAP video continues to play even though it is hidden.
I am very new to javascript.
Is there a better way to do this? How do I fix with the code I already have?
You could do something like this:
function unhide(divID) {
var item = document.getElementById(divID);
var other = {"verizon":"sap","sap":"verizon"};
if (item) {
item.className=(item.className=='hidden')?'unhidden':'hidden';
var tar = document.getElementById(other[divID]);
tar.className = 'hidden';
tar.getElementsByTagName("embed")[0].stopVideo();
}
}
Other is just an object which provides easy access to the id of the video to be stopped. It uses the string from divID to obtain the other string.
Then once you have that other element, you traverse into its children to find the embed element. [0] is used to get the first matching element (your video). Then you can use javascript's stopVideo() method on it to stop the video.
My preferred solution would be to set the HTML of that div to null rather than try to manipulate what's inside it to get it to shut up. After all it's hidden so why bother keeping it there.
document.getElementByID('div').innerHTML = "";
Thereby completely removing anything in there.
And to un-hide it (note you may have to fidget with this a bit to get the quotes to behave)
document.getElementByID('div').innerHTML = '<embed src="videos/sap.mov" height="270" width="480" scale="tofit"></embed>';
I think for flash or a heavy element like a video player this would be a better solution, imagine a page with 30 of these that are hidden, it would get pretty bogged down.
Related
What I'm trying to do: Create a list of items which contains a link to play audio from a youtube video beside each item
What I'm currently doing: I'm able to do this for a single item using the below:
<div data-video="VIDEO_ID"
data-autoplay="0"
data-loop="1"
id="youtube-audio">
</div>
<script src="https://www.youtube.com/iframe_api"></script>
<script src="https://cdn.rawgit.com/labnol/files/master/yt.js"></script>
This creates a play button and works perfectly on a single item, however will not work with multiple items on the same page presumably since they all use the same ID. Creating a different ID causes the player to not function. Creating two different data-video's with the same ID will only allow the first one to play, the other will appear correctly but not operate when pressing play.
Looking for solution: Preferably how to use the existing script for multiple videos on the same page. Otherwise an alternative solution for playing audio only on youtube videos with a custom play button would be great.
Thanks!
If you want you can just copy paste your code like this
https://jsfiddle.net/8wkjqf3m/
and it works, I'm not sure if you were having a problem doing that or if your problem was elsewhere. It is of course very sloppy looking and the code should be reworked so that you don't have to hard code every function for every video.
I tried to do everything dynamically and failed. I'm not sure if it is possible to dynamically make a function that makes a "new YT.player" for every video id you have and also have the onPlayerReady and onPlayerStateChange functions dynamically made to go with it. I'm sure there is some way but I couldn't figure it out.
The idea though is to make multiple "youtube-audio" divs with different ids for however many youtube players you want to have and have matching multiple "youtube-player" divs for the iframe to function. You can generate that part with javascript if you want so that you don't have to pollute your code with a bunch of repetitive html.
You can make all of your ids dynamically too.
var array = ['put a video id here','put a video id here','put a video id here'];
array = array.map(function(element,index) {
var div = document.createElement('div');
div.setAttribute('id', 'youtube-audio-' + index);
return {'videoId': element, 'div': div };
}
You can just have an array holding the youtube video ids and then initialize all of the divs data-video attributes using
document.getElementById("youtube-audio-1").dataset.video = //youtube video id
I don't see the point in doing all of that dynamically though if there is no way to get around copy pasting x number of "new YT.player"s and "onPlayerReady"s etc...
Good Luck, let me know if I was in the right area or if that was not what you wanted
I have modified the second script so it works as you (or I) want.
To use it use classes instead of IDs. Like the following:
<div data-video="NQKC24th90U" data-autoplay="0" data-loop="1" class="youtube-audio"></div>
<div data-video="KK2smasHg6w" data-autoplay="0" data-loop="1" class="youtube-audio"></div>
Here is the script:
/*
YouTube Audio Embed
--------------------
Author: Amit Agarwal
Web: http://www.labnol.org/?p=26740
edited by Anton Chinaev
*/
function onYouTubeIframeAPIReady()
{
var o= function(e, t)
// This function switches the imgs, you may want to change it
{
var a=e?"IDzX9gL.png":"quyUPXN.png";
//IDzX9gL is the stopped img and quyUPXN the playing img
t.setAttribute("src","https://i.imgur.com/"+a)
// folder or web direction the img is in. it can be "./"+a
};
var counter = 0;
var bigE = document.querySelectorAll(".youtube-audio");
bigE.forEach(function(e)
{
var t=document.createElement("img");
t.setAttribute("id","youtube-icon-"+counter),
t.style.cssText="cursor:pointer;cursor:hand",
e.appendChild(t);
var a=document.createElement("div");
a.setAttribute("id","youtube-player-"+counter),
e.appendChild(a);
t.setAttribute("src","https://i.imgur.com/quyUPXN.png");
e.onclick=function()
{
r.getPlayerState()===YT.PlayerState.PLAYING||r.getPlayerState()===YT.PlayerState.BUFFERING?(r.pauseVideo(),
o(!1, t)):(r.playVideo(),
o(!0, t))
};
var r= new YT.Player("youtube-player-"+counter,
{
height:"0",
width:"0",
videoId:e.dataset.video,
playerVars:
{
autoplay:e.dataset.autoplay,loop:e.dataset.loop
},
events:
{
onReady:function(e)
{
r.setPlaybackQuality("small"),
o(r.getPlayerState()!==YT.PlayerState.CUED, t)
},
onStateChange:function(e)
{
e.data===YT.PlayerState.ENDED&&o(!1, t)
}
}
})
counter++;
});
}
So basically I would like to make a little lazy load code to my site.
Every Youtube video has a thumbnail and usually the url is something like this:
http://img.youtube.com/vi/<THEVIDEOID>/maxresdefault.jpg
I would like to detect this and if it's true, this can be a click event, and after you clicked the image, you get the iframe and you can play the video.
Now, I know there is thousand and thousand outsiders plugin in the internet, but I don't want to load any other code, just that function what is really necessary for this script to work (I hate big load times like anyone else).
Sometimes the outside plugins has thousand, and thousand unnecessary functions for me, like check on every load I chose the click method or the scroll method, and other not useful things.
That's why I decided I trying to build my own.
I saw this post in the search results, but I would like to build this on jQuery way.
Note:
This need for a Wordpress site, that's why I use jQuery instead of $.
This what I have now:
jQuery(document).ready(function() {
function youtubecheck(){
var myregexp = /[a-z,A-Z,0-9]/g;//Regexp for videoid
var imageurl="http://img.youtube.com/vi/"+myregexp+"/maxresdefault.jpg"; // This doesn't sounds right, I need to find out something else.
if (jQuery("img").attr("src")=== "imageurl"){
var autoplay="?autoplay=1/"//this for iframe
jQuery(this).addClass("YT-image"); // Obviously we need class, because we don't whant to do this with all images, just with YT-imgaes.
jQuery(".YT-image").click(function() {
jQuery(".YT-image").replaceWith('<iframe width="560" height="315" src="https://www.youtube.com/embed/'+myregexp+autoplay+'" frameborder="0" allowfullscreen></iframe>'); // maybe we need each for every image? Also I'm not sure about "myregexp" variable in here.
});
}
}
youtubecheck();
});
Changed your if condition and regex
jQuery(document).ready(function() {
function youtubecheck() {
if (/img\.youtube\.com\/vi\/[a-z,A-Z,0-9]+\/maxresdefault\.jpg/g.test(jQuery("img").attr("src"))) {
var videoId = /img\.youtube\.com\/vi\/(.*?)\/maxresdefault\.jpg/g.exec(jQuery("img").attr("src"))[1];
var autoplay = "?autoplay=1/"; //this for iframe
jQuery("img").addClass("YT-image"); //Obviously we need class, becouse we don't whant to do this with all images, just with YT-imgaes.
jQuery(".YT-image").click(function() {
jQuery(this).replaceWith('<iframe width="560" height="315" src="https://www.youtube.com/embed/' + videoId + autoplay + '" frameborder="0" allowfullscreen></iframe>'); // maybe we need each for every image? Also I'm not sure about "myregexp" varible in here.
});
}
}
youtubecheck();
});
Updated the code this works
I have a few iframes on my homepage at the bottom (http://www.binarycontrast.com), where one is randomly selected on page load. The code I'm using below works, but the iframes load really slowly. What the code does is generate a random iframe to display on page load. I actually got the code from another question on here regarding loading random images on page load, and I just tweeked it to what I needed.
If I have a single iframe on the page it loads really quickly, but for some reason using this code slows it down a lot, so I want a way to speed up the iframe loading time whilst using some script to randomly choose one to display.
An alternative method or help with the code I have would be really appreciated.
Please see the below code:
<iframe class="random-iframe" src="http://www.binarycontrast.com/visit/24Option" width="100%" height="700" frameborder="0" scrolling="yes" seamless="seamless"></iframe>
<iframe class="random-iframe" src="http://www.binarycontrast.com/visit/OptionFair" width="100%" height="700" frameborder="0" scrolling="yes" seamless="seamless"></iframe>
<iframe class="random-iframe" src="http://www.binarycontrast.com/visit/StockPair" width="100%" height="700" frameborder="0" scrolling="yes" seamless="seamless"></iframe>
And the script used to make it work:
$(window).load(function(){
var divs = $("iframe.random-iframe").get().sort(function(){
return Math.round(Math.random())-0.5; //random so we get the right +/- combo
}).slice(0,1)
$(divs).appendTo(divs[0].parentNode).show();
});
And the css:
iframe.random-iframe { display: none; }
Thanks for any help in advance.
I think the Problem ist that you load all the iframes.
Even the ones you don't need.
You should only hold your Urls (Not the whole iframe tags) and the make a random select for one of the urls.
Only then create a Iframe tag with the selected url.
something like this:
function getRandomUrl(urls) {
var minIndex = 0;
var maxIndex = urls.length - 1;
var randomIndex = Math.floor(Math.random() * (maxIndex - minIndex)) + minIndex;
return urls[randomIndex];
}
var urls = [
"url1",
"url2",
"url3"];
var randomSelectedUrl = getRandomUrl(urls);
$("#hereComesTheIframeInto").html(
"<iframe class='random-iframe' src='" + randomSelectedUrl + "' width='100%' height='700' frameborder='0' scrolling='yes' seamless='seamless'></iframe>");
<div id="hereComesTheIframeInto"></div>
I Hope you get the point. I didn't finish it completely for you.
EDIT:
eradicated error. (I have composed the strings with "&" before but in Javascript you have to do this with "+")
Sorry for this. =(
Instead of loading all the iframes, and then hiding some of them, try to generate only one iframe.
Use random to chose which url will be in the src.
Then use
var chosenURL = 'url'; // The url you randomly chose
var parentNode = 'iframe-container'; // Where you want to put your iframe
$('<iframe class="random-iframe" src="'+chosenURL+'" width="100%" height="700" frameborder="0" scrolling="yes" seamless="seamless"></iframe>').appendTo(parentNode);
You would be far better of using your code to insert one of three urls randomly into the iframes src.
Looks like there are two issues:
You're hiding the iframes but they're all still loading in the background. You could try using an array with the sources and just creating a single iframe element, or leaving the src tag blank until you're ready to load it.
You're waiting for the window to load, including all images and iframes, before showing any iframe. If you changed the code to run when the document is ready then the code will run much sooner. Better yet, as long as the script is placed after the iframes in the DOM, you don't even need to wait for the whole document to load.
function loadRandomIFrame() {
var divs = document.querySelectorAll(".random-iframe"),
div = divs[Math.round(Math.random() * (divs.length - 1))],
frame = document.createElement("iframe");
frame.width = "100%";
frame.height = 700;
frame.frameborder = 0;
frame.scrolling = "yes";
frame.seamless = "seamless";
frame.src = div.dataset.src;
div.parentNode.appendChild(frame);
}
loadRandomIFrame();
<div class="random-iframe" data-src="http://www.binarycontrast.com/visit/24Option"></div>
<div class="random-iframe" data-src="http://www.binarycontrast.com/visit/OptionFair"></div>
<div class="random-iframe" data-src="http://www.binarycontrast.com/visit/StockPair"></div>
I have a simple web page where 1 frame displays a pdf and another a menu bar.
<iframe src="bar.html" name="menu" ></iframe>
<iframe src="doc.pdf" name="itempane" ></iframe>
Using chrome I can navigate from the menu bar to the parent and back down to the frame containing the pdf in order to print it
var pWindow = window.parent;
pWindow['itempane'].print();
Attempting to do the same in IE11 gives an Invalid calling object error.
you can see this at http://www.abhrdev.co.uk/main.html
What am I doing wrong / what is IE doing differently?
Cheers
Updated.....
I think I have proved that this is not a javascript coding issue but related to the pdf handling in IE. With the following page
Print PDF<br/>
Print HTML
<iframe src="bar_1.html" name="menu" ></iframe>
<iframe src="doc.pdf" name="pdfpane" ></iframe>
<iframe src="doc.html" name="htmlpane" ></iframe>
and this function
function printFromMain(paneName) {
var pWindow = window[paneName];
pWindow.focus();
pWindow.print();
}
the printing of the html page works but not the pdf the pWindow.focus() gives Invalid Calling Object - any insight into why that might be greatfully recieved
After trying several things, I finally go this to work in IE11:
1) use an object tag instead of iframe
2) run focus() / print() directly on the element
3) run after a timeout, to make sure everything in is loaded. There may be a better way (like using some event listener) to do this, as the timeout time needs to be fairly long for it to work properly
setTimeout(function () {
var contentThingy = document.getElementById('itempane');
contentThingy.focus();
contentThingy.print();
}, 4000);
Object (with a specified id) instead of iframe:
<object id="itempane" ... ></object>
Note: doesn't work in chrome. One of the other variations in the other answers (i.e. using ContentWindow) may.
Try actually using the window.frames to get the frameList and reference it by the frame name that way.
var pWindow = window.parent; //reference the parent from the iframe
var ifr = pWindow.frames.itempane; //get the pdf frame from the frame list
ifr.focus();
ifr.print();
Try this
<iframe src="bar.html" name="menu" ></iframe>
<iframe src="doc.pdf" ID="itempane" ></iframe>
var otherPane = parent.document.getElementById("itempane");
otherPane.focus(); // OR
otherPane.print(); // OR
var doc = otherPane.contentWindow || otherPane.contentDocument;
doc.focus();
doc.print();
Huge WTF that I thought was a bug hidden in the semicomplex web app that I'm making, but I have pared it down to the simplest code possible, and it is still replicable in Firefox, Chrome, and Safari, unpredictably but more than 1/2 of the time.
http://jsfiddle.net/cDpV9/7/
var v = $("<video id='v' src='http://ia600401.us.archive.org/18/items/ForrestPlaysTaik/forresto-plays-taik-piano-360.webm' autobuffer='auto' preload autoplay controls></video>");
$("#player").append(v);
Add a video element.
Video starts to load and play.
Video audio sounds like it is doubled.
Pause the visible video, and one audio track continues.
Delete the video element; the ghost audio keeps playing.
Delete the frame, and the ghost audio stops (though once in Firefox it continued to play after closing the window, and didn't stop until quitting Firefox).
Here is a screen capture to maybe show that I'm not completely crazy: http://www.youtube.com/watch?v=hLYrakKagRY
It doesn't seem to happen when making the element with .html() instead of .append(), so that's my only clue: http://jsfiddle.net/cDpV9/6/
$("#player").html("<video id='v' src='http://ia600401.us.archive.org/18/items/ForrestPlaysTaik/forresto-plays-taik-piano-360.webm' autobuffer='auto' preload autoplay controls></video>");
I'm on OS X 10.6.7.
I think that I have it. Even just creating the JQuery object without adding it to the page causes the ghost player to play: http://jsfiddle.net/cDpV9/8/
var v = $("<video id='v' src='http://ia600401.us.archive.org/18/items/ForrestPlaysTaik/forresto-plays-taik-banjo-360.webm' autobuffer='auto' preload autoplay controls></video>");
For now I can work around this by using .html(). I'll report the issue to JQuery.
Maybe jQuery caches the content of $() before appending it to your player div? So there is another instance of the video tag. It could be an error in jQuery. Have you tried this without Jquery/js?
I would try adding the autoplay attribute after you append the video player. This should then instantiate the play function.
That would be something like this:
var v = $("<video id='v' src='videofile.webm' autobuffer='auto' preload controls></video>");
$("#player").append(v);
v.attr('autoplay','autoplay');
When you create elements in JavaScript i.e. image elements, objects etc, they are loaded instantly and stored in memory as objects. That is why you can preload images before you load a page. It is therefore not a jQuery bug.
Ref: http://www.w3.org/TR/html5/video.html#attr-media-autoplay
When present, the user agent (as described in the algorithm described
herein) will automatically begin playback of the media resource as
soon as it can do so without stopping.
I've got the same problem over here. This seems to be an issue with using the "autoplay" attribute on your video markup.
Remove the autoplay attribute
append your video DOMNode to any node
if you want autoplay behavior, call videodomnode.play() - using jquery this would be $('video')[0].play()
You could get the html of #player and append the video your self, then add the total with .html() like this:
var v = $("#player").html() + "<video id='v' src='http://ia600401.us.archive.org/18/items/ForrestPlaysTaik/forresto-plays-taik-piano-360.webm' autobuffer='auto' preload autoplay controls></video>";
$("#player").html(v);
It's not as good as the .append() function, but if the .append() doesn't work, you might be forced to do something like this.
This one worked best in my case:
var v = '<audio hidden name="media"><source src="text.mp3"><\/audio>';
$('#player').append(v);
$("audio")[$('audio').size()-1].play();
I solved mine by loading video after dom loaded:
$(window).bind("load", function() {
var v = $("<video id='bgvid' loop muted>
<source src='/blabla.mp4' type='video/mp4'>
</source>
</video>");
$(".video-container").append(v);
v.attr('autoplay','autoplay');
});