Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 05.03.2018, 13:30
Новичок на форуме
Отправить личное сообщение для huckfinn Посмотреть профиль Найти все сообщения от huckfinn
 
Регистрация: 05.03.2018
Сообщений: 6

Ошибка при парсинге значения «margin-left»
Пытаясь сделать кастомный аудиоплеер для добавления аудиозаписей на сайт(взял за основу чей-то код), столкнулся с проблемой. Почему-то работает только один плеер на странице - тот, который создаётся последним. При попытке проиграть что-нибудь другое в консоли появляется ошибка(Ошибка при парсинге значения «margin-left»), быстро набирающая повторы. В итоге ничего толком не запускается. Притом такая ситуация возникает у меня в Firefox 52.6.0.6592, тогда как в Firefox 42-43 и Chrome 49.0 вроде бы всё нормально.
Вот сайт:
https://m-ch.ml/t/wakaba.html
Код для плеера:
//array for post ids
var num = [];

// array for AudioObjects
var audioList = [];
// components and the index for their AudioObject
var componentDict = {};
// store AudioObject that is currently playing
var playingAudio = null;
// store playhead id if one is being dragged
var onplayhead = null;

function getThreadNums ()
{
var audioElements = document.getElementsByClassName("audio"), i;
for (i = 0; i < audioElements.length; i++) {
        num[i]=audioElements[i].id;
		num[i]=num[i].slice(6);
//        window.alert(i+ " " + num[i]);
}
}

getThreadNums();



/* AudioObject Constructor */
function AudioObject(audio, duration) {
    this.audio = audio;
	this.id = audio;
    this.duration = duration;
}


AudioObject.prototype.bindAudioPlayer = function (num) {
    this.audioplayer = document.getElementById("audioplayer-" + num);
    this.playbutton = document.getElementById("playbutton-" + num);
    this.timeline = document.getElementById("timeline-" + num);
    this.playhead = document.getElementById("playhead-" + num);
	this.runtime = document.getElementById("runtime-" + num);
	this.range = document.getElementById("range-" + num);
	this.volume = document.getElementById("volume-" + num);
    this.timelineWidth = this.timeline.offsetWidth - this.playhead.offsetWidth;
}


/* addEventListeners() */
AudioObject.prototype.addEventListeners = function () {
    this.audio.addEventListener("timeupdate", AudioObject.prototype.timeUpdate, false);
    this.audio.addEventListener("durationchange", AudioObject.prototype.durationChange, false);
	this.audio.addEventListener("volumechange", AudioObject.prototype.volumeChange, false);
    this.timeline.addEventListener("click", AudioObject.prototype.timelineClick, false);
    this.playbutton.addEventListener("click", AudioObject.prototype.pressPlay, false);
    // Makes playhead draggable 
    this.playhead.addEventListener('mousedown', AudioObject.prototype.mouseDown, false);
    window.addEventListener('mouseup', mouseUp, false);
}

/* populateAudioList */
function populateAudioList() {
    var audioElements = document.getElementsByClassName("audio"), i;
    for (i = 0; i < audioElements.length; i++) {
        audioList.push(new AudioObject(audioElements[i], 0));
        audioList[i].bindAudioPlayer(num[i]);
        audioList[i].addEventListeners();
    }
}

/* populateComponentDictionary() 
 * {key=element id : value=index of audioList} */
function populateComponentDictionary() {
    for (i = 0; i < audioList.length; i++) {
        componentDict[audioList[i].audio.id] = i;
        componentDict[audioList[i].playbutton.id] = i;
        componentDict[audioList[i].timeline.id] = i;
        componentDict[audioList[i].playhead.id] = i;
		componentDict[audioList[i].runtime.id] = i;
		componentDict[audioList[i].range.id] = i;
		componentDict[audioList[i].volume.id] = i;
    }
}

///////////////////////////////////////////////
// Update Audio Player
///////////////////////////////////////////////

/* durationChange
 * set duration for AudioObject */
AudioObject.prototype.durationChange = function () {
    var ao = audioList[getAudioListIndex(this.id)];
    ao.duration = this.duration;
}

/* pressPlay() 
 * call play() for correct AudioObject
 */
AudioObject.prototype.pressPlay = function () {
    var index = getAudioListIndex(this.id);
    audioList[index].play();
}

