如何调整函数使其成为调用它的目标元素



我在Bootstrap 4中编写了以下代码,以便在点击视频时播放/暂停视频,它还切换了视频下方的小扬声器img。

我不想为我页面上的每个视频/img对重复这个函数,有没有办法重写这个函数,使它只影响被点击的视频,并以某种方式使它也更改相应的img?有什么方法可以用Class来做吗?

<div class="col bg-primary p-0" style="width: 100%; max-width: 787px;">
<div class="bg-danger">
<video id="c20-vid" style="width: 100%; max-width: 787px;" preload="metadata" poster="#.png" playsinline loop>
<source src="#.mp4" type="video/mp4">
</video>
</div>
<div class="text-center captions bg-warning">
<img src="img/muted_icon.png" width="15em" id="c20-mute-icon" />
</div>
</div>

这是JavaScript:


function playme() {
// in this case it's the element that was clicked
var video = this;
var muteicon = document.getElementById("c20-mute-icon");

if(video.paused) {
video.play();
muteicon.src="img/unmuted_icon.png";
} 
else {
video.pause();
muteicon.src="img/muted_icon.png";
}
}
document.getElementById("c20-vid").addEventListener("click", playme);

听起来你想做两件事:

  1. 编写一个事件处理程序,它知道其调用上下文,而无需对该上下文进行硬编码
  2. 查找相对于另一个元素的HTML元素

让我们分别处理这些问题,然后看一个同时处理这两个问题的示例。

编写了解其调用上下文的事件处理程序

这就是this的作用:(

来自MDN关于this:的文章

当函数用作事件处理程序时,它的this被设置为侦听器所在的元素(对于使用addEventListener((以外的方法动态添加的侦听器,有些浏览器不遵循此约定(。

简单地说,this是一个特殊变量,其值根据函数的调用位置而变化。

这个SO问题更彻底地解决了JavaScript中的作用域和上下文。

查找相对于另一个元素的HTML元素

Element.querySelector函数和DOM Node接口的父/子/同级属性的某种组合通常足以完成这项工作。

把它们放在一起

以下是将这些想法应用于HTML结构的片段(封装在外部div中(:

// Define event handler
function toggleMute(e) {
// "this" comes from the calling context
// in this case it's the element that was clicked
var video = this;
// get the video's parent element and find the first img element inside it
var muteicon = video.parentElement.querySelector('img');

// do some stuff with these elements
if(video.muted) {
video.muted = false;
video.style.background = "green"
muteicon.style.background = "yellow";
} 
else {
video.muted = true;
video.style.background = "orange"
muteicon.style.background = "teal";
}
}
// Attach handler to video element, listening for "click" event
document.getElementById('my-vid').addEventListener("click", toggleMute);
video { height: 100px; width: 100px; background: green; }
img { height: 50px; width: 50px; background: yellow; }
<div>
<video id="my-vid">
<source src="my.mp4">
</video>
<br>
<img src="img/muted_icon.png" id="speaker-icon" />
</div>

其他可能性

还有其他方法可以使事件处理程序了解其上下文。您还可以使用在调度事件时公开的事件对象,或者在HTML中显式传递this。请参阅以下示例。我的偏好是避免在HTML中内联设置处理程序,所以我会选择第二种或第三种方法。

function ping(target) {
console.log(target);
target.classList.toggle('pinged');
const next = target.nextElementSibling;
next.classList.toggle('pinged');
next.nextElementSibling.classList.toggle('pinged');

}
function pong() {
console.log(this);
this.classList.toggle('ponged');
this.nextElementSibling.classList.toggle('ponged');
this.previousElementSibling.classList.toggle('ponged');
}
function pang(e) {
console.log(e.target);
e.target.classList.toggle('panged');
const prev = e.target.previousElementSibling;
prev.classList.toggle('panged');
prev.previousElementSibling.classList.toggle('panged');
}
// 'ping' attached to element 'one' inline, in HTML
document.getElementById('two').addEventListener("click", pong);
document.getElementById('three').addEventListener("click", pang);
img {max-height: 200px; max-width: 200px;}
.pinged {filter: sepia(80%)}
.ponged {transform: scale(0.5)}
.panged {opacity: 0.5;}
<img id="one" src="https://www.thewholesomedish.com/wp-content/uploads/2019/06/The-Best-Classic-Tacos-550-500x500.jpg" onclick="ping(this)">
<img id="two" src="https://www.thewholesomedish.com/wp-content/uploads/2019/06/The-Best-Classic-Tacos-550-500x500.jpg">
<img id="three" src="https://www.thewholesomedish.com/wp-content/uploads/2019/06/The-Best-Classic-Tacos-550-500x500.jpg">

在HTML:中

<video id=“my-vid" onclick="toggleMute('my-vid', 'my-img');">
<source src=“my.mp4”>
</video>
<img id="my-img" src="img/muted_icon.png" id=“speaker-icon"  />

在javascipt:中

function toggleMute(vid, img) { // add parameters
var video = document.getElementById(vid); // use parameter
var muteicon = document.getElementById(img); // use parameter

if(video.muted) {
video.muted = false;
muteicon.src="img/unmuted_icon.png";
} 
else {
video.muted = true;
muteicon.src="img/muted_icon.png";
}
}

我不确定这是否是你访问视频以静音的方式——这取决于你自己。

最新更新