skip to Main Content

I’m using a Learning Management System where users can add YouTube videos, which are then embedded using the iframe tag. They are not embedded responsively automatically. However, I found this JavaScript to wrap the YouTube videos in a div to make them embed responsive:

var embedItem = document.querySelectorAll('iframe[src*="youtube"]');
  embedItem.forEach(function(eachEmbed){
    let wrapper = document.createElement('div');
    wrapper.classList.add('embed-responsive');
    wrapper.classList.add('embed-responsive-16by9');
    wrapper.appendChild(eachEmbed.cloneNode(true));
    eachEmbed.replaceWith(wrapper);
});

This result in a YouTube video being wrapped as follow in HTML:

<div class="embed-responsive embed-responsive-16by9">
     <iframe class="embed-responsive-item" src="https://www.youtube.com/embed/jTwdtMzZMds" allowfullscreen="true" title="YouTube video">
     </iframe>
</div>

This works great, but now, I want to wrap this element in another div <div class="video-wrapper rounded">

Basically the output I want for the original iframe tag is:

<div class="video-wrapper rounded">
      <div class="embed-responsive embed-responsive-16by9">
            <iframe class="embed-responsive-item" src="https://www.youtube.com/embed/jTwdtMzZMds"
                     allowfullscreen="true" title="YouTube video"></iframe>
      </div>
</div>

But I cannot figure out how I can tweak the javascript I found to perform this function automatically. Can anyone adapt the javascript code to perform this function? Does anyone know how to do this?

2

Answers


  1. var embedItem = document.querySelectorAll('iframe[src*="youtube"]');
      embedItem.forEach(function(eachEmbed){
        const container = document.createElement('div');
        container.classList.add('video-wrapper');
        container.classList.add('rounded');
        const wrapper = document.createElement('div');
        wrapper.classList.add('embed-responsive');
        wrapper.classList.add('embed-responsive-16by9');
        wrapper.appendChild(eachEmbed.cloneNode(true));
        container.appendChild(wrapper)
        eachEmbed.replaceWith(container);
    });
    Login or Signup to reply.
  2. I’ve assumed that you’re using Bootstrap 4 on your website based on the class names.

    As you can see here, you don’t actually need another div. You can apply the new classes to the div created in your existing code to achieve the rounded corners.

    Note that I’ve added overflow-hidden to the class list. This is necessary to apply the border radius to the inner elements.

    body {
      padding: 3rem; /* for demo only */
    }
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
    
    <div class="embed-responsive embed-responsive-16by9 video-wrapper rounded overflow-hidden">
      <iframe class="embed-responsive-item" src="https://www.youtube.com/embed/jTwdtMzZMds" allowfullscreen="true" title="YouTube video"></iframe>
    </div>

    Then, no need to call classList.add() repeatedly. Just put all the classes in a list.

    I’ve updated variable names here. They weren’t particularly semantic (singular vs. plural), and the repeat made things a bit confusing.

    const embedItems = document.querySelectorAll('iframe[src*="youtube"]');
    
    embedItems.forEach(function(item) {
      let wrapper = document.createElement('div');
    
      wrapper.classList.add(
        'embed-responsive',
        'embed-responsive-16by9',
        'video-wrapper',
        'rounded',
        'overflow-hidden'
      );
    
      wrapper.appendChild(item.cloneNode(true));
      item.replaceWith(wrapper);
    });
    body {
      padding: 3rem; /* for demo only */
    }
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
    
    <iframe class="embed-responsive-item" src="https://www.youtube.com/embed/jTwdtMzZMds" allowfullscreen="true" title="YouTube video"></iframe>

    Now, if you actually do need another element for reasons I’m not aware of, you can work in another level of wrapping.

    const embedItems = document.querySelectorAll('iframe[src*="youtube"]');
    
    embedItems.forEach(function(item) {
      let innerWrapper = document.createElement('div');
      innerWrapper.classList.add(
        'embed-responsive',
        'embed-responsive-16by9'
      );
      innerWrapper.appendChild(item.cloneNode(true));
    
      let outerWrapper = document.createElement('div');
      outerWrapper.classList.add(
        'video-wrapper',
        'rounded',
        'overflow-hidden'
      );
    
      outerWrapper.appendChild(innerWrapper);
      item.replaceWith(outerWrapper);
    });
    body {
      padding: 3rem;
      /* for demo only */
    }
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
    
    <iframe class="embed-responsive-item" src="https://www.youtube.com/embed/jTwdtMzZMds" allowfullscreen="true" title="YouTube video"></iframe>

    Since you are using Bootstrap, and therefore have the jQuery library available, I’ll offer a simple replacement for all this as an alternative.

    $('iframe[src*="youtube"]').each(function() {
      $(this) // <-- refers to the currently looped element
        // note the outside-in order here
        .wrap('<div class="video-wrapper rounded overflow-hidden"></div>')
        .wrap('<div class="embed-responsive embed-responsive-16by9"></div>');
    });
    body {
      padding: 3rem;
      /* for demo only */
    }
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
    
    <iframe class="embed-responsive-item" src="https://www.youtube.com/embed/jTwdtMzZMds" allowfullscreen="true" title="YouTube video"></iframe>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search