/* play() 
 * play or pause selected audio, if there is a song playing pause it
 */
AudioObject.prototype.play = function () {
    if (this == playingAudio) {
        playingAudio = null;
        this.audio.pause();
        changeClass(this.playbutton, "play");
    }
    // else check if playing audio exists and pause it, then start this
    else {
        if (playingAudio != null) {
            playingAudio.audio.pause();
            changeClass(playingAudio.playbutton, "play");
        }
		
		/*var a1 = document.getElementById(this.audio.id);
        a1.play();*/
		
		this.audio.play();
        playingAudio = this;
        changeClass(this.playbutton, "pause");
    }
}

/* timelineClick()
 * get timeline's AudioObject
 */
AudioObject.prototype.timelineClick = function (event) {
    var ao = audioList[getAudioListIndex(this.id)];
    ao.audio.currentTime = ao.audio.duration * clickPercent(event, ao.timeline, ao.timelineWidth);
}

/* mouseDown */
AudioObject.prototype.mouseDown = function (event) {
    onplayhead = this.id;
    var ao = audioList[getAudioListIndex(this.id)];
    window.addEventListener('mousemove', AudioObject.prototype.moveplayhead, true);
    ao.audio.removeEventListener('timeupdate', AudioObject.prototype.timeUpdate, false);
}

/* mouseUp EventListener
 * getting input from all mouse clicks */
function mouseUp(e) {
    if (onplayhead != null) {
        var ao = audioList[getAudioListIndex(onplayhead)];
        window.removeEventListener('mousemove', AudioObject.prototype.moveplayhead, true);
        // change current time
        ao.audio.currentTime = ao.audio.duration * clickPercent(e, ao.timeline, ao.timelineWidth);
        ao.audio.addEventListener('timeupdate', AudioObject.prototype.timeUpdate, false);
    }
    onplayhead = null;
}

/* mousemove EventListener
 * Moves playhead as user drags */
AudioObject.prototype.moveplayhead = function (e) {
    var ao = audioList[getAudioListIndex(onplayhead)];
    var newMargLeft = e.clientX - getPosition(ao.timeline);

  if (newMargLeft >= 0 && newMargLeft <= ao.timelineWidth) {
        document.getElementById(onplayhead).style.marginLeft = newMargLeft + "px";
    }
    if (newMargLeft < 0) {
        playhead.style.marginLeft = "0px";
    }
    if (newMargLeft > ao.timelineWidth) {
        playhead.style.marginLeft = ao.timelineWidth + "px";
    }
}

/* timeUpdate 
 * Synchronizes playhead position with current point in audio 
 * this is the html audio element
 */
AudioObject.prototype.timeUpdate = function () {
    // audio element's AudioObject
    var ao = audioList[getAudioListIndex(this.id)];
    var playPercent = ao.timelineWidth * (ao.audio.currentTime / ao.duration);
    ao.playhead.style.marginLeft = playPercent + "px";
    // If song is over
	
	var minutes = parseInt(ao.duration / 60, 10);
    var seconds = parseInt(ao.duration % 60);
	var cminutes = parseInt(ao.audio.currentTime / 60, 10);
    var cseconds = parseInt(ao.audio.currentTime % 60);
	document.getElementById("runtime-" + num[getAudioListIndex(this.id)] ).innerHTML=cminutes+":"+cseconds+"/"+minutes+":"+seconds;
	
    if (ao.audio.currentTime == ao.duration) {
        changeClass(ao.playbutton, "play");
        ao.audio.currentTime = 0;
        ao.audio.pause();
        playingAudio = null;
    }
	
}

function setVolume(vid) {
	vid=vid.slice(6);
	var slider = document.getElementById("range-" + vid);
    var output = document.getElementById("volume-" + vid);
    var music = document.getElementById("audio-" + vid);
    output.innerHTML = "Vol:" + Math.round(slider.value*100)+"%";
    music.volume = slider.value;
}

///////////////////////////////////////////////
// Utility Methods
///////////////////////////////////////////////

/* changeClass 
 * overwrites element's class names */
function changeClass(element, newClasses) {
    element.className = newClasses;
}

/* getAudioListIndex
 * Given an element's id, find the index in audioList for the correct AudioObject */
