I am using fullpage.js for my website. About fullpage.js everything working fine. I want to open an div on click of pagniation. I am able to open div on click which contains YouTube video. But when div is visible browser scroll will be disabled I am not getting where I go wrong.
here is sample of my code:
$(document).ready(function() {
$('#fullpage').fullpage({
verticalCentered: false,
css3:false,
navigation: true,
normalScrollElements: '.text',
navigationTooltips: ['tooltip1', 'tooltip2', 'tooltip3'],
onLeave: function(index, nextIndex, direction){
var prevIndex = index - 1;
var currentIndex = nextIndex - 1;
$('#section'+currentIndex).css('transform', 'scale(1.2)');
$('#section'+currentIndex).css('transition', 'all 5s ease-in');
setTimeout(function(){
$('#section'+prevIndex).css('transform', 'scale(1)');
$('#section'+prevIndex).css('transition', 'all 0.2s ease-in');
},500);
},
});
});
in jquery.fullpage.js
var li = '<li><span>' + tooltip + '</span>';
function :
function displayDetails(id)
{
$('#text').show();
}
HTML code:
<style>
#text {
position: absolute;
display:none;
z-index:999;
top: 300px;
width:100%;
height: auto;
}
</style>
<div id="text">
<iframe width="480" height="270" class="video" src="https://www.youtube.com/embed/6iNFimn4wFA" frameborder="0" allowfullscreen></iframe>
<iframe width="480" height="270" class="video" src="https://www.youtube.com/embed/jsd-mNTIukM" frameborder="0" allowfullscreen></iframe><br>
<iframe width="480" height="270" class="video" src="https://www.youtube.com/embed/ylD-WFvRZkM" frameborder="0" allowfullscreen></iframe>
<iframe width="480" height="270" class="video" src="https://www.youtube.com/embed/g2YzRTAstPo" frameborder="0" allowfullscreen></iframe><br>
<iframe width="480" height="270" class="video" src="https://www.youtube.com/embed/98NqtVG-hFU" frameborder="0" allowfullscreen></iframe>
<iframe width="480" height="270" class="video" src="https://www.youtube.com/embed/O4weBTRCFzU" frameborder="0" allowfullscreen></iframe><br>
<iframe width="480" height="270" class="video" src="https://www.youtube.com/embed/UVzEOsHT7XA" frameborder="0" allowfullscreen></iframe>
</div>
<div id="fullpage">
<div class="section" id="section0"></div>
<div class="section" id="section1"></div>
<div class="section" id="section2"></div>
<div class="section" id="section3"></div>
<div class="section" id="section4"></div>
</div>
This code opens div as expected but scrolling to see last contents is not working. Instead of video if I enter text scroll works perfectly. As soon as I add video in div scroll stops working. I haven't set overflow property for #text. Please help me out.
I found this worked
function testing(){
//forcing fullPage.js to recalculate dimensions.
setTimeout(function(){
fullpage_api.reBuild();
}, 500);
};
for me this didn't work
$.fn.fullpage.reBuild();
First of all, you should be using scrollOverflow:true rather than normalScrollElements.
scrollOverflow:
(default false) defines whether or not to create a scroll for the section in case its content is bigger than the height of it. When set to true, your content will be wrapped by the plugin. Consider using delegation or load your other scripts in the afterRender callback. In case of setting it to true, it requires the vendor plugin jquery.slimscroll.min and it should be loaded before the fullPage.js plugin. For example:
Then, fullPage.js is calculatingn the height of your sections on page load.
If the videos are not displayed on page load, fullPage.js won't know the content is changing until you tell it so.
Try this:
function displayDetails(id){
$('#text').show();
//forcing fullPage.js to recalculate dimensions.
$.fn.fullpage.reBuild();
}
More about the reBuild method in the docs:
reBuild()
Updates the DOM structure to fit the new window size or its contents.
Ideal to use in combination with AJAX calls or external changes in the
DOM structure of the site.
See this example I made for you
For react users, this is the solution I found, that works best.
You need to save the fullpageApi from the render method, in state.
And then, take advantage of the useEffect to call the rebuild method.
I was using it inside the render(), but then I was getting a lot of weird behaviours, because the rebuild() was being called in every other page state update.
const [fullPageApi, setFullPageApi] = useState<fullpageApi>();
useEffect(() => {
if (fullPageApi){
setTimeout(function () {
fullPageApi.reBuild();
}, 1000);
}
}, [fullPageApi]);
// (...)
// Component example
<ReactFullpage
scrollOverflow
navigation
render={({ fullpageApi }) => {
if (!fullPageApi) setFullPageApi(fullpageApi);
return (
<ReactFullpage.Wrapper>
<YourComponent />
</ReactFullpage.Wrapper>
);
}
}
/>
Related
I have the html like below:
<html>
<body>
<div>Welcome.</div>
<iframe src='otherpagecontent' width='594' height='334'>
#docuemnt
<html>
<body>
<div style='color:yellow'>
This should not show in fullscreen.
</div>
<div style='color:yellow'>
This should not show in fullscreen.
</div>
<div id='fullscreen' style='color:blue;'>
This should go fullscreen only.
</div>
<div style='color:red'>
This should not show in fullscreen.
</div>
<div style='color:red'>
This should not show in fullscreen.
</div>
</body>
</html>
</iframe>
<iframe src='diffirentpage'>
#docuemnt
<button onclick="launchFullscreen(document.getelementByID('fullscreen'));">Launch Fullscreen</button>
</iframe>
</body>
</html>
In JS:
this.launchFullscreen= function (element) {
var requestFullScreen = (element.requestFullScreen || element.mozRequestFullScreen || element.webkitRequestFullScreen || element.msRequestFullscreen);
requestFullScreen.apply(element);
}
Result in Request for fullscreen was denied because of FeaturePolicy directives.
How can I get this <div id='fullscreen'> to go fullscreen?
Should I change the CSS for this <div>, or bind the request from somewhere else?
PS: This work fine on Chrome, but issue occur on Firefox.
Yes, you should use CSS for this.
You can't force the user into full-screen by F11; however, you can make your div full screen by using the following CSS
div {width: 100%; height: 100%;}
This will of course assume your div is child of the tag. Otherwise, you'd need to add the following in addition to the above code.
div {position: absolute; top: 0; left: 0;}
from:How do I make a div full screen?
You might try this
<iframe src="myurl.in"
frameborder="0"
marginheight="0"
marginwidth="0"
width="100%"
height="100%"
scrolling="auto"></iframe >
from: https://www.geeksforgeeks.org/how-to-set-fullscreen-iframe/
I have three modals containing a video. Each button opens the same modal but it shows a different video depending on the buttom you clicked. It works fine, but I want to shut off the sound when closing the modal. There is a function to do that named closeVideo(), but it only works for the first modal, and not for the others.
Is there a way to create just one function to shut off the sound of every modal?
<div class="box">
<div class="piece">
<h2>Medcom</h2>
<div class="xbox">
<a class="ibutton trigger">
<h3>Ver video</h3>
</a>
</div>
</div>
</div>
<div class="box">
<div class="piece">
<h2>Juan Valdez</h2>
<div class="xbox">
<a class="ibutton trigger">
<h3>Ver video</h3>
</a>
</div>
</div>
</div>
<div class="box">
<div class="piece">
<h2>Grupo Epasa</h2>
<div class="xbox">
<a class="ibutton trigger">
<h3>Ver video</h3>
</a>
</div>
</div>
</div>
<div class="modal">
<div class="modal-content">
<span class="btn-close" (click)='closeVideo()'>
<img src="../../../../../assets/img/close.svg" alt="close">
</span>
<iframe id="player" width="560" height="315" src="https://www.youtube.com/embed/N8ABAZvh8WE" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
</div>
<div class="modal">
<div class="modal-content">
<span class="btn-close" (click)='closeVideo()'>
<img src="../../../../../assets/img/close.svg" alt="close">
</span>
<iframe id="player" width="560" height="315" src="https://www.youtube.com/embed/rn937OyA00g" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
</div>
<div class="modal">
<div class="modal-content">
<span class="btn-close" (click)='closeVideo()'>
<img src="../../../../../assets/img/close.svg" alt="close">
</span>
<iframe id="player" width="560" height="315" src="https://www.youtube.com/embed/EUjWFr3w7RU" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
</div>
/* SHOW MODALS */
const triggers = document.getElementsByClassName('trigger');
const triggerArray = Array.from(triggers).entries();
const modals = document.getElementsByClassName('modal');
const closeButton = document.getElementsByClassName('btn-close');
const myPlayer = document.getElementById('player');
for (let [index, trigger] of triggerArray) {
let triggerIndex = index;
function toggleModal() {
modals[triggerIndex].classList.toggle('show-modal');
}
trigger.addEventListener("click", toggleModal);
closeButton[triggerIndex].addEventListener("click", toggleModal);
}
closeVideo(){
myPlayer.setAttribute("src", " ");
console.log('video is closed now!');
}
The reason that you're having trouble is due to the repetition of the id across all <iframe> elements; as any id can be used only once within an HTML document JavaScript will only ever look for precisely one element with a given id; hence in this case if it finds an element with id="player" it will not look for any other element with that id attribute-value, since none should exist.
One solution, therefore, is to change the id to a class and therefore JavaScript will look for all elements with that class-name, then you could iterate through those elements and hide all of them:
closeVideo(){
let myPlayers = document.querySelectorAll('.player');
// here we use NodeList.forEach() to iterate through the
// NodeList returned by document.querySelectorAll(), and
// use an Arrow function as the callback:
myPlayers.forEach(
// here 'player' is the current element of the NodeList
// over which we're iterating; and we set the src of each
// element of the NodeList in turn to an empty string:
(player) => player.setAttribute('src','')
);
console.log('video is closed now!');
}
Of course this requires the HTML to be updated, to the following:
<div class="modal">
<div class="modal-content">
<span class="btn-close" (click)='closeVideo()'>
<img src="../../../../../assets/img/close.svg" alt="close">
</span>
<!-- note the change from id="player" to class="player"
this is true of all elements, though for brevity I'm
only showing one element -->
<iframe class="player" width="560" height="315" src="https://www.youtube.com/embed/N8ABAZvh8WE" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
</div>
However, once this is done you still have three modal elements, each with a different video within it. It's important to remember that one of the general principle of most programming is that of "DRY": Don't Repeat Yourself.
With that in mind, especially given the repetition of the elements themselves, it seems easier to use the <button> elements to pass in the relevant data, taking advantage of custom data-* attributes, such as:
<!-- here we use the data-video-id attribute to hold the video's id,
the data-platform-base attribute to hold the relevant base-URL
of the platform, and we use the videoPlayer function itself to
create the relevant src: -->
<button data-video-id="N8ABAZvh8WE" data-platform-base="https://www.youtube.com/embed/">Open: </button>
// here the event argument is passed in automatically by
// the later use of EventTarget.addEventListener(); we're using
// Arrow function syntax, since we have no need to use 'this'
// in the function:
const closeVideo = (event) => {
// event.target is the element that originally triggered
// the eventListener was listening for:
let closeButton = event.target,
// we use Element.closest() to find the first ancestor
// element of the event.target that matches the supplied
// CSS selector:
modal = closeButton.closest('div.modal'),
// from that modal element we use querySelector() to find
// the first of any elements that match the supplied CSS
// selector:
player = modal.querySelector('iframe');
// here we update the 'hidden' property of the modal element
// to true in order to hide the element:
modal.hidden = true;
// we update - or rather remove - the player's src, by setting
// that src to null (in order to stop the video and any sound
// from playing):
player.src = null;
},
// here we retrieve all the <button> elements that have a
// data-video-id attribute and which have a data-platform-base
// attribute:
buttons = document.querySelectorAll('button[data-video-id][data-platform-base]'),
// we find the modal element using document.querySelector() to search
// the document for the first of any elements that match the supplied
// CSS selector:
modal = document.querySelector('div.modal');
// here we use querySelector() again to search within the modal
// element (the div.modal element found above) to find the first
// <span> element with the class of 'btn-close', and use
// EventTarget.addEventListener() to bind the closeVideo() function
// (note the deliberate lack of parentheses on the function name)
// as the event-handler for the 'click' event:
modal.querySelector('span.btn-close').addEventListener('click', closeVideo);
// we use NodeList.forEach() to iterate over the NodeList returned by
// document.querySelectorAll():
buttons.forEach(
// using Arrow function syntax:
// we again use EventTarget.addEventListener() to bind the
// anonymous function as the event-handler for the 'click'
// event:
(button) => button.addEventListener('click', () => {
// here we cache a reference to the button.dataset DOMStringMap
// of custom data-* attributes and properties:
const data = button.dataset,
// here we create a url from the attribute-values held in the
// data-platform-base and data-video-id properties (note that
// these attribute-names are camel-cased as normal in JavaScript;
// these properties are retrieved within the jQuery-like
// ${...} and interpolated into the String:
url = `${data.platformBase}${data.videoId}`,
// we find the modal element:
modal = document.querySelector('div.modal'),
// we find the player element:
player = modal.querySelector('iframe');
// we update the src attribute of the player:
player.src = url;
// then we update the modal.hidden property to true, in order
// to show that element:
modal.hidden = false;
})
);
*,
::before,
::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
/*
here we position the modal element centred on the page,
and with a low z-index to keep it below the page content:
*/
.modal {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: -1000;
}
/*
here we update the z-index to a high number, in order to lift
it above the page-content; the selector here selects:
- all elements with a class of 'modal',
- which do not have the hidden attribute, using the
attribute-selector ([hidden]) within CSS' negation-operator
( :not() )
*/
.modal:not([hidden]) {
z-index: 1000;
}
/*
here we show the video id in the <button> elements:
*/
button::after {
content: attr(data-video-id);
}
span.btn-close {
display: inline-block;
cursor: pointer;
border: 2px solid #aaa;
width: 3ex;
height: 3ex;
text-align: center;
line-height: 3ex;
}
<!-- Note the addition of the 'hidden' attribute, below: -->
<div class="modal" hidden>
<div class="modal-content">
<span class="btn-close">X</span>
<iframe id="player" width="560" height="315" src="https://www.youtube.com/embed/N8ABAZvh8WE" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
</div>
<button data-video-id="N8ABAZvh8WE" data-platform-base="https://www.youtube.com/embed/">Open: </button>
<button data-video-id="rn937OyA00g" data-platform-base="https://www.youtube.com/embed/">Open: </button>
<button data-video-id="EUjWFr3w7RU" data-platform-base="https://www.youtube.com/embed/">Open: </button>
JS Fiddle demo.
[In] case, I don't want to apply the 'DRY' concept and keep several modals in my HTML, Is there a way to use the forEach() function, and still be able to open and see the other videos? I mean, after iterating the elements with class 'player' ? because I have seen it makes all the remaining videos hidden. Just curious about it.
Comment from OP, below: How can I make one function to close modals with different content in JS.
I'm not entirely sure that I understood the request on first reading, my first thoughts are below. This approach emulates the first approach (above), in that only one video/'modal' is visible at any one time. If I've misunderstood please clarify in the comments below and I'll attempt to improve the answer to meet your needs.
// here we define a 'modals' Object that serves as a
// repository of functions and controls for the
// interactivity:
const modals = {
// a 'buttons' Object that caches the relevant
// control elements:
buttons: {
show: document.querySelectorAll('.trigger'),
hide: document.querySelectorAll('.btn-close'),
},
// functions, which serve to provide the interactivity;
// here we have an EventObject ('evt') passed to the
// show() function (passed automatically by the later
// use of EventTarget.addEventListener()):
show: function(evt) {
// EventObject.currentTarget returns the element to
// which the event-listener was bound
// (EventObject.target returns the element that
// triggered the listened-for action, which may be
// the element itself or a descendant of that element):
let clicked = evt.currentTarget,
// we retrieve the relevant index from the element's
// dataset (we assign that value in later code) and
// and cast it to an integer, with parseInt(), in
// base-10 (hence the '10' as the second argument):
i = parseInt(clicked.dataset.index, 10),
// here we retrieve the elements with a class of
// 'modal':
modalBoxes = document.querySelectorAll('.modal');
// iterating over those elements using
// NodeList.prototype.forEach():
modalBoxes.forEach(
// we pass two arguments into the function, both
// of which are available automatically; 'modal'
// is a reference to the current Node of the
// NodeList over which we're iterating, and 'index'
// is the index of the current Node within the
// NodeList itself.
// in the function we're updating the modal.hidden
// property, we want to show the modal if its index
// matches; so if the i is not equal to index the
// modal is hidden, otherwise the modal is shown by
// as its index is equal to 'i' and therefore the
// assessment is false, so hidden its hidden property
// is false, therefore it's shown:
(modal, index) => modal.hidden = i !== index
);
},
hide: (evt) => {
// here we're navigating from the element to which
// the event-listener was bound up to the first
// ancestor element with the class of 'modal':
const m = evt.currentTarget.closest('.modal'),
// from there we retrieve the <iframe> element:
iframe = m.querySelector('iframe');
// here we hide the modal:
m.hidden = true;
// here we update the src of the <iframe> to be equal
// its own src; this causes a reload of the content
// and as such stops it from playing:
iframe.src = iframe.src;
},
// an initialisation function:
init: function() {
// here we're using destructuring to assign the
// 'hide' and 'show' properties of the
// this.buttons Object to variables of the same
// name:
const {
show,
hide
} = this.buttons;
// here we retrieve the NodeList of '.modal' elements
// and then iterate over them:
document.querySelectorAll('.modal').forEach(
(modal) => {
// we're initially hiding all '.modal' elements:
modal.hidden = true;
});
// iterating over the 'show' elements:
show.forEach(
// passing in two arguments, 'btn' is the reference
// to the current Node in the NodeList, and 'i' is
// the current Node's index in that NodeList:
(btn, i) => {
// here we set the element's data-index attribute by
// setting its dataset.index property to be equal to
// the index of the current 'show' element:
btn.dataset.index = i;
// binding the function of the current modals Object
// as the event-handling function of the 'click' event:
btn.addEventListener('click', this.show);
});
// similar to the above, but binding the hide() function
// of the modals Object as the event-handler for the
// 'click' event on each of the 'hide' elements:
hide.forEach(
(btn) => {
btn.addEventListener('click', this.hide);
});
},
};
// initialising the functionality:
modals.init();
*,
::before,
::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
main {
width: 80%;
margin: 0 auto;
}
header {
display: flex;
justify-content: space-between;
}
.box {
text-align: center;
}
<main>
<header>
<div class="box">
<div class="piece">
<h2>Medcom</h2>
<div class="box">
<button class="ibutton trigger">
<h3>Ver video</h3>
</button>
</div>
</div>
</div>
<div class="box">
<div class="piece">
<h2>Juan Valdez</h2>
<div class="xbox">
<button class="ibutton trigger">
<h3>Ver video</h3>
</button>
</div>
</div>
</div>
<div class="box">
<div class="piece">
<h2>Grupo Epasa</h2>
<div class="xbox">
<button class="ibutton trigger">
<h3>Ver video</h3>
</button>
</div>
</div>
</div>
</header>
<div class="videoContent">
<div class="modal">
<div class="modal-content">
<span class="btn-close">
<img src="../../../../../assets/img/close.svg" alt="close">
</span>
<iframe class="player" width="560" height="315" src="https://www.youtube.com/embed/N8ABAZvh8WE" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
</div>
<div class="modal">
<div class="modal-content">
<span class="btn-close">
<img src="../../../../../assets/img/close.svg" alt="close">
</span>
<iframe class="player" width="560" height="315" src="https://www.youtube.com/embed/rn937OyA00g" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
</div>
<div class="modal">
<div class="modal-content">
<span class="btn-close">
<img src="../../../../../assets/img/close.svg" alt="close">
</span>
<iframe class="player" width="560" height="315" src="https://www.youtube.com/embed/EUjWFr3w7RU" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
</div>
</div>
</main>
JS Fiddle demo.
Reference:
CSS:
Attribute selectors ([attribute]).
Negation (:not()) pseudo-class.
HTML:
hidden.
JavaScript:
Arrow function expressions.
Destructuring assignment {a,b} = ObjectName.
document.querySelector().
Element.closest().
Element.setAttribute().
Event.currentTarget
Event.target.
EventTarget.addEventListener().
HTMLElement.hidden.
HTMLOrForeignElement.dataset.
NodeList.prototype.forEach().
Template literals (Template strings).
you can perform the following function in JavaScript
$(function(){
$('.modal').hide();
});
o
Save it in an array and then loop through that array and close one by one with adding the hide class
$(function(){
var arrayModals=$('.modal');
for(var modalObj:arrayModals){
//do stuff here
$(document.find(modalobj).getId()).toggleClass('visible');
}
}):
only do it in the event you want either by clicking or detecting the end of a video
I have a video that I want to show to users on the website, I created a button where they click and it shows a youtube video in popup, but when I close it, it still shows "Playing audio" in the tab and you can hear the video still. How can I achieve when they click X or anywhere else(they can closing it too by clicking anywhere) to actually stops the video and its audio.
$(document).ready(function() {
$('#headerVideoLink').magnificPopup({
type:'inline',
midClick: true // Allow opening popup on middle mouse click. Always set it to true if you don't provide alternative source in href.
});
});
#headerPopup{
width:75%;
margin:0 auto;
}
#headerPopup iframe{
width:100%;
margin:0 auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/magnific-popup.js/1.1.0/jquery.magnific-popup.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/magnific-popup.js/1.1.0/magnific-popup.min.css" rel="stylesheet"/>
<span class="icon-play mr-2"></span>Watch Video</p>
<div id="headerPopup" class="mfp-hide embed-responsive embed-responsive-21by9">
<iframe class="embed-responsive-item" width="854" height="480" src="https://www.youtube.com/embed/qN3OueBm9F4?autoplay=1" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
</div>
Any help will mean a lot, thanks!
What if you use the iframe content type of the MagnificPopup plugin?
So it would look something like this:
$(document).ready(function () {
$('#headerVideoLink').magnificPopup({
type: 'iframe',
midClick: true,
items: {
// HTML markup of popup, `mfp-close` will be replaced by the close button
markup: '<div class="mfp-iframe-scaler">' +
'<div id="headerPopup" class="mfp-hide embed-responsive embed-responsive-21by9">' +
'<iframe class="embed-responsive-item" width="854" height="480" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>' +
'</div>',
patterns: {
youtube: {
// URL that will be set as a source for iframe.
src: 'https://www.youtube.com/embed/qN3OueBm9F4?autoplay=1'
}
},
// Templating object key. First part defines CSS selector, second attribute.
// "iframe_src" means: find "iframe" and set attribute "src".
srcAction: 'iframe_src',
}
});
});
https://dimsemenov.com/plugins/magnific-popup/documentation.html#iframe-type
Or try to clear the iframe source using your original Javascript:
$(document).ready(function () {
$('#headerVideoLink').magnificPopup({
type: 'inline',
midClick: true,
callbacks: {
open: function () {
// Will fire when this exact popup is opened
// this - is Magnific Popup object
},
close: function () {
// Will fire when popup is closed
$('#headerPopup > iframe').attr('src', '');
}
}
});
});
Is it possible to use JQuery to build a youtube video slider? I'd like to display a few ones I uploaded.
Found some answers but made with specific frameworks, if it's possible I'd like to stick with something simple.
I found this code very helpful but I can't seem to make it work.
JSFiddle
$('.play-button').on('click', function () {
$(this).hide();
$(this).parent().fadeOut();
$(this).parent().siblings('.slider-video')[0].play();
});
$('.slider-video').on('play', function () {
$(this).attr('controls', '1');
});
// Additionnal code for the slider
var pos = 0,
slides = $('.slide'),
numOfSlides = slides.length;
function nextSlide(){
stopCurrentVideo();
slides.eq(pos).animate({left:'-100%'},500);
pos = pos >= numOfSlides-1 ? 0 : ++pos;
slides.eq(pos).css({left:'100%'}).animate({left:0},500);
}
function previousSlide(){
stopCurrentVideo();
slides.eq(pos).animate({left:'100%'},500);
pos = pos == 0 ? numOfSlides-1 : --pos;
slides.eq(pos).css({left:'-100%'}).animate({left:0},500);
}
function stopCurrentVideo(){
$('.slider-video:eq('+pos+')').load().removeAttr('controls')
.siblings('.overlay-content').show().find('.play-button').show();
}
$('.left').click(previousSlide);
$('.right').click(nextSlide);
You can achieve this with the YouTube iFrame API:
https://developers.google.com/youtube/iframe_api_reference
This API becomes available when you append enablejsapi=1 to the URLs of YouTube video embeds.
In order to access the controls for stopping videos, for each video you need to access an instance of YT.Player. For each iFrame, I created an instance of YT.Player, and attached it directly to the slide object as a parameter called video.
(Note that many developers say you shouldn't attach data directly to DOM objects, but I did so here because it allowed me to more closely match your original code.)
YT.Player can be accessed through a special function that must be called onYouTubeIframeAPIReady, which I could only get to work if it was outside of $(document).ready.
I can't put my solution on JSFiddle because the iFrames don't play nice, so here's my implementation on GitHub:
http://robertakarobin.github.io/jquery-video-slider
https://github.com/robertakarobin/jquery-video-slider
Here are the relevant bits:
HTML:
<div class="video-slider">
<!-- SLIDE 1 -->
<div class="slide">
<iframe class="video" src="https://www.youtube.com/embed/YE7VzlLtp-4?ecver=2&enablejsapi=1"></iframe>
</div>
<!-- SLIDE 2 -->
<div class="slide">
<iframe class="video" src="https://www.youtube.com/embed/YE7VzlLtp-4?ecver=2&enablejsapi=1"></iframe>
</div>
<!-- END OF SLIDES -->
<div class="slide-arrow left"></div>
<div class="slide-arrow right"></div>
</div>
JavaScript:
$(document).ready(function () {
var pos = 0,
slides = $('.slide'),
numOfSlides = slides.length;
function nextSlide() {
// `[]` returns a vanilla DOM object from a jQuery object/collection
slides[pos].video.stopVideo()
slides.eq(pos).animate({ left: '-100%' }, 500);
pos = (pos >= numOfSlides - 1 ? 0 : ++pos);
slides.eq(pos).css({ left: '100%' }).animate({ left: 0 }, 500);
}
function previousSlide() {
slides[pos].video.stopVideo()
slides.eq(pos).animate({ left: '100%' }, 500);
pos = (pos == 0 ? numOfSlides - 1 : --pos);
slides.eq(pos).css({ left: '-100%' }).animate({ left: 0 }, 500);
}
$('.left').click(previousSlide);
$('.right').click(nextSlide);
})
function onYouTubeIframeAPIReady() {
$('.slide').each(function (index, slide) {
// Get the `.video` element inside each `.slide`
var iframe = $(slide).find('.video')[0]
// Create a new YT.Player from the iFrame, and store it on the `.slide` DOM object
slide.video = new YT.Player(iframe)
})
}
The slider seems to be working fine. Just change the code from Video tag to YouTube Embed Code and you have a Youtube player Carousel.
<div class="video-slider">
<!-- SLIDE 1 -->
<div class="slide">
<div style="position:relative;height:0;padding-bottom:56.28%"><iframe src="https://www.youtube.com/embed/YE7VzlLtp-4?ecver=2" style="position:absolute;width:100%;height:100%;left:0" width="640" height="360" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></div>
</div>
<!-- SLIDE 2 -->
<div class="slide">
<div style="position:relative;height:0;padding-bottom:56.28%"><iframe src="https://www.youtube.com/embed/EngW7tLk6R8?ecver=2" style="position:absolute;width:100%;height:100%;left:0" width="640" height="360" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></div>
</div>
<!-- END OF SLIDES -->
<div class="slide-arrow left"></div>
<div class="slide-arrow right"></div>
</div>
You can get the YouTube Embed Code by right clicking on the video on youtube.com and select Copy Embed Code, and use that code in the slider.
Hope it helps.
I have made a fork of the author fiddle and made the changes. JSFiddle
I have two iframes in one page.
<iframe id="video" width="420" height="315" src="//www.youtube.com/embed/9B7te184ZpQ?rel=0" frameborder="0" allowfullscreen></iframe>
<iframe id="video1" width="420" height="315" src="//www.youtube.com/embed/9B7te184ZpQ?rel=0" frameborder="0" allowfullscreen></iframe>
I want to access onplay() event of iframe, then i can able to stop second video(#Video1) while playing first one(#Video) and Stop first video(#Video) when playing Second(#Video1).
It is possible using YoutubeAPI but i do not want to use that because i have other url videos not Youtube videos(here i put youtube links instead orignal links to avoid copyright). Is there another way except YoutubeAPI. YoutubeAPI is not working on another link resources. Please Suggest.
It has two <iframe>. First, you need switch between iframe.
Is there a way to change context to iframe in javascript console?
After, here my code how to access to event onPlay() of <iframe>
<script src="https://www.youtube.com/iframe_api"></script>
<div class="module module-home-video">
<span class="module-strip">Latest Product Video</span>
<div id="video"></div>
</div>
<script>
var player, playing = false;
function onYouTubeIframeAPIReady() {
player = new YT.Player('video', {
height: '360',
width: '640',
videoId: 'xmhtV4270NU',
events: {
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerStateChange(event) {
if(!playing){
alert('onPlay is clicked');
playing = true;
}
}
</script>