Isabella
Isabella

Reputation: 137

In JavaScript getAttribute from li element works partially

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>

Upvotes: 1

Views: 95

Answers (5)

Md. Amirozzaman
Md. Amirozzaman

Reputation: 1125

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>

Upvotes: 1

Arnab Banerji
Arnab Banerji

Reputation: 11

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>

Upvotes: 1

tevemadar
tevemadar

Reputation: 13205

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>

Upvotes: 2

Anonymous
Anonymous

Reputation: 12017

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

Upvotes: 1

T. Short
T. Short

Reputation: 3614

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

Upvotes: 1

Related Questions