Не работает JS из файла

Если вставить JS в тело страниццы, то он работает.

<!DOCTYPE html>
<html>
    <head>
        //
    </head>
    <body>
        <script src="/js/app.min.js"></script>
        <script>
            // Тут код
        </script>
    </body>
</html>

Если я перемещаю его в /js/app.min.js, то не работает.

var jivo_loaded = false,
    buttons = document.querySelectorAll('.btn-buy, .btn-ask');

function jivo_onLoadCallback() {
    jivo_loaded = true;
    gtag('event', 'jivo_loaded');
}

function jivo_onIntroduction() {
    gtag('event', 'jivo_new_contact');
};

function showContactForm() {
    if (jivo_loaded) {
        jivo_api.open({ 
            start: 'menu',
        });
    } else {
        gtag('event', 'jivo_not_loaded');
    }

    if (this.dataset.color) {
        addColorToCookie(this.dataset.color);
        gtag('event', 'btn_buy');
    } else {
        gtag('event', 'btn_ask');
    }
}

function addColorToCookie(id) {
    this.axios
        .post('/update/' + id)
        .then((response) => {
            // 
        });
}

for (var index = 0; index < buttons.length; index++) {
    buttons[index].addEventListener('click', showContactForm);
}

Если в /js/app.min.js добавить alert('ok'), то он тоже прекрасно работает. То есть, что-то не то с моим кодом. Проблема явно в моем коде, только я не пойму что не так. Этот же код работает, когда он не в файле, а просто вставлен в тело страницы. Что не так?

Update

Разобрался немного. Функции, которые написал я — работают из файла. Проблема в том, что сейчас не срабатывают callback-функции от чата (Jivo). В частности jivo_onLoadCallback() и jivo_onIntroduction(). Есть ли варианты это исправить?


Ответы (1 шт):

Автор решения: Alexandr

Вариант 1. Подключение скрипта перенести в подвал сайта после тега body

<!DOCTYPE html>
<html>
    <head>
        //
    </head>
    <body>
       
        
    </body>
    <script src="/js/app.min.js"></script>
    <script>
            // Тут код
    </script>
</html>

Вариант 2. Добавить обертку к вашему скрипту, которая будет говорить, что запускать скрипт надо после загрузки DOM.

document.addEventListener('DOMContentLoaded' , ()=>{ 
   //сюда вставить весь ваш код
})

Вариант 3. Используйте 'defer'. Скрипты с defer всегда выполняются, когда дерево DOM готово, но до события DOMContentLoaded:

<!DOCTYPE html>
<html>
    <head>
       <script defer src="/js/app.min.js"></script>
    </head>
    <body>
        
        
    </body>
</html>
→ Ссылка