JWplayer 7 - добавить активный класс к текущему воспроизводимому видео

Я использую JWplayer 7 (режим рендеринга HTML5) на своем сайте. Я создал проигрыватель с настраиваемым списком воспроизведения, но не могу выделить текущее воспроизводимое видео при нажатии на него.

Есть ли решение добавить собственный класс, например .active, при нажатии на элемент списка.

Это мой код для настройки JWplayer.

var playerInstance = jwplayer("videoCont");
playerInstance.setup({
    image: "{PLAYLIST_IMAGE}",
    autostart: false,
    aspectratio: "16:9",
    playlist : "{NV_BASE_SITEURL}{MODULE_NAME}/player/{RAND_SS}{PLAYLIST_ID}-{PLIST_CHECKSS}-{RAND_SS}{FAKE_ID}/",
    controls: true,
    displaydescription: true,
    displaytitle: true,
    flashplayer: "{NV_BASE_SITEURL}themes/default/modules/{MODULE_NAME}/jwplayer/jwplayer.flash.swf",
    primary: "html5",
    repeat: false,
    skin: {"name": "stormtrooper"},
    stagevideo: false,
    stretching: "uniform",
    visualplaylist: true,
    width: "100%"
  });

И следующий код для создания пользовательского проигрывателя

var list = document.getElementById("show-list");
var html = list.innerHTML;
html +="<ul class='list-group'>"
playerInstance.on('ready',function(){
var playlist = playerInstance.getPlaylist();
for (var index=0;index<playlist.length;index++){
    var playindex = index +1;
    html += "<li class='list-group-item'><span>"+playlist[index].title+"</span><span class='pull-right'><label onclick='javascript:playThis("+index+")' title='Phát "+playlist[index].title+"' class='btn btn-default btn-xs'><i class='fa fa-play'></i></label><label class='btn btn-default btn-xs' href='"+playlist[index].link+"' title='Xem ở cửa sổ mới' target='_blank'><i class='fa fa-external-link-square'></i></label></span></li>"
    list.innerHTML = html;
}
html +="</ul>"
});
    function playThis(index) {
        playerInstance.playlistItem(index);
    }

РЕШЕНИЕ: основано на идее @zer00ne

Добавьте следующий код:

playerInstance.on('playlistItem', function() {
var playlist = playerInstance.getPlaylist();
var index = playerInstance.getPlaylistIndex();
var current_li = document.getElementById("play-items-"+index);
for(var i = 0; i < playlist.length; i++) {
        $('li[id^=play-items-]').removeClass( "active" )
}
current_li.classList.add('active');
});

до

function playThis(index) {
    playerInstance.playlistItem(index);
}

И отредактируйте html, сгенерированный следующим образом:

    html += "<li id='play-items-"+index+"' class='list-group-item'><span>"+playlist[index].title+"</span><span class='pull-right'><label onclick='javascript:playThis("+index+")' title='"+lang_play+" "+playlist[index].title+"' class='btn btn-primary btn-xs mgr_10'><i class='fa fa-play'></i></label><a href='"+playlist[index].link+"' title='"+lang_new_window+"' target='_blank'><label class='btn btn-default btn-xs'><i class='fa fa-external-link-square'></i></label></a></span></li>"

С добавлением id='play-items-"+index+"' для определения уникального класса для каждого элемента списка.


person Aluminum Gates    schedule 21.10.2015    source источник
comment
Я считаю, что решил вашу проблему, пожалуйста, просмотрите мое решение.   -  person zer00ne    schedule 27.10.2015
comment
Спасибо, @zer00ne! Ваш код очень помог мне найти решение, совместимое с моим сайтом. Когда я попробовал ваш код, консоль Firefox показала, что не определяет li[i]. Я думаю, нам придется работать с этой проблемой.   -  person Aluminum Gates    schedule 28.10.2015
comment
Хм. Попробуйте заменить: current_li.classList.add('active'); на current_li.className = 'active';   -  person zer00ne    schedule 28.10.2015
comment
Ва! При замене на current_li.className = 'active'; класс oringin (в данном случае list-group-item) полностью заменяется на active вместо добавления нового класса. Я думаю, что classList.add - безопасный метод.   -  person Aluminum Gates    schedule 28.10.2015
comment
Если Firefox не принимает li[i], то HTMLCollection, вероятно, необходимо преобразовать в настоящий массив. Ожидание обновления.   -  person zer00ne    schedule 28.10.2015
comment
Хорошо, смотрите обновление, я тестировал его с Firefox до и после этого обновления, и проблем не возникло. Вы используете Mac? Или вы интегрируете больше моего кода в свой код?   -  person zer00ne    schedule 28.10.2015
comment
Привет @zer00ne! Я попробовал ваш код обновления. Сейчас я использую последнюю версию FF в Windows 10 и последней версии Chrome. FF возвращает There was an error calling back an event handler for "playlistItem". Error: li[i] is undefined В Chrome возвращает There was an error calling back an event handler for "playlistItem". Error: Cannot read property 'classList' of undefined   -  person Aluminum Gates    schedule 29.10.2015
comment
Очень озадачивает, я использую Chrome и FF Win8, и он работает нормально, и я не получаю никаких ошибок. i.imgur.com/pRjSOAy.png i.imgur.com/uQ1ie78.png   -  person zer00ne    schedule 29.10.2015


