Похоже, вы хотите сделать две вещи:
- Напишите обработчик событий, который знает о своем контексте вызова, без жесткого кодирования этого контекста.
- Найдите элемент HTML относительно другого элемента.
Давайте рассмотрим их по отдельности, а затем рассмотрим пример, который делает и то, и другое.
Написание обработчика событий который знает о контексте его вызова
Это то, для чего this
:)
Из статьи MDN на this
:
Когда функция используется в качестве обработчика событий, this устанавливается на элемент, на котором размещен слушатель (некоторые браузеры не следуют этому соглашению для слушателей, динамически добавляемых методами, отличными от addEventListener ()).
Проще говоря, this
- это специальная переменная, значение которой изменяется в зависимости от того, откуда вызывается функция.
Этот вопрос SO касается областей и контекстов в JavaScript подробнее тщательно .
* 10 35 * Поиск элемента HTML относительно другого элемента
Некоторая комбинация Element.querySelector и свойств родительского / дочернего / родственного интерфейса узла DOM обычно достаточно, чтобы выполнить эту работу.
Собираем все вместе
Вот фрагмент, который применяет эти идеи к вашей 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>
Дополнительные возможности
Есть и другие способы информировать обработчик событий о своем контексте. Вы также можете использовать объект события, который отображается при отправке события, или явно передать this
в HTML. См. Примеры ниже. Я предпочитаю избегать встроенных обработчиков в 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;}