Skip to content
Advertisement

Display different video source according to screen size

I am trying to load different videos according to the screen size. I found a solution to doing this using javascript. However, I am not able to integrate this code into nuxt.js.

Working Code: HTML

<div class="container">
  <div class="row">
    <video id="vid1" class="col-12" loop muted autoplay></video>
    <video id="vid2" class="col-12" loop muted autoplay></video>
  </div>  
</div>

JAVASCRIPT

let videos = {
  "vid1": [
    "https://storage.googleapis.com/coverr-main/mp4/Love-Boat.mp4",
    "https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4"
  ],
  "vid2": [
    "https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4",
    "https://storage.googleapis.com/coverr-main/mp4/Love-Boat.mp4"
  ]
};

function setVideoWithScreen(screen, element) {
  console.log(videos);
  element.setAttribute("type", "video/mp4");
  if (window.innerWidth < screen) {
    element.removeAttribute("src");
    element.setAttribute("src", videos[element.id][0]);
    element.load();
  } else {
    element.removeAttribute("src");
    element.setAttribute("src", videos[element.id][1]);
    element.load();
  }
}

let el = document.querySelectorAll('.video');
for (i = 0; i < el.length; i++) {
  setVideoWithScreen(700, el[i])
}

window.addEventListener("resize", function() {
  let el = document.querySelectorAll('.video')
  for (i = 0; i < el.length; i++) {
    setVideoWithScreen(700, el[i])
  }
});

The Fiddle: https://jsfiddle.net/j78w36er/2/

I tried to integrate like this:

<template>
  <div class="container">
    <div class="row">
      <video id="vid1" class="col-12" loop muted autoplay></video>
      <video id="vid2" class="col-12" loop muted autoplay></video>
    </div>  
  </div>
</template>

export default {
  data () {
    return {
      let videos = {
        "vid1": [
          "https://storage.googleapis.com/coverr-main/mp4/Love-Boat.mp4",
          "https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4"
        ],
        "vid2": [
          "https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4",
          "https://storage.googleapis.com/coverr-main/mp4/Love-Boat.mp4"
        ]
      }
    }
  },
  methods: {
    setVideoWithScreen(screen, element) {
      element.setAttribute("type", "video/mp4");
      if (window.innerWidth < screen) {
        element.removeAttribute("src");
        element.setAttribute("src", videos[element.id][0]);
        element.load();
      } else {
        element.removeAttribute("src");
        element.setAttribute("src", videos[element.id][1]);
        element.load();
      }
    }
  },
  mounted () {
    if (process.browser) {    
      let el = document.querySelectorAll('.video');
      for (i = 0; i < el.length; i++) {
        setVideoWithScreen(700, el[i])
      }

      window.addEventListener("resize", function() {
        let el = document.querySelectorAll('.video')
        for (i = 0; i < el.length; i++) {
          setVideoWithScreen(700, el[i])
        }
      })
   }
 }

I would be very thankful for any kind of help!

Advertisement

Answer

Your code is primarily invalid and not compliant With Vue. The correct code should look like this (.vue file):

<template>
  <div class="container">
    <div class="row">
      <video id="vid1" class="col-12" loop muted autoplay></video>
      <video id="vid2" class="col-12" loop muted autoplay></video>
    </div>  
  </div>
</template>


<script>

export default {
  data () {
    return {
      videos: {
        "vid1": [
          "https://storage.googleapis.com/coverr-main/mp4/Love-Boat.mp4",
          "https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4"
        ],
        "vid2": [
          "https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4",
          "https://storage.googleapis.com/coverr-main/mp4/Love-Boat.mp4"
        ]
      }
    }
  },
  methods: {
    setVideoWithScreen(screen, element) {
      element.setAttribute("type", "video/mp4");
      if (window.innerWidth < screen) {
        element.removeAttribute("src");
        element.setAttribute("src", this.videos[element.id][0]);
        element.load();
      } else {
        element.removeAttribute("src");
        element.setAttribute("src", this.videos[element.id][1]);
        element.load();
      }
    }
  },
  mounted () {
    if (process.browser) {    
      let el = document.querySelectorAll('video');
      for (let i = 0; i < el.length; i++) {
        this.setVideoWithScreen(700, el[i])
      }

      window.addEventListener("resize", () => {
        let el = document.querySelectorAll('video')
        for (let i = 0; i < el.length; i++) {
          this.setVideoWithScreen(700, el[i])
        }
      })
   }
 }
}
</script>

but unfortunately there are a lot of bad practices here that you should keep in mind when writing your code. A few tips from me:

  • study basic concepts of vue, there are lot of vue bugs in data, mounted. Check how vue works in documentation.
  • use debounce function when you work with events like resize, scroll etc.
  • use DRY pattern
  • you can use vue $refs instead of querySelector
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement