Instructions on how to automatically play multiple video tags on one HTML page while also opening a modal

I'm working on an HTML page that needs to display two different videos in separate modals.

My goal is to have each video start playing automatically when the play-video icon is clicked and the modal opens. I attempted this using the code snippet (video.forEach(video => video.play());), but both videos start playing simultaneously.

Additionally, I need the video to pause and the modal to close if the user clicks outside of the modal or on the modal-close area. To achieve this, I used the following code: (video.forEach(video => video.pause());).

The task must be completed with JavaScript alone.

Your assistance in advance is greatly appreciated.

// modal and video
var modal = document.getElementsByClassName("modal");
var playVideo = document.getElementsByClassName("play-video");
var modalClose = document.getElementsByClassName("modal--close");
var video = document.querySelectorAll('video');
function setDataIndex() {
   for (i = 0; i < playVideo.length; i++){
        playVideo[i].setAttribute('data-index', i);
        modal[i].setAttribute('data-index', i);
        modalClose[i].setAttribute('data-index', i);
        video.forEach(video => video.play());
   }
}
for (i = 0; i < playVideo.length; i++){
     playVideo[i].onclick = function() {
     var ElementIndex = this.getAttribute('data-index');
     modal[ElementIndex].style.display = "block";
    };
    modalClose[i].onclick = function() {
       var ElementIndex = this.getAttribute('data-index');
       modal[ElementIndex].style.display = "none";
       video.forEach(video => video.pause());
    };
}
window.onload = function() {
   setDataIndex();
};
window.onclick = function(event) {
      if (event.target === modal[event.target.getAttribute('data-index')]) {
          modal[event.target.getAttribute('data-index')].style.display = "none";
          video.forEach(video => video.pause());
   }
};
// modal and video
:root{
    /* colors */
    --cws: #121214;         /*color name: Woodsmoke               RGB: 18, 18, 20              */
    --clo: #2A827c;         /*color name: Lochinvar               RGB: 42, 130, 124            */
    --cpr: #3CBBB0;         /*color name: Puerto Rico             RGB: 60, 187, 176            */
    --cwa: #7C809B;         /*color name: Waterloo                RGB: 124, 128, 155           */
    --csp: #F5EDF0;         /*color name: Soft Peach              RGB: 245, 237, 240           */
    --cwh: #FFFFFF;         /*color name: White                   RGB: 255, 255, 255           */
}
.play-video{
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background-color: green;
}

/* modal */
.modal{
    display: none;
    position: fixed;
    z-index:13;
    left: 0;
    top: 0;
    bottom: 0;
    right: 0;
    width: 100%;
    height: 100%;
    overflow-y: hidden; 
    background: rgba(124, 128, 155,.8); 
}

.modal.active{
    display: flex;
    align-items: center;
    justify-content: center;
}

.modal--content {
    margin: auto;
    width: 50%;
    height: auto;
    border-radius: 20px;
    -webkit-border-radius: 20px;
    -moz-border-radius: 20px;
    -ms-border-radius: 20px;
    -o-border-radius: 20px;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    -webkit-transform: translate(-50%, -50%);
    -moz-transform: translate(-50%, -50%);
    -ms-transform: translate(-50%, -50%);
    -o-transform: translate(-50%, -50%);
}

.modal--header{
    text-align: right;
    position: absolute;
    top: 20px;
    right: 30px;
}

.modal--close{
    color: var(--cws);
    font-size: 3rem;
    transition: all .5s;
    -webkit-transition: all .5s;
    -moz-transition: all .5s;
    -ms-transition: all .5s;
    -o-transition: all .5s;
}
  
.modal--close:hover,
.modal--close:focus {
    color: var(--csp);
    cursor: pointer;
}

.modal--body{
    width: 100%;
    height: 100%;
}

.modal--body video{
    width: 100%;
    height: 100%;
    border-radius: 10px;
    -webkit-border-radius: 10px;
    -moz-border-radius: 10px;
    -ms-border-radius: 10px;
    -o-border-radius: 10px;
    border: 15px solid var(--csp);
}
/* modal */
<!--  icon play -->
<div class="play-video"></div>
<div class="play-video"></div>
<!--  icon play -->

<!-- The Modal -->
<div class="modal">
     <div class="modal--header">
           <span class="modal--close">&times;</span>
     </div>
     <div class="modal--content">
           <div class="modal--body">
                <video controls class="inlineVideo" autoplay="autoplay">
                  <source src="https://www.youtube.com/watch?v=sgNkCrAhTGc" >
           </video>
      </div>
   </div>
</div>
<!-- The Modal -->

<!-- The Modal -->
<div class="modal">
     <div class="modal--header">
           <span class="modal--close">&times;</span>
     </div>
     <div class="modal--content">
           <div class="modal--body">
                <video controls class="inlineVideo" autoplay="autoplay">
                  <source src="https://www.youtube.com/watch?v=YZ0cJiVr2-w" >
           </video>
      </div>
   </div>
</div>
<!-- The Modal -->

Answer №1

// Handling modals and videos
var modalElements = document.getElementsByClassName("modal");
var playVideoElements = document.getElementsByClassName("play-video");
var modalCloseElements = document.getElementsByClassName("modal--close");
var videoElements = document.querySelectorAll('video');

function setElementIndexes() {
   for (var i = 0; i < playVideoElements.length; i++){
        playVideoElements[i].setAttribute('data-index', i);
        modalElements[i].setAttribute('data-index', i);
        modalCloseElements[i].setAttribute('data-index', i);
        videoElements[i].setAttribute('data-index', i);
   }
}

