Javascript не работает даже при размещении в конце секции Body - PullRequest
0 голосов
/ 26 мая 2020

Я поместил следующий скрипт в самый конец раздела body моего файла html, где select_1, select_2, select_3 являются динамическими c (зависимыми) раскрывающимися списками. (Назовем сценарий ниже НОВЫЙ СКРИПТ).

function json(response) {
    return response.json()
}

function url_parser(XArray, some_str){
    var url_str = [];
    for (var i=0; i < XArray.length; ++i)
        url_str.push('/'+XArray[i].value);
    url_str.push(some_str);
    url_str = url_str.join('');
    return url_str
}

function selectionHTML(nextFormElement, data){
    let optionHTML = '';
        for (let tmp of data.select_array) {
            optionHTML += '<option value="' + tmp.gid + '">' + tmp.gid + '</option>';
        }
        nextFormElement.innerHTML = optionHTML;
}


function myChoices(XArray, some_str, nextFormElement){
    my_url = url_parser(XArray, some_str);
    fetch(my_url).then(json).then(selectionHTML.bind(null, nextFormElement));
}


let select_1 = document.getElementById('tipo_via');
let select_2 = document.getElementById('numero_via');
let select_3 = document.getElementById('apendice_via');

select_1.onchange = myChoices([tipo_via], '/numero_via', select_2);
select_2.onchange = myChoices([tipo_via, numero_via], '/apendice_v', select_3);

Однако этот скрипт не работает. Единственный способ:

  1. удалить его из файла html и
  2. выполнить его в консоли в определенном порядке

Предоставление деталей в порядке выполнения:

  1. Выполнить (в консоли) весь код между function json(response) и let select_3 = document.getElementById('apendice_via');
  2. изменить значение (на странице) select_1.
  3. Выполнить (в консоли) select_1.onchange = myChoices([tipo_via], '/numero_via', select_2); (теперь select_2 правильно обновляется).
  4. изменить значение (на странице) select_2.
  5. Выполнить (в консоли) select_2.onchange = myChoices([tipo_via, numero_via], '/apendice_v', select_3); (select_3 теперь корректно обновляется).

Посмотрев на похожие проблемы, я подумал, что проблема была (возможно, все еще) связана со временем загрузки страницы, поэтому я поместил скрипт в конец <body>. Я также попытался поместить его в <head>

. НОВЫЙ СКРИПТ должен был заменить СТАРЫЙ СКРИПТ (ниже ... который отлично работает), так как всего будет 8 раскрывающихся списков.

function json(response) {
    return response.json()
}

function url_parser(XArray, some_str,){
    var url_str = [];
    for (var i=0; i < XArray.length; ++i)
        url_str.push('/'+XArray[i].value);
    url_str.push(some_str);
    url_str = url_str.join('');
    return url_str
}


let select_1 = document.getElementById('tipo_via');
let select_2 = document.getElementById('numero_via');
let select_3 = document.getElementById('apendice_via');


select_1.onchange = function(){
    my_url = url_parser([tipo_via], '/numero_via');
    fetch(my_url).then(json).then(function(data) {
            let optionHTML = '';
            for (let tmp of data.select_array) {
                optionHTML += '<option value="' + tmp.gid + '">' + tmp.gid + '</option>';
            }
            select_2.innerHTML = optionHTML;
        });
}

select_2.onchange = function(){
    my_url = url_parser([tipo_via, numero_via], '/apendice_v');
    fetch(my_url).then(json).then(function(data) {
            let optionHTML = '';
            for (let tmp of data.select_array) {
                optionHTML += '<option value="' + tmp.gid + '">' + tmp.gid + '</option>';
            }
            select_3.innerHTML = optionHTML;
        });
}

Я не могу понять, действительно ли проблема связана с загрузкой страницы, почему она влияет на НОВЫЙ сценарий, а не на СТАРЫЙ.

Любая помощь будет принята с благодарностью. Заранее спасибо.

Ответы [ 2 ]

2 голосов
/ 26 мая 2020

Ваш код сбивает с толку вызов функции и ссылку на функцию для обработчика событий. Например, в этой строке:

select_1.onchange = myChoices([tipo_via], '/numero_via', select_2);

... это означает, что вызывает myChoices с некоторыми аргументами и присваивает возвращаемое значение onchange. Вместо этого вы хотите, чтобы при возникновении события onchange вы вызывали myChoices с этими аргументами. Это больше из того, что вы хотите:

select_1.addEventListener(
  'change', 
  () => myChoices([tipo_via], '/numero_via', select_2));
select_2.addEventListener(
  'change',
  () => myChoices([tipo_via, numero_via], '/apendice_v', select_3));

Я изменил назначение с onchange на предпочтительный addEventListener, но самый важный ключ здесь - перенос вызова вашей функции в новую функцию, чтобы фактический звонок происходит не сразу. Теперь, пока не будет запущено событие DOM change, будет вызываться стрелочная функция, а внутри этой функции будет вызов myChoices(...). Обратите внимание, что исходный рабочий код также ссылался на функцию прослушивателя, чтобы отложить вызов до тех пор, пока не произойдет событие.

0 голосов
/ 26 мая 2020

DOM может быть не готов (HTML полностью проанализирован и дерево DOM построено внутри), поэтому вам нужно выполнить свой код в событии DOMContentLoaded .

Если это не решает проблему, тогда опубликуйте подробное описание ошибки, например, ошибки из консоли браузера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...