If you take a look at this page here, you'll see that I've created a bit of a Youtube video gallery. When it works, it should replace the video in the main section of the page (at the top) with the thumbnail that is clicked and the text on the right is also replaced with text related to that video.
The text replacement seems to be working perfectly but I'm experiencing an issue where during the swap, the iFrame seems to be getting placed multiple times and so the video plays 2-3 times.
The Javascript is below -- is this something I've missed?
<script>
function replaceVideo(id) {
originalSrc = jQuery("iframe", "#" + id).attr("src");
autoPlay = originalSrc + "&autoplay=1";
jQuery("iframe", "#" + id).attr("src", autoPlay);
video = jQuery(".video-wrap", "#" + id).html();
jQuery(".flex-video").html(video);
text = jQuery(".video-description", "#" + id).html();
jQuery(".vid_desc").html(text);
jQuery("iframe", "#" + id).attr("src", originalSrc);
}
jQuery(".video-list li").click(function() {
id = jQuery(this).attr("id");
replaceVideo(id);
});
jQuery(window).load(function() {
if(window.location.search.substring(1)) {
element = window.location.search.substring(1).split('&');
if (document.getElementById(element[0])) {
document.onload = replaceVideo(element[0]);
}
}
});
</script>
Thanks!
Run jQuery(".flex-video") this in your javascript console. You'll see there are THREE divs that have that class. So jQuery(".flex-video").html(video); this line of JS changes the inner HTML of 3 elements to be the iframe.
<div class="flex-video widescreen">
<iframe width="583" height="328" src="http://www.youtube.com/embed/TWmFCX40BQc?rel=0&autoplay=1" frameborder="0" allowfullscreen></iframe>
</div>
You need to make the above div distinguishable from the other flex-video frames. Give the parent div an id or another class or something to query off of. Do that, and then you'd be fine.
EDIT: By the way, this code is wrong:
if(window.location.search.substring(1))
{
element = window.location.search.substring(1).split('&');
if (document.getElementById(element[0])) {
document.onload = replaceVideo(element[0]);
}
}
setting document.onload to a function call will call replaceVideo and set the onload property to whatever it returns, which is nothing. It may appear to work because the video plays, but that's just because you're calling the replaceVideo method. Setting your if to this, will probably be sufficient for you (unless you can explain why you're setting it to onload)
if(document.getElementById(element[0]))
replaceVideo(element[0]);
Related
I am a beginner JS user, and I am trying to get a video to play on fullscreen and replace an invisible div further down on the page. I started with a guide from Chris Ferdinandi.
In his guide, the video replaces the image that is clicked. I would like to have the div later down on the page to be replaced on the click.
Any guidance would be great!
HTML
<a data-video="480459339" class="stylsheetref" href="#" target="">Watch the Tour</a>
<div id="video-replace"></div>
Javascript (modified from this guide)
<script>
if (!Element.prototype.requestFullscreen) {
Element.prototype.requestFullscreen = Element.prototype.mozRequestFullscreen || Element.prototype.webkitRequestFullscreen || Element.prototype.msRequestFullscreen;
}
// Listen for clicks
document.addEventListener('click', function (event) {
//Set invisible Div (new code added by me)
var videonew = '#video-replace');
// Check if clicked element is a video link
var videoId = event.target.getAttribute('data-video');
if (!videoId) return;
// Create iframe
var iframe = document.createElement('div');
iframe.innerHTML = '<p>x</p><iframe width="560" height="960" src="https://player.vimeo.com/video/' + videoId + '?rel=0&autoplay=1" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>';
var video = iframe.childNodes[1];
// Replace the image with the video
event.target.parentNode.replaceChild(video, videonew);
// Enter fullscreen mode
video.requestFullscreen();
}, false);
</script>
There are problems in your code.
var videonew = '#video-replace'); there's an orphan ), since you are using this in the `replaceChild``method I assume you want the variable to reference to an element.
So change it to
var videonew = document.querySelector('#video-replace');
Pro tip: Using the Developer console during development can help you figure out such errors in your code.
I am trying to replace internal links:
<div class="activityinstance">
activity
</div>
to become:
<div class="activityinstance">
<iframe src="http://website.com/hvp/view.php?id=515512">
activity
</iframe>
</div>
I have been able to replace just the text with an iframe using jquery.
https://codepen.io/alanpt/pen/mWJvoB
But this is proving to be quite hard.
Another difficulty is that it needs to only be links with hvp in the address.
I appreciate any help - thanks.
$('body').ready(function(){
$('.activityinstance a').each(function(){ // get all the links inside the .activeinstance elements
var $this = $(this); // ...
var $parent = $this.parent(); // get the parent of the link
var href = $this.attr('href'); // get the href of the link
if(href.indexOf('/hvp/') == -1) return; // if the href doesn't contain '/hvp/' then skip the rest of this function (where the replacement happens)
$this.remove(); // remove the link as I don't see any reasong for it to be inside the iframe
$parent.append('<iframe src="' + href + '"></iframe>'); // add an iframe with the src set to the href to the parent of the link
});
});
A sample of:
<div class="activityinstance">
activity
</div>
[Because of a fact that having HTML inside of an IFRAME tags has no bearing, and is a complete waste of bytes, we will leave it out. And because this solution doesn't need wrappers, we'll stick to the good old (plain and clean) JavaScript].
The snippet:
[].slice.call(document.links).
forEach(
function( a ) {
if( a.href.match(/hvp/) ) {
a.outerHTML = "<iframe src=" + a.href + "><\/iframe>"
}
} );
will result in clean HTML such as:
<div class="activityinstance">
<iframe src="http://website.com/hvp/view.php?id=515512"></iframe>
</div>
...of course, without indentations and unnecessary white-spaces.
$('a').replaceWith(function () {
var content = this;
return $('<iframe src="about:blank;">').one('load', function () {
$(this).contents().find('body').append(content);
});
});
I've got the following script which swaps the source of an image. However currently this happens after the page loads so the user experiences a split second of seeing one picture before it switches to the correct image.
<script>
window.onload = function () {
var winnerName = $("#leaderboard tr td:eq(1)").text().trim();
$("#pictureDiv img").attr("src", "/Content/Images/" + winnerName + ".jpg");
};
</script>
How can I get the image to switch before loading?
Note I've also tried:
<script>
$(function() {
var winnerName = $("#leaderboard tr td:eq(1)").text().trim();
$("#pictureDiv img").attr("src", "/Content/Images/" + winnerName + ".jpg");
});
</script>
but this results in the same thing occurring
Both of the window.onload or jQuery's $(function()... functions are only called when the page is fully loaded.
The closest you could get is to add the function to the images onload handler.
<img src="..." onload="function() {...}">
But I suspect the same will still occur.
If the image's src needs to be set using javascript then you could try dynamically creating the image and adding it in where you need it, using something like the following.
$(function() {
var winnerName = $("#leaderboard tr td:eq(1)").text().trim();
var imgElement = $('<img>').attr("src", "/Content/Images/" + winnerName + ".jpg");
$("#pictureDiv").append(imgElement);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="pictureDiv"></div>
I'm trying to figure out how to combine this code into a switch statement using an index. I'm using this code to allow someone to click on a thumbnail, play that video in the player along with change the title depending on which video is played. Thanks in advance.
<script>
// Play the video
$( "#video-1, #item1" ).click(function() {
flowplayer().play("video1.mp4");
});
$( "#video-2, #item2" ).click(function() {
flowplayer().play("video2.mp4");
});
$( "#video-3, #item3" ).click(function() {
flowplayer().play("video3.mp4");
});
$( "#video-4, #item4" ).click(function() {
flowplayer().play("video4.mp4");
});
$( "#video-5, #item5" ).click(function() {
flowplayer().play("video5.mp4");
});
// Change title
function changeTitle(name)
{
document.getElementById("show-title").innerHTML = "Now playing " + name;
}
// Add and remove active class
$('#playlist li').on('click', function(){
$(this).addClass('active').siblings().removeClass('active');
});
</script>
The cleanest way to do this is to add a common class name to all the items that you want to be video click enabled (all the #itemX and #video-X elements) so then you can use a very simple piece of javascript for the common click handler. You then extract the digits out of the click on element's ID value in order to figure out which video to play:
$(".videoPlay").click(function {
var num = this.id.match(/\d+/)[0];
flowplayer().play("video" + num + ".mp4");
});
If you cant add the common class, then you can just list out all the selectors you want included:
$("#video-1, #video-2, #video-3, #video-4, #video-5, #item1, #item2, #item3, #item4, #item5").click(function() {
var num = this.id.match(/\d+/)[0];
flowplayer().play("video" + num + ".mp4");
});
Or, if you have no other ids that might get caught up in a partial id match, you can use the starts with selector logic, though I prefer to avoid this because it's not fast for the browser to resolve (it has to look at every single object that has an ID). I'd perfer listing the actual ids or using a common class name:
$("[id^='video-'], [id^='item']").click(function() {
var num = this.id.match(/\d+/)[0];
flowplayer().play("video" + num + ".mp4");
});
If there is no correspondence between the id of the clicked-on item and the video filename, then you need to create some sort of map between the two. My favorite technique would be to specify a data-video custom attribute on the actual element:
<div class="videoPlay" data-video="thor.mp4">Click me to Play a Video</div>
And, then the JS would be:
$(".videoPlay").click(function {
var fname = $(this).data("video");
flowplayer().play(fname);
});
You can have as many of these HTML elements as you want and just make sure each one specifies the video file you want that element to play and the JS doesn't have to change at all as you add more and more.
This should work :
$( "[id^='video-'], [id^=item]" ).click(function() {
var vid = this.id.replace(/(\d)|./g, '$1');
flowplayer().play("video"+ vid +".mp4");
});
I have a little html5 application where you can play a sound by clicking a button.
I have a function that adds an <audio> tag to a <div> with an id "playing." The sound removes itself when it is done.
function sound(track){
$("#playing").append("<audio src=\"" + track + "\" autoplay onended=\"$(this).remove()\"></audio>");
}
For the button I have:
<button onclick="sound('sounds/tada.mp3')">Tada</button>
When I click the button, an <audio> briefly appears in the element inspector and disappears when it is finished, just the way I want it, but after triggering it two times, it just stops working in Chrome, at least. There are no errors in the console either.
What is going on?
Get rid of the onclick/onend in your HTML and reference the button in your js:
HTML
<button id='tada' sound_url='sounds/tada.mp3'>Tada</button>
And the JS
var sound = function(track){
$("#playing").append("<audio id='played_audio' src='\" + track + \"' autoplay='true'></audio>");
}
$('#tada').on('click', function () {
var sound_url = $(this).attr('sound_url');
sound(sound_url);
});
$('#playing').on('end', 'played_audio', function() {
$(this).remove();
});
Okay, lets see..
var audioURL = "http://soundbible.com/mp3/Canadian Geese-SoundBible.com-56609871.mp3";
var audioEl = null;
function removeAudio() {
if (audioEl && audioEl.parentNode)
audioEl.parentNode.removeChild(audioEl);
}
function sound() {
removeAudio();
audioEl = document.createElement("audio");
audioEl.src = audioURL;
audioEl.controls = true;
audioEl.addEventListener("ended", removeAudio); // <-- Note it's ended, not end!
document.getElementById("playing").appendChild(audioEl);
audioEl.play();
}
document.getElementById("tada").addEventListener("click", sound);
<div id="playing">
</div>
<button id="tada">Tada</button>
I'm not seeing any problems with this script.
Decide audioURL, set audioEl to null as it will be used later
When the element with ID "tada" is clicked, run our sound function.
Remove the audio.
Create the audio element.
When the audio is finished, remove the audio.
Append the audio to the element with ID "playing".
Play the audio.
One thing to note is that I use the ended event, not the end event.
(This answer is here because Andrew really wants us to answer it.)