for (var i = 0; i < playVideoElements.length; i++){
     playVideoElements[i].onclick = function() {
       var elementIndex = this.getAttribute('data-index');
       modalElements[elementIndex].style.display = "block";
    };
    
    modalCloseElements[i].onclick = function() {
       var elIndex = this.getAttribute('data-index');
       modalElements[elIndex].style.display = "none";
       videoElements.forEach(video => video.pause());
    };
}
window.onload = function() {
   setElementIndexes();
};

window.onclick = function(event) {
      if (event.target === modalElements[event.target.getAttribute('data-index')]) {
          modalElements[event.target.getAttribute('data-index')].style.display = "none";
          videoElements[elementIndex].play();
   }
};
// Modal and Video functionality

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Limiting page entry with passport.js and express middleware

My server is set up to authenticate user login. I have successfully redirected users to the success page after authentication (and back to the login page if it fails). However, I am facing an issue with using my own express middleware to restrict access fo ...

Encountering issues with gulp-angular-templatecache while processing angular templates through pipelining

I've encountered an issue with gulp-angular-templatecache in my gulpfile. Here's the task causing trouble: gulp.task('templates', function() { return gulp.src(paths.angularTemplates) .pipe(templateCache()) ...

Is Apache required for running NodeJs?

Recently, I set up a web project on my local machine following a tutorial. With the help of XAMPP, I was able to install MySQL and Apache to run my Node.JS backend. Now, I'm looking into hosting the project on an external server to make it accessible ...

Eliminate Bootstrap's styling from HTML characters

The default heavy checkmark (✔) appears as "✔" Bootstrap 4.3 seems to be altering the appearance of the check, causing it to display as a thick-green one, which is not what I prefer -- see example below I want to remove Bootstrap's styli ...

How to use jQuery to highlight the parent element when clicking on a child element?

I'm struggling with some HTML code that looks like the following: <ul> <li class="curent"><a href="home.html">Home</a></li> <li> <a href="javascript:void(0)">Products</a> <ul ...

How can I place text on top of an image with a filter using Bootstrap?

I am facing a challenge of overlaying text on an image with a tinted background color and opacity. While working with Bootstrap 4, I suspect that some classes might be conflicting with each other. This is my current setup: Index.cshtml: <div class=" ...

Can someone help me troubleshoot the issue with my submit button's onclick function?

I am currently working on a project where I have a content box enclosed in a div tag. Within this content box, there are paragraphs with unique IDs for individual styling rules. I have set margins, padding, and other styles accordingly. At the bottom of th ...

A guide on embedding the flag status within the image tag

I would like to determine the status of the image within the img tag using a flag called "imagestatus" in the provided code: echo '<a href="#" class="swap-menu"><img id="menu_image" src="images/collapsed.gif" hspace = "2"/>'.$B-> ...

Custom Wikipedia HTML template for a unique and immersive user experience

I am looking to develop a wiki website similar to Wikipedia using .Net, but I am having difficulty finding an HTML template that resembles it. Can anyone provide information on the template or framework used by Wikipedia and where I can get it? ...

Simple linking inside a Div container

I'm working on a div that has the following markup: <div class="col-sm-12"> <p class="bg-info">Basic Information</p> </div> Here's how it currently looks: I want to add an 'Add /Edit' link to t ...

Troubleshooting the issue of browser prefix injections not functioning properly in Vue when using the

I've spent an entire afternoon on this issue and I'm completely stuck. After realizing that IE11 doesn't support grid-template, I learned that I need to use -ms-grid-columns and -ms-grid-rows instead. I am attempting to generate CSS and inje ...

Creating a new array in Vue.js by filtering the results of a promise iteration

Is there a way to use the splice method to insert promise values from an old array into a new one for vue reactivity? I'm encountering an issue where the newArray remains empty and does not receive any values. Check out this link for more information. ...

Position a single div on the left-hand side and arrange two divs on the right using display:flex

Is there a way to achieve this layout without adding another div, using only parents and 3 child elements? I had tried using height: max-content, but it didn't work as expected. .container { display: flex; flex-wrap: wrap; } .item { flex-bas ...

Utilize JavaScript to trigger a div pop-up directly beneath the input field

Here is the input box code: <input type='text' size='2' name='action_qty' onmouseup='showHideChangePopUp()'> Along with the pop-up div code: <div id='div_change_qty' name='div_change_qty&ap ...

Conflicting events arising between the onMouseUp and onClick functions

I have a scrollbar on my page that I want to scroll by 40px when a button is clicked. Additionally, I want the scrolling to be continuous while holding down the same button. To achieve this functionality, I implemented an onClick event for a single 40px s ...

Show the cost on the HTML page according to the chosen currency option

I am currently dealing with two primary currencies in my business. The product page is created using HTML. There are 4 products on a single page, and I wish to display two prices for each product based on the selected currency (USD or EUR) without having t ...

How do I test Pinia by calling one method that in turn calls another method, and checking how many times it has been called

As I embark on my journey with Vue 3 and Pinia, a particular question has been lingering in my mind without a concrete answer thus far. Let's delve into the crux of the matter... Here's an example of the store I am working with: import { ref, co ...

Navigating Date Conversion within Component in Angular 2 Application

Searching for a way to update the display of certain dates in my Angular 2 application, I encountered a roadblock. Using the date pipe in conjunction with string interpolation wasn't viable due to the structure of my template code: <input class="a ...

Updating the state of an object nested within another object in React JS

So, I have a nested object within another object and I need to update the state of one or more properties in the inner object. This is my current state: const [products, setProducts] = useState({ name: '', type: '', price: '& ...

Incrementing numbers with jQuery append autoincrement

I am working with a dynamic list of input fields, each one with a unique incremental name. Here's an example structure... <input type="text" name="values[0]" value="some text"> <input type="text" name="values[1]" value="some other text"> ...