Reputation: 137
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
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
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
Reputation: 13205
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
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
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