Объект для видео
Всем привет. Сейчас изучаю объекты и вот решил сделать небольшой простенький видео плеер при помощи конструктора объектов.
Вот код var all_video = []; function video_designer(){ this.videoBlock; this.video; this.PlayPause; this.StopV; this.fPlay = function(){this.video.play();} } window.onload = function(){ mas_video = document.getElementsByClassName("videoBlock"); for(var i=0; i<mas_video.length; i++){ var newObj = new video_designer; newObj.videoBlock = mas_video[i]; // получаем блок обертку в которой находится видео newObj.video = mas_video[i].childNodes[3]; // получаем видео newObj.PlayPause = mas_video[i].childNodes[5].childNodes[1]; // получаем кнопку при нажатии которой запускается видео newObj.StopV = mas_video[i].childNodes[5].childNodes[3]; // получаем кнопку при нажатии которой выключается видео newObj.PlayPause.addEventListener("click",newObj.fPlay); // добавляем событие к кнопке что бы при нажатии видео начинало проигрываться all_video.push(newObj); // записываем текущий объект видео в массив и создаем новый объект видео если они еще имеются на странице } } Проблема возникает при вызове метода fPlay, не могу понять в чем дело все вроде бы правильно написано, объекты для меня тема новая, поэтому много чего пока что не знаю и не понимаю. Пожалуйста подскажите как решить проблему? Желательно дайте понятный пример решения, мне на примерах как то понятнее понимается :) |
arcmag,
Во первых имена констркторов объектов принято писать с большой буквы. Во вторых у вас в обработчике клика не верный контекст. В третьих не надо объявлять методы объекта в конструкторе, это приводит к перерасходу памяти. Методы надо объявлять в прототипе. /** * @class VideoManager * @param {HTMLVideoElement} video * @param {HTMLElement} playPause * @constructor */ function VideoManager(video, playPause){ /** * Видео элемент * @type {HTMLVideoElement} */ this.video = video; this._setHandlers(playPause); } /** * Назначаем обработчик * @param {HTMLElement} playPause * @private */ VideoManager.prototype._setHandlers = function (playPause) { playPause.addEventListener("click", this.play.bind(this), false); }; VideoManager.prototype.play = function(){ this.video.play(); }; |
То есть надо написать как то так?
var all_video = []; function Video_designer(){ this.videoBlock; this.video; this.PlayPause; this.StopV; } Video_designer.prototype.fPlay = function(){ this.video.play(); }; Video_designer.prototype.fStop = function(){ this.video.stop(); }; window.onload = function(){ mas_video = document.getElementsByClassName("videoBlock"); for(var i=0; i<mas_video.length; i++){ var newObj = new Video_designer; newObj.videoBlock = mas_video[i]; // получаем блок обертку в которой находится видео newObj.video = mas_video[i].childNodes[3]; // получаем видео newObj.PlayPause = mas_video[i].childNodes[5].childNodes[1]; // получаем кнопку при нажатии которой запускается видео newObj.StopV = mas_video[i].childNodes[5].childNodes[3]; // получаем кнопку при нажатии которой выключается видео newObj.PlayPause.addEventListener("click",newObj.fPlay); // добавляем событие к кнопке что бы при нажатии видео начинало проигрываться all_video.push(newObj); // записываем текущий объект видео в массив и создаем новый объект видео если они еще имеются на странице } } Все равно не работает, в консоли появляется такая ошибка Uncaught TypeError: Cannot read property 'play' of undefined То есть как мне кажется проблема в том что метод почему то не видит this.video объекта для которого я вызываю play(). Хотя может я и ошибаюсь, но почему так не могу понять. |
Цитата:
Цитата:
|
Нет это у меня в коде есть разметка
<div class="videoBlock"> <div class="titleVideo">Заголовок видео</div> <video id="video001"> <source src="video/drawing.mp4" type="video/mp4" /> <source src="video/drawing.ogv" type="video/ogg" /> <source src="video/drawing.webm" type="video/webm" /> </video> <div class="toolsControll"> <div class="button cont1"></div> <div class="button cont3"></div> <div class="wrapperProgress"> <div class="wrapperLoading"></div> <div class="wrapperPosition"></div> </div> <div class="infoTime">00:00/00:00</div> <div class="volume"></div> <div class="resize"></div> <div class="actionInfo"></div> </div> в ней находятся нужные элементы, тут все правильно я все проверял |
arcmag,
newObj.PlayPause.addEventListener("click",newObj.f Play.bind(newObj), false) Говорю же, контекст не тот. |
arcmag,
Вообще тот код что в цикле - просто ужас. По хорошему надо давать в конструктор объекта те данные с которыми он будет работать и не надо напрямую обращаться к ключам объекта. Если уж следовать вашей логике, то надо в конструктор класть видео блок, в видео менеджере сделать метод инициализации, чтобы он сам искал нужные элементы, видео и вешал обработчики, как в примере который я вам писал. |
Цитата:
|
Окончательно запутавшись решил получше изучить ваш пример и как то переделать его под себя.
Пришлось покопаться в сети и почитать о bind() после чего поматерившись методом тыка удалось таки запустить свое чудовище. var all_video = []; function Video_designer(myVideoBlock){ this.videoBlock = myVideoBlock; this.video = this.videoBlock.childNodes[3]; this.PlayPause = this.videoBlock.childNodes[5].childNodes[1]; this.StopV = this.videoBlock.childNodes[5].childNodes[3]; this.fPlay = function(){this.video.play();} this.fStop = function(){this.video.pause();} } window.onload = function(){ mas_video = document.getElementsByClassName("videoBlock"); for(var i=0; i<mas_video.length; i++){ var newObj = new Video_designer(mas_video[i]); console.log(newObj.videoBlock+" 1"); newObj.PlayPause.addEventListener("click",newObj.fPlay.bind(newObj)); newObj.StopV.addEventListener("click",newObj.fStop.bind(newObj)); all_video.push(newObj); } } Вроде бы работает :) я аж почувствовал как захрустел мой мозг от напряжения когда я это переваривал. Товарищу tsigel большое спасибо, без вас бы я не справился. |
arcmag,
В js принято называть переменные в camel case, не надо подчеркиваний. var allVideo = []; var VideoDesigner = function VideoDesigner(myVideoBlock){ this.video = myVideoBlock.querySelector("video"); this.playPause = myVideoBlock.childNodes[5].childNodes[1]; this.stopV = myVideoBlock.childNodes[5].childNodes[3]; this._setHandlers(); }; VideoDesigner.prototype._setHandlers = function () { this.playPause.addEventListener("click", this.fPlay.bind(this), false); this.stopV.addEventListener("click", this.fStop.bind(this), false); }; VideoDesigner.prototype.fPlay = function(){ this.video.play(); }; VideoDesigner.prototype.fStop = function(){ this.video.pause(); }; window.onload = function(){ Array.prototype.forEach.call(document.getElementsByClassName("videoBlock"), function (myVideoBlock) { allVideo.push(new VideoDesigner(myVideoBlock)); }); }; Постарайтесь убрать из кода цифры, понимание которых затрудняет код. Дайте кнопке плейПауза особый класс и тогда "myVideoBlock.childNodes[5].childNodes[1]" превратится в "myVideoBlock.querySelector(".особый класс")". Ото сильно упростит понимание вашего кода и убережот от ошибок по невнимательности. Подчеркивание перед методом означает что это приватный метод, и пользоваться им может только его владелец (но это условности) Примерно так это должно выглядеть. Симпотичнее, верно? ;) |
Часовой пояс GMT +3, время: 07:51. |