Uncaught TypeError: невозможно прочитать свойство «длина» неопределенного — jQuery

У меня есть простой интерактивный видеоплеер HTML5, в котором пользователь может воспроизводить разные видео с помощью кнопок при нажатии.

Я добавил кнопку возврата, которая позволяет пользователю вернуться к ранее воспроизведенному видео.

Вот html

    <div class = "container-fluid">
        <div class = "row">
            <div class = "col-12" canplay id = "video-block">                    
                <div id = "video-container">
                        <video id = "videoplayer" playsinline autoplay>
                            <source src = "" type = "video/mp4">
                        </video>
                        <div id = "interactive-layers">
                                <!-- <div class = "go_back">Go back</div> -->
                        </div>
                    </div>
                    <div id = "video-controls">
                        <div id = "seek-bar-container">
                        <div id = "seek-bar">
                            <div id = "current-time">

                            </div>
                        </div>
                        </div>
                        <div id = "pause-play-button">
                        <span id = "play">play</span>
                        <span id = "pause">pause</span>
                        </div>
                    </div>
            </div>
        </div>
    </div>

вот мой js

var movies = null;
var flowchart = null;
var connections = null;
var videohistory = [];


$(document).ready(function () {
    $.getJSON('data.json', function (data) {
        movies = data.movies;
        $.getJSON('datasaved/settings2.json', function (data) {
            flowchart = data.movies;
            connections = data.connections;

            for (var c = 0; c < connections.length; c++) {
                connections[c].buttonid = String(connections[c].buttonid).split("moviebuttons")[1];
                connections[c].movieid = String(connections[c].movieid).split("movieblock")[1];
            }

            for (var j = 0; j < movies.length; j++) {
                for (var i = 0; i < flowchart.length; i++) {
                    if (flowchart[i].checkbox == true && flowchart[i].movieid == movies[j].movieid) {
                        playVideo(movies[j], flowchart[i]);
                    }
                }
            }
        });
        setInterval(updateTimeline, 40);
    })

    $("#interactive-layers").on("click", ".video-btns", buttonLinkClicked);
    $('#interactive-layers').on('click', ".go_back", function () {
        playVideo(videohistory[videohistory.length - 2], true);

    });

    video = $("#video-container").find('video');
    video[0].addEventListener("timeupdate", onUpdateTime);
    video[0].addEventListener("canplaythrough", videoReady);
    video[0].addEventListener("pause", onPause);
    video[0].addEventListener("play", onPlay);
    video[0].addEventListener("ended", onEnded);
    video[0].addEventListener("timeupdate", onUpdateTime);
})

function buttonLinkClicked(e) {

    var mov = null;
    var flo = null;

    for (var j = 0; j < movies.length; j++) {
        if ($(e.target).attr("targetmovieid") == movies[j].movieid) {
            mov = movies[j];
        }
    }
    for (var i = 0; i < flowchart.length; i++) {
        if (flowchart[i].movieid == $(e.target).attr("targetmovieid")) {
            flo = flowchart[i];
        }
    }

    if (mov == null || flo == null) {
        $(this).attr('buttonid');
        var getButon = $(this).attr('buttonid');

        switch (getButon) {
            case "5":

                window.open('https://www.meed.com/', '_blank').focus();

                break;

            case "6":

                window.open('https://buy.meed.com/', '_blank').focus();

                break;
            case "7":

                window.open('https://www.meedprojects.com/projects-platform/bespoke-services', '_blank').focus();

                break;

            case "60":

                window.open('https://premium.meedprojects.com/Login', '_blank').focus();

                break;
        }

    } else {

        playVideo(mov, flo);
    }

}

function updateTimeline() {
    if ($("#videoplayer")[0].duration) {
        $(".video-btns").each(function () {
            if ($("#videoplayer")[0].currentTime >= parseFloat($(this).attr("starttime")) && $("#videoplayer")[0].currentTime < parseFloat($(this).attr("endtime"))) {
                $(this).addClass("show");
            } else {
                $(this).removeClass("show");
            }
        });
    }
}



function addGoBack() {
    var goback = $(" <div class='go_back'>Go back</div>");
    $("#interactive-layers").append(goback);
}

