Каждый объект TextTrack имеет свойство cues, которое является списком TextTrackCueList, содержащим объекты VTTCue (все метки текущего трека).
Каждый объект VTTCue имеет свойство track, которое является объектом TextTrack. Этот TextTrack — смотрим первый пункт.
Если представить, как дерево
TextTrack
cues[0]
track
cues[0]
track ... и так до неопределенной глубины.
HTML
<video width="400" height="225" id="myVideo" preload="metadata" controls>
<source src="my-video.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'>
<track src="track.vtt" default="true" kind="subtitles" srclang="en" label="English">
</video>
Можно открыть инструменты разработчика в браузере, или пройтись скриптом в глубину дерева.
JavaScript<script>
var headTrack;
// После загрузки окна получаем объект трека
// Навешиваем на него обработчик
window.onload = function() {
var headTrack = myVideo.textTracks[0];
headTrack.addEventListener('cuechange', getAllTracks);
console.log(myVideo.textTracks);
};
// Когда браузер заходит в метку, запускаем основную функцию
function getAllTracks(event) {
var currentTrack = event.target;
getHoleTracks(currentTrack);
}
// Счётчик, чтобы не было бесконечной рекурсии
var counter = 0;
// Извлекаем cues из textTrack
// Извлекаем track из VTTCue
function getHoleTracks(textTrack) {
counter++;
var firstCue = textTrack.cues[0];
var cuesTrack = firstCue.track;
// Вывод в консоль для наглядности
console.log(counter);
console.log('firstCue' + firstCue);
console.log('cuesTrack' + cuesTrack);
// Если последний TextTrack содержит cues, повторяем
// Ограничимся сотней выводов
if (cuesTrack.cues[0] && (counter < 100) ) {
getHoleTracks(cuesTrack);
}
}
</script>
Вопросы
Это что, кроличья нора без дна? Баг или фича?
Влияет ли нагрузку браузера такое дерево объектов или он как-то оптимизирует не создавая его на всю глубину?
Или это я что-то неправильно понимаю?
Свойство track - всего лишь ссылка на родительский обект типа TextTrack. Проверить это очень легко: нужно добавить какое-нибудь дополнительное свойство в myVideo.textTracks[0] и посмотреть добавилось ли оно во всех вложенных объектах (добавилось). Получается, что никакой кроличьей норы нет - вы ходили по кругу
Похоже, я слишком буквально воспринимаю визуальную картинку из инструментов разработчика в браузере. Всегда с трудом понимаю ссылки и указатели. Не могу представить визуальную аналогию.
Есть такая структура данных связный список. На js его не сложно реализовать, причем возьмем частный случай, двунаправленный связный список.
Это список, у которого каждый элемент имеет ссылку на родительский элемент и дочерний
Создадим такой список из двух объектов:
const obj1 = { value : 1, parent: null, child: null }
const obj2 = { value : 2, parent: null, child: null }
// свяжем эти два объекта
obj1.child = obj2
obj2.parent = obj1
И так мы создали циклические ссылки, потому что св-во parent у obj2 ссылается на obj1, у которого есть св-во child, которое ссылается на obj2
Как это выглядит в консоли:
Казалось, бы, это должно занимать бесконечно много памяти, но движок браузера не такой глупый. Поэтому он хранит не сам объект ( его копию ), а, грубо говоря, адрес в памяти, пройдя по которому можно получить нужные данные. Тем самым мы не плодим бесконечные сущности, а используем ссылки для доступа к объектам в св-вах.
Так же и с DOM структурой, у каждого элемент есть св-во parentNode, которое ссылается на родительский элемент, в свою очередь у родительского элемента есть св-во children, коллекция дочерних элементов, которые ссылаются на его детей, у которых св-во parentNode ссылается обратно на родительский элемент)))
По понятным причинам, такие объекты сложно представить в виде JSON ( ошибка как бы намекает )
Сборка персонального компьютера от Artline: умный выбор для современных пользователей