20.02.2015, 12:36
|
Интересующийся
|
|
Регистрация: 06.02.2015
Сообщений: 29
|
|
Объект для видео
Всем привет. Сейчас изучаю объекты и вот решил сделать небольшой простенький видео плеер при помощи конструктора объектов.
Вот код
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, не могу понять в чем дело все вроде бы правильно написано, объекты для меня тема новая, поэтому много чего пока что не знаю и не понимаю.
Пожалуйста подскажите как решить проблему?
Желательно дайте понятный пример решения, мне на примерах как то понятнее понимается
|
|
20.02.2015, 14:07
|
Профессор
|
|
Регистрация: 12.12.2012
Сообщений: 1,398
|
|
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();
};
Последний раз редактировалось tsigel, 20.02.2015 в 14:16.
|
|
20.02.2015, 14:35
|
Интересующийся
|
|
Регистрация: 06.02.2015
Сообщений: 29
|
|
То есть надо написать как то так?
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().
Хотя может я и ошибаюсь, но почему так не могу понять.
|
|
20.02.2015, 14:39
|
|
Профессор
|
|
Регистрация: 11.09.2010
Сообщений: 8,804
|
|
Сообщение от arcmag
|
childNodes[3]
|
Че за магические числа?
Сообщение от arcmag
|
не видит this.video
|
Может потому что он равен undefined?, так как childNodes[3] нету?
__________________
В личку только с интересными предложениями
|
|
20.02.2015, 14:46
|
Интересующийся
|
|
Регистрация: 06.02.2015
Сообщений: 29
|
|
Нет это у меня в коде есть разметка
<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>
в ней находятся нужные элементы, тут все правильно я все проверял
|
|
20.02.2015, 14:53
|
Профессор
|
|
Регистрация: 12.12.2012
Сообщений: 1,398
|
|
arcmag,
newObj.PlayPause.addEventListener("click",newObj.f Play.bind(newObj), false)
Говорю же, контекст не тот.
Последний раз редактировалось tsigel, 20.02.2015 в 14:57.
|
|
20.02.2015, 14:56
|
Профессор
|
|
Регистрация: 12.12.2012
Сообщений: 1,398
|
|
arcmag,
Вообще тот код что в цикле - просто ужас. По хорошему надо давать в конструктор объекта те данные с которыми он будет работать и не надо напрямую обращаться к ключам объекта. Если уж следовать вашей логике, то надо в конструктор класть видео блок, в видео менеджере сделать метод инициализации, чтобы он сам искал нужные элементы, видео и вешал обработчики, как в примере который я вам писал.
|
|
20.02.2015, 15:42
|
|
Профессор
|
|
Регистрация: 11.09.2010
Сообщений: 8,804
|
|
Сообщение от tsigel
|
вешал обработчики, как в примере который я вам писал
|
Вот именно. Я вообще не заметил навешивание обработчиков в цикле, так как там его не должно быть вообще. Думал fPlay вызываешь напрямую.
__________________
В личку только с интересными предложениями
|
|
20.02.2015, 16:14
|
Интересующийся
|
|
Регистрация: 06.02.2015
Сообщений: 29
|
|
Окончательно запутавшись решил получше изучить ваш пример и как то переделать его под себя.
Пришлось покопаться в сети и почитать о 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 большое спасибо, без вас бы я не справился.
|
|
20.02.2015, 16:22
|
Профессор
|
|
Регистрация: 12.12.2012
Сообщений: 1,398
|
|
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(".особый класс")". Ото сильно упростит понимание вашего кода и убережот от ошибок по невнимательности.
Подчеркивание перед методом означает что это приватный метод, и пользоваться им может только его владелец (но это условности)
Примерно так это должно выглядеть. Симпотичнее, верно?
Последний раз редактировалось tsigel, 20.02.2015 в 16:47.
|
|
|
|