function playVideo(movie, flowchartvideo, back) {

    var movieHistory = Object.values(movie);

    $("#interactive-layers").html("");
    addGoBack();

    if (back == true) {

        videohistory.pop();

    } else {

        videohistory.push(movieHistory);
        console.info(videohistory);
    }

    if (videohistory.length == 1) {
        $(".go_back").addClass('hidden');
    } else {
        $(".go_back").removeClass('hidden');
    }


    var buttons = movie.buttons;

    for (var b = 0; b < buttons.length; b++) {

        for (var c = 0; c < connections.length; c++) {
            if (connections[c].buttonid == buttons[b].buttonid) {
                buttons[b].targetmovieid = connections[c].movieid;
            }
        }
    }

    $("#videoplayer").attr("src", movie.movie_url);
    $("#videoplayer")[0].muted = false;


    //  alert(buttons.length);
    for (var b = 0; b < buttons.length; b++) {
        var buttonid = buttons[b].buttonid;
        var label = buttons[b].label;
        var starttime = buttons[b].start_time;
        var endtime = buttons[b].end_time;

        var videobtns = $("<div buttonid='" + buttonid + "'  class='video-btns' targetmovieid='" + buttons[b].targetmovieid + "' starttime='" + starttime + "' endtime='" + endtime + "'><span class='label'>" + label + "</span></div>")
        var top, left, width, height;
        top = buttons[b].top
        left = buttons[b].left
        width = buttons[b].width
        height = buttons[b].height;

        $("#interactive-layers").append(videobtns);
        videobtns.css({
            top: top,
            left: left,
            width: width,
            height: height
        })
    }
}

Когда пользователь воспроизводит второе видео, появляется кнопка возврата, и пользователь может щелкнуть ее и воспроизвести предыдущий фильм.

Теперь, когда я нажимаю вернуться, я получаю следующую ошибку

main.js: 156 Uncaught TypeError: невозможно прочитать свойство «длина» неопределенного

ОБНОВИТЬ

Here is live demo : live demo

Что я делаю неправильно? или может кто-нибудь предоставить простой метод для этого?

У вас нигде нет переменной connections, что такое connections.length?

Barmar 13.07.2019 01:44

Какая строка является строкой 156?

Barmar 13.07.2019 01:46
for (var b = 0; b < buttons.length; b++)
The Dead Man 13.07.2019 01:51

@Barmar Я не добавляю соединения, потому что с этим нет проблем, я просто хочу воспроизвести предыдущее воспроизведенное видео, но не уверен, что делаю правильно

The Dead Man 13.07.2019 01:57

@Barmar добавил весь код, который я использую для своего плеера и живой демонстрации

The Dead Man 13.07.2019 02:07

Ошибка означает, что movie.buttons не определено. Проверьте значение movie.

Barmar 13.07.2019 02:07

@Barmar на консоли movie.buttons перед нажатием кнопки возврата отображает значение, сразу после нажатия кнопки возврата отображается эта ошибка, вы можете проверить это в демо-версии.

The Dead Man 13.07.2019 02:14
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
7
683
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я ответил очень быстро, после проверки вашего рабочего кода, предлагаю вам внимательнее взглянуть на строку...

var movieHistory = Object.values(movie);

Похоже, он не делает то, что вы хотите. (клонировать объект фильма). Просто измените его на

var movieHistory = movie;

У меня это работает в консоли Chrome Dev...

Я попробую вот живая демо https://videomill-bot.audiencevideo.com/editor/preview.html проверьте это

The Dead Man 13.07.2019 01:55

У меня есть весь код, который я использую, проверьте обновленный вопрос, эта строка предназначена для преобразования объекта в массив, проверьте код

The Dead Man 13.07.2019 02:05

да, он преобразует объект в массив, но это создаст проблему при следующем вызове функции. Он ожидает объект, но теперь получает массив.

Max 13.07.2019 02:09

ради интереса попробуйте изменить "var movieHistory = Object.values(movie);" на "var movieHistory = фильм"

Max 13.07.2019 02:10

что эта строка должна делать?

The Dead Man 13.07.2019 02:15

Вы хотите сохранить ранее показанное видео в массиве, чтобы иметь возможность вернуться к нему, но только потому, что вам нужен объект в массиве, это не причина для преобразования его в один. просто поместите исходный объект фильма в массив истории, он будет работать.

Max 13.07.2019 02:20

@user9964622 user9964622 Это должно было быть очевидно, если бы вы это сделали console.info(videohistory). Он не содержит массив объектов.

Barmar 13.07.2019 02:20

Другие вопросы по теме