function getAudioListIndex(id) {
    return componentDict[id];
}

/* clickPercent()
 * returns click as decimal (.77) of the total timelineWidth */
function clickPercent(e, timeline, timelineWidth) {
   return ((e.clientX - getPosition(timeline))/ timelineWidth);
}

// getPosition
// Returns elements left position relative to top-left of viewport
function getPosition(el) {
    return el.getBoundingClientRect().left;
}

    populateAudioList();
    populateComponentDictionary();
Ответить с цитированием
  #2 (permalink)  
Старый 05.03.2018, 13:38
Новичок на форуме
Отправить личное сообщение для huckfinn Посмотреть профиль Найти все сообщения от huckfinn
 
Регистрация: 05.03.2018
Сообщений: 6

Я так понимаю, проблема может быть с перемещением головки, но я проверял - значения переменных получаются правильные. К тому же один плеер ведь работает, а кое-где и вообще все. Уже всё пересмотрел на несколько раз и не пойму, в чём может быть дело. Есть идеи у кого-нибудь?
P.S.
Ещё заметил, что проиграть трек-таки можно, если головку сдвинуть, но общее время тогда не показывается.

Последний раз редактировалось huckfinn, 05.03.2018 в 13:49.
Ответить с цитированием
  #3 (permalink)  
Старый 05.03.2018, 13:48
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

huckfinn,
попробуйте не использовать for а только forEach!!!
Ответить с цитированием
  #4 (permalink)  
Старый 05.03.2018, 14:24
Новичок на форуме
Отправить личное сообщение для huckfinn Посмотреть профиль Найти все сообщения от huckfinn
 
Регистрация: 05.03.2018
Сообщений: 6

Так ведь мне заранее не известны массивы, они в цикле заполняются. Разве forEach можно использовать, если элементы не заданы?
Ответить с цитированием
  #5 (permalink)  
Старый 05.03.2018, 14:43
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

huckfinn,
var для i строка 72 добавьте.
Ответить с цитированием
  #6 (permalink)  
Старый 05.03.2018, 14:50
Новичок на форуме
Отправить личное сообщение для huckfinn Посмотреть профиль Найти все сообщения от huckfinn
 
Регистрация: 05.03.2018
Сообщений: 6

Добавил везде var на всякий случай. Хотя это роли не сыграло - думаю, если что-то с этим было бы не так, была бы ошибка с указанием на строку.
Ответить с цитированием
  #7 (permalink)  
Старый 05.03.2018, 15:03
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

huckfinn,
не могу воспроизвести ошибку, всё работает 58.0.2 (64-бит) Firefox, только предположение что в onplayhead нет id строка 159 либо id неправильное
Ответить с цитированием
  #8 (permalink)  
Старый 05.03.2018, 15:15
Новичок на форуме
Отправить личное сообщение для huckfinn Посмотреть профиль Найти все сообщения от huckfinn
 
Регистрация: 05.03.2018
Сообщений: 6

С id как будто всё в порядке. Видимо, что-то специфичное. Спасибо за ответы, в любом случае.
Ответить с цитированием
  #9 (permalink)  
Старый 11.03.2018, 08:00
Новичок на форуме
Отправить личное сообщение для huckfinn Посмотреть профиль Найти все сообщения от huckfinn
 
Регистрация: 05.03.2018
Сообщений: 6

Похоже, проблема была в неправильной продолжительности трека - причём получался ноль, а не nan, поэтому ошибок и не было. Исправил, изменив ao.duration (длительность, получаемая при создании аудио-объекта) на document.getElementById(this.id).duration; Всё равно странно это, но теперь вроде как везде работает.
Ответить с цитированием
Ответ



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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Ошибка при клике Зосимов Общие вопросы Javascript 10 09.06.2015 14:19
Ошибка (spawn ENOENT) при использовании библиотеки ImageMagick на Windows uWeb AJAX и COMET 1 03.10.2014 20:16
Ошибка “define is not defined” при запуске Istanbul TorchTT Общие вопросы Javascript 0 26.06.2014 15:38
Ошибка при добавлении обработчика к событию Riim Events/DOM/Window 32 19.01.2010 14:17
Как узнать какие ошибки произошли при парсинге xml файла faunder Events/DOM/Window 0 12.09.2008 14:17