jQuery порядок выполнения тега скрипта при использовании $ .append - PullRequest
0 голосов
/ 07 августа 2020

Обычно, когда у меня есть что-то подобное ниже на странице HTML, это работает нормально. Блок локального сценария выполняется только после завершения загрузки внешнего блока сценария.

<div id="curve_chart" style="width: 900px; height: 500px"></div>

<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">         
    google.charts.load('current', {'packages':['corechart']});
    google.charts.setOnLoadCallback(drawChart);
    
    function drawChart() {
        var data = google.visualization.arrayToDataTable([
        ['Year', 'Sales', 'Expenses'],
        ['2004',  1000,      400],
        ['2005',  1170,      460],
        ['2006',  660,       1120],
        ['2007',  1030,      540]
        ]);
        
        var options = {
        title: 'Company Performance',
        curveType: 'function',
        legend: { position: 'bottom' }
        };
        
        var chart = new google.visualization.LineChart(document.getElementById('curve_chart'));
        
        chart.draw(data, options);
    }         
</script>

Однако, если я возьму приведенный выше код и добавлю его в контейнер DIV следующим образом:

$("#some_element").append($.parseHTML([code from above here], document, true));

Это дает мне сообщение «Uncaught ReferenceError: google is not defined». Я думаю, проблема в том, что при добавлении этого фрагмента кода, как этот, либо порядок тегов сценария не соблюдается, либо он просто загружает все теги сценария параллельно?!

Теперь я знаю, что есть обходные пути к этому (в основном с использованием $ .getScript и обратного вызова), но я хотел бы знать, почему это именно так, и есть ли способ заставить его работать так, как ожидалось.

1 Ответ

0 голосов
/ 07 августа 2020

Когда вы добавляете строку HTML к узлу DOM, поведение браузера по умолчанию блокирует выполнение скрипта (в качестве меры безопасности для предотвращения атаки XSS). Что делает jQuery (насколько мне известно), так это переоценивает эти сценарии. В случаях, когда есть URL-адрес скрипта, jQuery отправляет запрос AJAX. Как вы знаете, AJAX является асинхронным, что означает, что сценарии могут разрешаться в любом порядке (в отличие от того, что происходит, когда вы используете HTML напрямую). В результате встроенный JavaScript выполняется перед сценарием зависимости. Вы можете узнать об этом больше, просмотрев вкладку сети.

$('#someContainer').append(`
<div id="curve_chart" style="width: 900px; height: 500px"><\/div>

<script type="text\/javascript" src="https:\/\/www.gstatic.com\/charts\/loader.js"><\/script>
<script type="text\/javascript">         
    google.charts.load('current', {'packages':['corechart']});
    google.charts.setOnLoadCallback(drawChart);
    
    function drawChart() {
        var data = google.visualization.arrayToDataTable([
        ['Year', 'Sales', 'Expenses'],
        ['2004',  1000,      400],
        ['2005',  1170,      460],
        ['2006',  660,       1120],
        ['2007',  1030,      540]
        ]);
        
        var options = {
        title: 'Company Performance',
        curveType: 'function',
        legend: { position: 'bottom' }
        };
        
        var chart = new google.visualization.LineChart(document.getElementById('curve_chart'));
        
        chart.draw(data, options);
    }         
<\/script>
`);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id="someContainer"></div>

На скриншоте ниже вы можете видеть, что инициатором запроса для loader.js скрипта является jQuery. На правой панели вы видите ajax в стеке вызовов.

введите описание изображения здесь

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