Ответы (2)


ОБНОВЛЕНИЕ

У Firefox есть проблема с li[i], так как это HTMLCollection (nodeList), а не исходящий из querySelectorAll(). Необходимо добавить один дополнительный шаг, чтобы преобразовать li[i] в ​​настоящий массив. Обновление включает функцию под названием nodeList2Array(sel).

ОБНОВЛЕНИЕ

Я неправильно истолковал запрос ОП:

Есть ли решение добавить собственный класс, например .active, при нажатии на элемент списка.

Итак, что необходимо, так это манипулировать сгенерированными <li>s пользовательского списка воспроизведения.

РЕШЕНИЕ

Добавьте это после остальной части скрипта:

jw.on('playlistItem', function() {
    var playlist = jw.getPlaylist();
    var idx = jw.getPlaylistIndex();
    //var li = document.querySelectorAll('.group-list-item');
    var li = nodeList2Array('.group-list-item');

    for(var i = 0; i < playlist.length; i++) {
        if(i === idx) {
            li[i].classList.add('active');
        }
        else {
            li[i].classList.remove('active');
        }
    }
});

function nodeList2Array(sel) {
    var li = Array.prototype.slice.call(document.querySelectorAll(sel));
    return li;
}

ДЕМО

!!!ВАЖНО ПРОЧТИТЕ ЭТО!!!

Следующая демонстрация ОПРЕДЕЛЕННО РАБОТАЕТ, но вам нужно ввести свой собственный ключ, чтобы она заработала. У JW7 нет бесплатной версии, как у JW6.

var jw = jwplayer("media1");
jw.setup({
  playlist: "https://content.jwplatform.com/feeds/13ShtP5m.rss",
  displaytitle: false,
  width: 680,
  height: 360
});

var list = document.querySelector(".group-list");
var html = list.innerHTML;

jw.on('ready', function() {
  var playlist = jw.getPlaylist();
  for (var idx = 0; idx < playlist.length; idx++) {
    html += "<li class='group-list-item' title='" + playlist[idx].title + "'><a href='javascript:playThis(" + idx + ");'><img height='75' width='120' src='" + playlist[idx].image + "'><figcaption>" + playlist[idx].title + "</figcaption></a></li>";
    list.innerHTML = html;
  }
});

//SOLUTION~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

jw.on('playlistItem', function() {
  var playlist = jw.getPlaylist();
  var idx = jw.getPlaylistIndex();
  var li = document.querySelectorAll('.group-list-item');
  for (var i = 0; i < playlist.length; i++) {
    if (i === idx) {
      li[i].classList.add('active');
    } else {
      li[i].classList.remove('active');
    }
  }
});
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function playThis(idx) {
  jw.playlistItem(idx);
}
html {
  box-sizing: border-box;
  font: 400 16px/2 small-caps"Trebuchet MS";
  height: 100vh;
  width: 100vw;
}
*,
*:before,
*:after {
  box-sizing: inherit;
  margin: 0;
  padding: 0;
  border: 0 solid transparent;
  outline: 0;
  text-indent: 0;
}
body {
  height: 100%;
  width: 100%;
  background: #000;
  color: #FFF;
  position: relative;
}
#main {
  margin: auto;
  width: 680px;
}
#frame1 {
  position: absolute;
  top: 12.5%;
  left: 25%;
}
.jwp {
  position: relative;
}
.group-list {
  position: relative;
  list-style-type: none;
  list-style-position: inside;
}
.group-list li {
  list-style: none;
  display: inline-block;
  float: left;
  padding: 15px 0 0 11px;
  line-height: 2;
}
.group-list a {
  text-decoration: none;
  display: inline-block;
  background: #000;
  border: 1px solid #666;
  border-radius: 8px;
  height: 75px;
  width: 120px;
  text-align: center;
}
.group-list a:hover,
.group-list a:active {
  border: 1px solid #ff0046;
  border-radius: 8px;
  color: #FFF;
  background: hsla(180, 60%, 50%, .4);
}
img {
  display: block;
}
.active {
  background: hsla(180, 60%, 50%, .4);
  outline: 3px solid #0FF;
}
.active figcaption {
  color: #000;
}
<!doctype html>
<html>

