Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 20.02.2015, 12:36
Интересующийся
Отправить личное сообщение для arcmag Посмотреть профиль Найти все сообщения от arcmag
 
Регистрация: 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, не могу понять в чем дело все вроде бы правильно написано, объекты для меня тема новая, поэтому много чего пока что не знаю и не понимаю.
Пожалуйста подскажите как решить проблему?
Желательно дайте понятный пример решения, мне на примерах как то понятнее понимается
Ответить с цитированием
  #2 (permalink)  
Старый 20.02.2015, 14:07
Профессор
Отправить личное сообщение для tsigel Посмотреть профиль Найти все сообщения от tsigel
 
Регистрация: 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.
Ответить с цитированием
  #3 (permalink)  
Старый 20.02.2015, 14:35
Интересующийся
Отправить личное сообщение для arcmag Посмотреть профиль Найти все сообщения от arcmag
 
Регистрация: 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().
Хотя может я и ошибаюсь, но почему так не могу понять.
Ответить с цитированием
  #4 (permalink)  
Старый 20.02.2015, 14:39
Аватар для danik.js
Профессор
Отправить личное сообщение для danik.js Посмотреть профиль Найти все сообщения от danik.js
 
Регистрация: 11.09.2010
Сообщений: 8,804

Сообщение от arcmag
childNodes[3]
Че за магические числа?
Сообщение от arcmag
не видит this.video
Может потому что он равен undefined?, так как childNodes[3] нету?
__________________
В личку только с интересными предложениями
Ответить с цитированием
  #5 (permalink)  
Старый 20.02.2015, 14:46
Интересующийся
Отправить личное сообщение для arcmag Посмотреть профиль Найти все сообщения от arcmag
 
Регистрация: 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>

в ней находятся нужные элементы, тут все правильно я все проверял
Ответить с цитированием
  #6 (permalink)  
Старый 20.02.2015, 14:53
Профессор
Отправить личное сообщение для tsigel Посмотреть профиль Найти все сообщения от tsigel
 
Регистрация: 12.12.2012
Сообщений: 1,398

arcmag,

newObj.PlayPause.addEventListener("click",newObj.f Play.bind(newObj), false)


Говорю же, контекст не тот.

Последний раз редактировалось tsigel, 20.02.2015 в 14:57.
Ответить с цитированием
  #7 (permalink)  
Старый 20.02.2015, 14:56
Профессор
Отправить личное сообщение для tsigel Посмотреть профиль Найти все сообщения от tsigel
 
Регистрация: 12.12.2012
Сообщений: 1,398

arcmag,
Вообще тот код что в цикле - просто ужас. По хорошему надо давать в конструктор объекта те данные с которыми он будет работать и не надо напрямую обращаться к ключам объекта. Если уж следовать вашей логике, то надо в конструктор класть видео блок, в видео менеджере сделать метод инициализации, чтобы он сам искал нужные элементы, видео и вешал обработчики, как в примере который я вам писал.
Ответить с цитированием
  #8 (permalink)  
Старый 20.02.2015, 15:42
Аватар для danik.js
Профессор
Отправить личное сообщение для danik.js Посмотреть профиль Найти все сообщения от danik.js
 
Регистрация: 11.09.2010
Сообщений: 8,804

Сообщение от tsigel
вешал обработчики, как в примере который я вам писал
Вот именно. Я вообще не заметил навешивание обработчиков в цикле, так как там его не должно быть вообще. Думал fPlay вызываешь напрямую.
__________________
В личку только с интересными предложениями
Ответить с цитированием
  #9 (permalink)  
Старый 20.02.2015, 16:14
Интересующийся
Отправить личное сообщение для arcmag Посмотреть профиль Найти все сообщения от arcmag
 
Регистрация: 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 большое спасибо, без вас бы я не справился.
Ответить с цитированием
  #10 (permalink)  
Старый 20.02.2015, 16:22
Профессор
Отправить личное сообщение для tsigel Посмотреть профиль Найти все сообщения от tsigel
 
Регистрация: 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.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
виджет, только сторона клиента (JS, JQUery, работа с датами, масштабирование) eugen35 Работа 4 31.07.2014 09:50
Решение проблемы кодировок для AJAX и PHP без iconv (cp1251 в AJAX) Serge Ageyev AJAX и COMET 10 24.04.2013 20:48
HTA-приложение для радио Pianorama Magneto Ваши сайты и скрипты 42 22.01.2012 08:34
Помогите с галереей для видео разобраться ЁжыГ Элементы интерфейса 1 10.12.2011 02:08