I am trying to have users click a play button, watch a case study video, and have the video go back to its original state once done playing. The issue is that when adding multiple case studies on one page the getElementById(), not only is invalid HTML, but it also plays the wrong case study video or it won't play at all.
I read online that getElementsByName or getElementsByClassName could be an alternative, but I can't get them to work.
Case study HTML block (this gets repeated on the page)
<div class="caseStudy">
<button id="playButton"></button>
<div id="casestudyPoster" class="caseStudy_poster"></div>
<iframe class="caseStudy_video" src="<vimeo-url-here>" width="100%" height="100%" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" webkitallowfullscreen mozallowfullscreen allowfullscreen>
</iframe>
</div>
JavaScript:
var poster = document.getElementById("casestudyPoster");
var button = document.getElementById("playButton");
poster.onclick = function() { fadeImage() };
button.onclick = function() { fadeImage() };
function fadeImage() {
poster.style.visibility = "hidden";
button.style.visibility = "hidden";
var iframe = document.querySelector('iframe');
var player = new Vimeo.Player(iframe);
player.play();
player.on('ended', function(data){
poster.style.visibility = "visible";
button.style.visibility = "visible";
});
}
How can I get this JavaScript to work with multiple caseStudys?
The issue is you are binding your JavaScript functionality to only one element, whereas you desire to bind your JavaScript functionality to multiple elements.
Here is an example of A) collecting several similar elements B) binding unique events to their unique properties.
// Gather all your similar elements
const videoElements = document.querySelectorAll( '.video-element' );
// For each element, let's do something with it.
videoElements.forEach( ( vidEl ) => {
// For this current element, lets create useful variables from elements found within it.
const playButton = vidEl.querySelector( '.play-button' );
const dynamicText = vidEl.querySelector( '.dynamic-text' );
// For this current element's play button, let's bind a unique event to it.
playButton.onclick = () => { dynamicText.innerHTML = `Video Playing!` };
} );
.video-element {
border: 1px solid;
margin: 1rem;
}
<div class="video-element">
<h2>Video 1</h2>
<button class="play-button">Play</button>
<span class="dynamic-text">I have my own functionality!</span>
</div>
<div class="video-element">
<h2>Video 2</h2>
<button class="play-button">Play</button>
<span class="dynamic-text">I have my own functionality!</span>
</div>
<div class="video-element">
<h2>Video 3</h2>
<button class="play-button">Play</button>
<span class="dynamic-text">I have my own functionality!</span>
</div>
<div class="video-element">
<h2>Video 4</h2>
<button class="play-button">Play</button>
<span class="dynamic-text">I have my own functionality!</span>
</div>
Related
i want to build a image button, that plays an audio.
My Version works but when I want to use it more than once on a site, it only play one mp3, not the other ones.
My Code:
<audio loop="false" src="audio_01.mp3"> </audio>
<p><img alt="" class="hover_pic" src="image.png" style="width: 40%;cursor:pointer" /></p>
<script>
var aud = document.getElementById("ASong").children[0];
var isPlaying = false;
aud.pause();
function playPause() {
if (isPlaying) {
aud.pause();
} else {
aud.play();
}
isPlaying = !isPlaying;
}
</script></div>
and
<div id="BSong" onclick="playPause()" type="button">
<audio loop="false" src="audio_02.mp3"> </audio>
<p><img alt="" class="hover_pic" src="image.png" style="width: 40%;cursor:pointer" /></p>
<script>
var aud = document.getElementById("BSong").children[0];
var isPlaying = false;
aud.pause();
function playPause() {
if (isPlaying) {
aud.pause();
} else {
aud.play();
}
isPlaying = !isPlaying;
}
</script></div>
So you have an idea what the problem is that the button only play one of them on the website?
You are using the same variable names multiple times like aud, isPlayig, etc..
To solve this issue, you should declare only once the whole script and form the onclick="playPause()" send the id of the song you want to play.
Be aware if there is already some music which is playing.
It's hard to tell how your two current code snippets are arranged with respect to each other, but duplicating the code over and over every time you want to add another track is going to be unmaintainable. As it stands, the variables for isPlaying and aud probably overwrite each other, depending on how they're laid out, even if they're in different scripts. Using const or let instead of var and use strict; at the top of your script can help detect these aliases.
You could add closures around each one to keep them distinct, but a better approach is to write a loop (which also acts as a scoping closure) and dynamically add the listener to each element. For example:
const trackEls = [...document.querySelectorAll(".track")];
for (const trackEl of trackEls) {
const audioEl = trackEl.querySelector("audio");
trackEl.addEventListener("click", () => {
audioEl.paused ? audioEl.play() : audioEl.pause();
});
}
<div class="tracks">
<div type="button" class="track">
<audio src="https://upload.wikimedia.org/wikipedia/commons/d/d8/Bourne_woods_2020-11-18_0732.mp3"></audio>
<img alt="play track icon" src="http://placekitten.com/50/50" class="track-icon">
</div>
<div type="button" class="track">
<audio src="https://upload.wikimedia.org/wikipedia/commons/e/ea/Rapid-Acoustic-Survey-for-Biodiversity-Appraisal-pone.0004065.s017.ogg"></audio>
<img alt="play track icon" src="http://placekitten.com/50/50" class="track-icon">
</div>
</div>
Note that the above code lets multiple audio files play at once. If you want to stop all other audio elements when a new one is clicked and reset their time, you can do that with a loop or an extra variable that keeps track of the currently-playing track. For example:
const trackEls = [...document.querySelectorAll(".track")];
let currentTrack;
for (const trackEl of trackEls) {
const audioEl = trackEl.querySelector("audio");
trackEl.addEventListener("click", () => {
if (audioEl !== currentTrack) {
if (currentTrack) {
currentTrack.pause();
currentTrack.currentTime = 0;
}
currentTrack = audioEl;
}
audioEl.paused ? audioEl.play() : audioEl.pause();
});
}
<div class="tracks">
<div type="button" class="track">
<audio src="https://upload.wikimedia.org/wikipedia/commons/d/d8/Bourne_woods_2020-11-18_0732.mp3"></audio>
<img alt="play track icon" src="http://placekitten.com/50/50" class="track-icon">
</div>
<div type="button" class="track">
<audio src="https://upload.wikimedia.org/wikipedia/commons/e/ea/Rapid-Acoustic-Survey-for-Biodiversity-Appraisal-pone.0004065.s017.ogg"></audio>
<img alt="play track icon" src="http://placekitten.com/50/50" class="track-icon">
</div>
</div>
A few remarks on your code:
There's no need for isPlaying variables since audio elements already track their playing/paused state with audioElement.paused. If you track it in external state, you add further complication and room for bugs if your variable and the the audio element's state go out of sync.
Avoid putting a <script> in a <div>. <script> is usually a child of <body> or <head> (probably <body> in this case), after all of the HTML tags are closed.
onclick on an HTML element is generally poor practice. HTML should be structural, not behavioral. Similarly, style="width: 40%;cursor:pointer" should be moved to an external stylesheet and applied to a class.
.children[0]; is a brittle way to select the audio element in a track. If you wind up rearranging elements in the div, this code is liable to break. document.querySelector("#BSong audio") is more precise and robust to refactors, although using classes instead of ids enables easier dynamism so you don't have to type each track out by hand.
CSS classes are usually kebab-case, so hover_pic would be hover-pic.
I am using 2 custom buttons and using JavaScript to click the audio play and pause.
I am using the below code for that:
<img class="head-iconn" src="img/audio.png" onClick="document.getElementById('audio1_play32').play(); return false;" />
<img class="head-icon2" src="img/audio2.png" onClick="document.getElementById('audio1_play32').pause(); return false;" />
But I want to stop the audio instead of pause so that when I play it again, it'll start from the beginning.
I am using this code for that:
<img class="head-iconn" src="img/audio.png" onClick="document.getElementById('audio1_play32').play(); return false;" />
<img class="head-icon2" src="img/audio2.png" onClick="document.getElementById('audio1_play32').pause(); document.getElementById('audio1_play32').currentTime = 0;return false;" />
and now the audio stops but can not play again when I click on the first button.
This is the audio code I am using:
<audio id="audio1_play32" controls>
<source src="voice/vo1.mp3" type="audio/mp3"/>
</audio>
Can someone please let me know what I am making mistake?
Thank you.
Update
Although not part of the question OP asked,
"What is I have multiple audios on a single page?"
Simply place the event handler on an element that contains all of the <button>s. Then get the reference to a specific <audio> by proximity of clicked <button>(event.target):
<audio><!--mp3 = btnGroup.previousElementSibling--></audio>
<fieldset>
<!--btnGroup = clicked.parentElement-->
<button><!--clicked = event.target--></button>
</fieldset>
Stay away from using attribute event handlers:
<!-- This is bad -->
<button class='play' onclick='playAudio()'>PLAY</button>
Use .addEventListener()
<button class='play'>PLAY</button>
<script>
const play = document.querySelector('.play');
play.addEventListener('click', playAudio);
</script>
or property event handlers:
<button class='play'>PLAY</button>
<script>
const play = document.querySelector('.play');
play.onclick = playAudio;
</script>
See Event Handlers
Keep your JavaScript separate from HTML or you'll cripple the growth of your code. The example below uses event delegation to determine which button was clicked and what happens according to what was clicked.
const main = document.querySelector('main');
const audioControl = event => {
const clicked = event.target;
const btnGroup = clicked.parentElement;
const mp3 = btnGroup.previousElementSibling;
if (clicked.matches('.play') && !mp3.paused) {
mp3.pause();
} else if (clicked.matches('.play') && !mp3.playing) {
mp3.play();
} else if (clicked.matches('.stop')) {
mp3.pause();
mp3.currentTime = 0;
} else {
return false;
}
};
main.onclick = audioControl;
button {
border: 0;
cursor: pointer;
font-size: 4ch
}
fieldset {
display: inline-block;
}
<main>
<audio src='https://soundbible.com/mp3/thunder_strike_1-Mike_Koenig-739781745.mp3'></audio>
<fieldset>
<button class='play'>⏯️</button>
<button class='stop'>⏹️</button>
</fieldset>
<audio src='https://soundbible.com/mp3/airplane-landing_daniel_simion.mp3'></audio>
<fieldset>
<button class='play'>⏯️</button>
<button class='stop'>⏹️</button>
</fieldset>
<audio src='https://soundbible.com/mp3/old-car-engine_daniel_simion.mp3'></audio>
<fieldset>
<button class='play'>⏯️</button>
<button class='stop'>⏹️</button>
</fieldset>
</main>
I want to make a page to upload the avatar.
By default, I use the vector to show where the image will appear
and then provide a button to upload the URL to change the avatar.
That's all it is! But the script still doesn't work.
Pleased to hear your feedback on how to fix it. Bless
<img id="put_image_here_bitch" src="https://cdn0.iconfinder.com/data/icons/finance-vol-2-4/48/77-512.png" alt="" width="100px" height="100px">
<div class="block" > The person who uploads this is cool
</div>
<button onclick="hideElement()">Click to upload photo by URL</button>
<div>
<input id="input" autofocus class='hidden_element' style="display: none;" type="text" id="input">
</div>
<div>
<button class='hidden_element' style="display: none;" onclick="uploadImage()">UPLOAD</button>
</div>
This is my script
function hideElement(){
var hide = document.getElementsByClassName('hidden_element');
if (hide.style.display === "none") {
hide.style.display = "block";
} else {
hide.style.display = "none";
}
}
var uploadImage = function(){
image = document.getElementById('input').value;
showImage = document.getElementById('put_image_here_bitch').setAttribute('src', image);
};
As stated in the comments, .getElementsByClassName() returns a collection of elements, not a single element and your code attempts to call the style property of the collection, which doesn't exist.
Instead, you need to loop through the collection and operate on the elements within the collection individually, but don't use .getElementsByClassName() and instead use .querySelectorAll().
var hidden = document.querySelectorAll('.hidden_element');
function hideElement(){
// Loop over the colleciton elements
hidden.forEach(function(element){
if (element.style.display === "none") {
element.style.display = "block";
} else {
element.style.display = "none";
}
});
}
var uploadImage = function(){
image = document.getElementById('input').value;
showImage = document.getElementById('put_image_here_bitch').setAttribute('src', image);
};
<img id="put_image_here_bitch" src="https://cdn0.iconfinder.com/data/icons/finance-vol-2-4/48/77-512.png" alt="" width="100px" height="100px">
<div class="block" > The person who uploads this is cool
</div>
<button onclick="hideElement()">Click to upload photo by URL</button>
<div>
<input id="input" autofocus class='hidden_element' style="display: none;" type="text" id="input">
</div>
<div>
<button class='hidden_element' style="display: none;" onclick="uploadImage()">UPLOAD</button>
</div>
But, beyond that, you should also avoid using inline styles as they are the most specific way of setting a style and therefore the hardest to override. They also often require duplicated code to be written. Instead, use CSS classes as shown below:
// Get references to the DOM elements that you'll need to work with
const btnUpload = document.querySelector("button"); // find the first button
const hidden = document.querySelectorAll(".hidden");
const upload = document.querySelector(".upload");
// Do your event binding in JavaScript, not in HTML
btnUpload.addEventListener("click", hideElement);
upload.addEventListener("click", uploadImage);
function hideElement(){
// Loop over the collection of hidden elements
hidden.forEach(function(item){
// See how much more simple it is to work with classes?
item.classList.toggle("hidden");
});
}
function uploadImage(){
showImage = document.getElementById('put_image_here_bitch').setAttribute('src', input.value);
};
.hidden { display:none; }
<img id="put_image_here_bitch" src="https://cdn0.iconfinder.com/data/icons/finance-vol-2-4/48/77-512.png" alt="" width="100px" height="100px">
<div class="block" > The person who uploads this is cool
</div>
<button>Click to upload photo by URL</button>
<div>
<input id="input" autofocus class='hidden' type="text" id="input">
</div>
<div>
<button class='hidden upload'>UPLOAD</button>
</div>
simple.. getElementsByClassName() returns an HTMLCollection with all DOM elements containing that class. An HTMLCollection is like an array ( but not really ) containing element references.
thus you need to define which entry in the array you want to handle ( even if there's only one )
your code should work by simply adding [0] to your DOM read ( the '0' means the first element in the collection )
ex:
var hide = document.getElementsByClassName('hidden_element')[0];
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 page which display 4 small iframes and i have one load more button. What I want is: code for load more button that when button is clicked, it will display more iframes 3 or 5. (i will add these).
I have code for a iframe like this below:
<div style="margin:0px; padding:0px;">
<iframe style="width: 100%; overflow:hidden; margin-top:-0px;" width="400" height="378" src="" allowtransparency="true" frameborder="0"></iframe>
</div>
<button class="btn">Load More</button>
I followed this here but it didnot work for me.
jQuery load first 3 elements, click "load more" to display next 5 elements
Please help me. Thanks
An iframe creater object I created below
initialize the iframe object
add all iframe links when initializing iframe object
add parent container you would like ALL iframeS to be inside. In my example is the body of the document
add an event listener to button which will trigger iframe method name add_iframe()
counter = 0
function iframe_creator(parent, src_array) {
this.src_array = src_array;
this.parent = parent;
this.template = '\
<iframe style="width: 100%; overflow:hidden; margin-top:-0px;" width="400" height="378" src="" allowtransparency="true" frameborder="0"></iframe>\
';
this.add_iframe = function() {
for (i = 0; i < 5; ++i) {
if (counter < this.src_array.length) {
var div = document.createElement('div');
div.innerHTML = this.template;
div.getElementsByTagName('iframe')[0].src = this.src_array[counter];
div.style = "margin:0px; padding:0px;"
this.parent.appendChild(div);
++counter;
} //end if
}
}
}
create_frame = new iframe_creator(document.body, ['https://en.wikipedia.org/wiki/Nature', 'https://en.wikipedia.org/wiki/Nature','https://en.wikipedia.org/wiki/Nature','https://en.wikipedia.org/wiki/Nature','https://en.wikipedia.org/wiki/Nature']);
document.getElementById('button').addEventListener('click', function() {
create_frame.add_iframe()
})
iframe {
border: solid black;
}
<button id="button">
press
</button>
First, give your <div> where you want to place your <iframe>-Tags in an ID so that you can select and interact with it using JS.
Then use JS to create a function which will add a new <iframe>-Tag to your wrapping div.
http://codepen.io/anon/pen/EgdKQp
HTML:
<div id="wrapper"></div>
<button onclick="loadMore()">Load More</button>
JS:
function loadMore() {
var wrapper = document.getElementById('wrapper'); // Get wrapper
var iframe = document.createElement('iframe'); // Create new iframe
wrapper.appendChild(iframe); // Set iframe as child of wrapper
// Set the initial url like this:
iframe.contentWindow.document.location.href = 'http://codepen.io/';
}