1

My Js code in the bottom is working properly for first link, but not for the second, even if I refresh the page it works only for first link, any idea how to solve this? thank you.

<div class="container">
    <div class="list">
        <li><a data-video="https://www.youtube.com/embed/PkZNo7MFNFg" href="#">Vido 1</a></li>
        <li><a data-video="https://www.youtube.com/embed/7bE2mI4ePeU" href="#">Vido 2</a></li>
        <br>
        <br>
    </div>
    <div class="vid">
        <iframe id="videos" width="760" height="415" style="background: #ccc;" src="" frameborder="0"
            allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
            allowfullscreen></iframe>
    </div>
</div>

<script>
    let clicked = document.querySelector('a').getAttribute('data-video');
    document.querySelector('a').addEventListener('click', () => {
        document.querySelector('iframe').src = clicked;
    });
</script>

Isabella
  • 137
  • 12
  • 2
    You have to use querySelectorAll instead of querySelector so that it will select all the a tags, please see this https://stackoverflow.com/questions/14377590/queryselector-and-queryselectorall-vs-getelementsbyclassname-and-getelementbyid – Tinu Jos K Dec 25 '19 at 18:12

5 Answers5

2

querySelector()

The Document method querySelector() returns the first Element within the document that matches the specified selector, or group of selectors. If no matches are found, null is returned.

You rather need querySelectorAll

The Document method querySelectorAll() returns a static (not live) NodeList representing a list of the document's elements that match the specified group of selectors.

You need this latter one with a loop, also the event handler should handle the event for deciding what has been clicked:

document.querySelectorAll('a').forEach(item => item.addEventListener('click',
    event => document.querySelector('iframe').src = event.target.getAttribute('data-video')
));

Demo (it just displays text as these snippets are heavily sandboxed here)

document.querySelectorAll('a').forEach(item => item.addEventListener('click',
    event => document.querySelector('.vid').innerText = event.target.getAttribute('data-video')
));
<div class="container">
    <div class="list">
        <li><a data-video="https://www.youtube.com/embed/PkZNo7MFNFg" href="#">Vido 1</a></li>
        <li><a data-video="https://www.youtube.com/embed/7bE2mI4ePeU" href="#">Vido 2</a></li>
        <br>
        <br>
    </div>
    <div class="vid">
    </div>
</div>
tevemadar
  • 12,389
  • 3
  • 21
  • 49
  • I decided to choose your answer because it is more readable and it is much better for minimalist people like me, thank you all. – Isabella Dec 25 '19 at 18:52
1

document.querySelector will only return the first element it finds.

What you want to use is doucment.querySelectorAll(). This will return an array of all the elements that match the query. You can read more about it here:

https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll

T. Short
  • 3,481
  • 14
  • 30
1

You're only adding the listener to the first element. Add it to all of them:

document.getElementsByTagName('a').forEach(e => {
    let clicked = e.getAttribute('data-video');
    e.addEventListener('click', () => {
        document.querySelector('iframe').src = clicked;
    });
});
Anonymous
  • 11,748
  • 6
  • 35
  • 57
  • 1
    Your code worked perfectly by using "querySelectorAll" instead of "getElementsByTagName", thank you. – Isabella Dec 25 '19 at 18:25
1

I think this can work:

    <div class="container">
    <div class="list">
        <li><a data-video="https://www.youtube.com/embed/PkZNo7MFNFg" href="#">Vido 1</a></li>
        <li><a data-video="https://www.youtube.com/embed/7bE2mI4ePeU" href="#">Vido 2</a></li>
        <br>
        <br>
    </div>
    <div class="vid">
        <iframe id="videos" width="760" height="415" style="background: #ccc;" src="" frameborder="0"
                allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
                allowfullscreen></iframe>
    </div>
</div>

    <script>

        let allLinks = document.querySelectorAll('a');
        for (let i = 0; i < allLinks.length; i++) {
            let link = allLinks[i];

            link.addEventListener('click', function () {
                let clicked = this.getAttribute('data-video');
                console.log(`clicked = ${clicked}`);
                document.querySelector('iframe').src = clicked;
            });
        }

    </script>
1

First of all querySelector return only first element,so we need to querySelectorAll to target all elements.So try this one:

<div class="container">
    <div class="list">
        <li><a data-video="https://www.youtube.com/embed/PkZNo7MFNFg" href="#" >Vido 1</a></li>
        <li><a data-video="https://www.youtube.com/embed/7bE2mI4ePeU" href="#">Vido 2</a></li>
        <br>
        <br>
    </div>
    <div class="vid">
        <iframe id="videos" width="760" height="415" style="background: #ccc;" src="" frameborder="0"
            allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
            allowfullscreen></iframe>
    </div>
</div>

<script>
    const vLinks = document.querySelectorAll("a");
    for (const vLink of vLinks) {
        vLink.addEventListener('click', (e) => {
              e.preventDefault();
              document.querySelector('iframe').src=e.target.dataset.video;
              console.log(e.target.dataset.video);
          })
    };
</script>

Another approach is:

<div class="container">
    <div class="list">
        <li><a data-video="https://www.youtube.com/embed/PkZNo7MFNFg" href="#" >Vido 1</a></li>
        <li><a data-video="https://www.youtube.com/embed/7bE2mI4ePeU" href="#">Vido 2</a></li>
        <br>
        <br>
    </div>
    <div class="vid">
        <iframe id="videos" width="760" height="415" style="background: #ccc;" src="" frameborder="0"
            allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
            allowfullscreen></iframe>
    </div>
</div>

<script>
    
    window.addEventListener('click', (e) => {
        //action has been taken if target elements has 'data-video' attribute
        if(e.target.dataset.video){
            e.preventDefault();
            document.querySelector('iframe').src=e.target.dataset.video;
            console.log(e.target.dataset.video);
        }
    })
</script>
Md. Amirozzaman
  • 1,083
  • 10
  • 21