Home > Enterprise >  How can I wrap two separate divs around an iframe using JavaScript?
How can I wrap two separate divs around an iframe using JavaScript?

Time:09-16

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 >
     <iframe  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 >

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

<div >
      <div >
            <iframe  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?

CodePudding user response:

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);
});

CodePudding user response:

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 >
  <iframe  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  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  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 ></div>')
    .wrap('<div ></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  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>

  • Related