# id ДОЛЖЕН быть уникальным
Прежде всего, # id ДОЛЖЕН быть уникальным , нет исключений из этого принципиально важного правила. Так что измените #video-post
на #video-post1
и #video-post2
... еще лучше, просто используйте класс .video-post
на обоих.
Разыменование jQuery Объекты
Тег <video>
управляется Видео API , который является простым JavaScript интерфейсом. Хотя jQuery по сути JavaScript, jQ не может распознать простые JS методы, такие как .play()
или .pause()
. Хотя использование метода .trigger()
для запуска событий возможно, это плохая замена для элемента управления, который обеспечивает API видео.
Чтобы использовать простые JavaScript методы для элемента, на него следует ссылаться как на объект DOM, а не на объект jQuery. Конечно, использование простого JS метода, такого как:
const active = document.querySelector('.active');
let vid = active.querySelector('video');
, является пустым, если у вас уже есть:
let $vid = $('.active').find('video');
К счастью, есть два простых способа конвертировать jQuery объект в объект DOM. Термин называется разыменованием. Продолжая приведенный выше пример:
скобка
$vid[0]
.get()
метод
$vid.get(0);
Достаточно того или другого (они являются эквивалентами).
Демонстрация
Демонстрация ниже - это просто рациональное эффективное использование jQuery. Вы только придерживаетесь этого кода и стиля:
- меньше классов
- без идентификаторов
- использование
this
ключевого слова - поток условий
- использование индексированных позиций
- использование более подходящих jQuery методов
- делегирование события
- шаблон взаимной исключительности
Этот список можно продолжить, и подробности go по любому из этих пунктов позволяют избежать вопроса. Попробуйте демо, примените столько, сколько сможете - к своему собственному коду. Все детали прокомментированы в демоверсии. Удачи.
/*
The next 3 statements are one time initialization steps
- declare index count
- hide al <li> except the active one
- hide all videos (this is done separately for the FX)
*/
let index = 0;
$('.items li').not('.active').hide();
$('video').hide();
/*
click event is delegated to <nav>
any <button> clicked by user is considered "this" (also e.target)
*/
$('.navbar').on('click', 'button', function(e) {
// Declare the last <li> index number
const last = $('.items li').length - 1;
//console.log(last);
/*
These control statements establish:
- if the index number increases or decreases by 1
according to which <button> was clicked
- to cycle as a bi-directional loop
Normally I would use ternary for terseness and less
bloat but I used if/else if/else for readability instead
*/
if ($(this).hasClass('next')) {
index++
if (index > last) {
index = 0;
}
} else {
index--;
if (index < 0) {
index = last;
}
}
//console.log(index);
/*
The next two statements will hide ALL <li> and <video>
tags and ensuring that nothing has the .active class.
NOTE: The last statement is this.pause()
.pause() is a plain JavaScript method thus does not
recognize jQuery objects like $(this) so `this`
keyword must be used instead
*/
$('.items li').removeClass('active').fadeOut('slow');
$('video').each(function(i) {
$(this).slideUp();
this.pause();
});
/*
Assign the .active class to the <li> at the position
designated by current index number
*/
$('.items li').eq(index).addClass('active');
/*
if current active <li> has the .vid class, reveal <li>
and <video> separately for FX...
otherwise just reveal the active <li>
NOTE: The statement: vid[0].play();
.play() is a plain JS method like .pause() and the
variable `$vid` references a jQuery object so $vid
must be de-referenced to be a DOM object that
.play() will recognize.
De-referencing a jQ object can be done by:
- bracket notation: ex. $vid[0]
or
- .get() method: ex. $vid.get(0)
The index number of 0 is required (first reference)
*/
if ($('.active').hasClass('vid')) {
let $vid = $('.active').find('video');
$('.active').fadeIn('fast');
$vid.slideDown('slow');
$vid[0].play();
} else {
$('.active').fadeIn('slow');
}
/*
There are three actions requested:
- stop click event from bubbling*
- prevent any default actions that clicking could
cause*
- terminate function
*the first two above only happen with jQuery
*/
return false;
});
::root,
body {
font: 400 3vw/1 Arial;
}
.ui {
max-width: 420px;
margin: 5vh auto;
}
.navbar {
text-align: center
}
.items {
position: relative;
list-style: none;
padding-left: 0
}
button {
padding: 0;
border: 0;
background: none;
cursor: pointer
}
.items li {
position: absolute;
top: 0;
left: 0;
}
.ico {
font-size: 2.25rem
}
.ico::before {
content: attr(data-ico);
display: inline-block;
vertical-align: top;
}
video {
width: 360px;
height: auto
}
<form class="ui">
<nav class='navbar'>
<button class="ico prev" type='button'>⏪</button>
<button class="ico next" type='button'>⏩</button>
</nav>
<ul class="items">
<li class="ico active" data-ico='?'><a href='#/'>Home</a></li>
<li class='ico' data-ico='?'><a href='#/'>Favorites</a></li>
<li class='ico vid' data-ico='?'>
<video src="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-720p.mp4"></video>
</li>
<li class='ico' data-ico='?'><a href='#/'>Top Topics</a></li>
<li class='ico' data-ico='?'><a href='#/'>Hot Topics</a></li>
<li class='ico vid' data-ico='?'>
<video src="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4"></video>
</li>
</ul>
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>