<head>
  <meta charset="utf-8">
  <title>JWplayer 7 - Add active class to current playing video</title>
  <meta name="SO33252950" content="http://stackoverflow.com/questions/33252950/jwplayer-7-add-active-class-to-current-playing-video">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">

  <script src="https://d1jtvmpy1cspce.cloudfront.net/lib/jw/7/jwplayer.js"></script>
  <script>
    jwplayer.key = "/*........::::::45_Alphanumerics::::::........*/"
  </script>
</head>

<body>
  <main id="main">
    <section id="frame1" class="frame">
      <div id="media1" class="jwp">Loading...</div>
      <ul id="list1" class="group-list"></ul>
    </section>
  </main>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>

</body>

</html>


СТАРЫЙ


Конечно, можно добавить класс, такой как .active, а затем применить стили таким образом, но JW7 имеет обширную документацию по CSS Skin. Я стилизовал кожу, используя технику, описанную здесь:

https://glpro.s3.amazonaws.com/_util/smpte/jwp.html

ДЕМО

https://glpro.s3.amazonaws.com/_util/smpte/jwp.html

/* Allows you to adjust the color of the playlist item when hovering and has a different active style.*/

.jw-skin-stormtrooper .jw-playlist-container .jw-option:hover,
.jw-skin-stormtrooper .jw-playlist-container .jw-option.jw-active-option {
  background-color:  hsla(210,100%,20%,1);
}

/* Changes the color of the label when hovering.*/

.jw-skin-stormtrooper .jw-playlist-container .jw-option:hover .jw-label {
  color: #0080ff;
}

/* Sets the color of the play icon of the currently playing playlist item.*/
.jw-skin-stormtrooper .jw-playlist-container .jw-label .jw-icon-play {
  color: #0080ff;
}

/* Sets the color of the playlist title */
.jw-skin-stormtrooper .jw-tooltip-title {
    background-color: #000;
    color: #fff
}

/* Style for playlist item, current time, qualities, and caption text.*/
.jw-skin-stormtrooper .jw-text {
  color: #aed4ff;
}

/* Color for all buttons when they are inactive. This is over-ridden with the 
inactive configuration in the skin block.*/
.jw-skin-stormtrooper .jw-button-color {
  color: #cee2ec;
}


/* Color for all buttons for when they are hovered on. This is over-ridden with the 
active configuration in the skin block.*/

.jw-skin-stormtrooper .jw-button-color:hover {
  color: #00e;
}


/* Color for when HD/CD icons are toggled on. */
.jw-skin-stormtrooper .jw-toggle {
  color:  #0080ff;
}

/* Color for when HD/CD icons are toggled off. */
.jw-skin-stormtrooper .jw-toggle.jw-off {
  color: #ffffff;
}
person zer00ne    schedule 22.10.2015
comment
Спасибо @zer00ne! Но похоже, вы неправильно поняли мой вопрос. Я имею в виду, что когда мы нажимаем на элемент, JWP будет воспроизводить этот клип, и я попытался добавить новый класс к этому элементу ‹li›, чтобы показать, какой клип воспроизводится. - person Aluminum Gates; 23.10.2015

Спасибо за идею @zer00ne! Ваш код не полностью работает с моим сайтом, но дает решение.

playerInstance.on('playlistItem', function() {
var playlist = playerInstance.getPlaylist();
var index = playerInstance.getPlaylistIndex();
var current_li = document.getElementById("play-items-"+index);
for(var i = 0; i < playlist.length; i++) {
        $('li[id^=play-items-]').removeClass( "active" )
}
current_li.classList.add('active');
});

Этот код удалит все «активные» из каждого элемента li и найдет правильный идентификатор с текущим индексом воспроизведения, а затем добавит «активный» класс.

person Aluminum Gates    schedule 28.10.2015