Определить, работает ли какая-либо функция JavaScript - PullRequest
12 голосов
/ 09 января 2012

Я знаю, это может звучать очень странно, но мне нужно знать, есть ли на странице активный / работающий javascript.

Я нахожусь в ситуации, когда мне приходится запускать свой код javascript / jquery после того, как все на странице отрендерено и все остальные сценарии завершены.

Возможно ли это обнаружить?

EDIT:

Спасибо всем за ответы. К сожалению, я не смог найти решение, потому что у меня нет полного контроля над тем, что происходит на странице.

Даже, я смог поместить свой javascript в конец страницы, я думаю, что это не будет решением снова. Причина в том, что когда страница выполняет рендеринг функции, она вызывает другие функции, они вызывают другие и так далее. В результате некоторые данные неверны, и поэтому мне нужно запустить мой код, чтобы исправить это.

Я использую setTimeout с 2 секундами, чтобы мой код выполнялся последним, но это ужасно ...

Итак, спасибо всем, но это больше проблема с системой, а не с js.

Ответы [ 3 ]

13 голосов
/ 09 января 2012

JavaScript в веб-браузерах является однопоточным (за исключением использования веб-работников ), поэтому, если ваш код JavaScript работает, по определению никакой другой код JavaScript не выполняется. *

Чтобы убедиться, что ваш скрипт выполняется после того, как все другие JavaScript на странице были загружены и оценены, и после того, как все рендеринг произошел, некоторые предложения:

  • Поместите тег script для вашего кода в самом концефайла.
  • Используйте атрибуты defer и async в теге (они будут игнорироваться браузерами, которые их не поддерживают, но цель состоит в том, чтобываш последний столько, сколько мы можем).
  • Перехват события window load через соединение в стиле DOM2 (например, addEventListener в браузерах с поддержкой стандартов или attachEvent в более старых версиях IE).
  • В событии load запланируйте выполнение своего кода после setTimeout с задержкой 0 мс (на самом деле это не будет ноль, это будет немногобольше).

Итак, тег script:

<script async defer src="yourfile.js"></script>

... и yourfile.js:

(function() {
    if (window.addEventListener) {
        window.addEventListener("load", loadHandler, false);
    }
    else if (window.attachEvent) {
        window.attachEvent("onload", loadHandler);
    }
    else {
        window.onload = loadHandler; // Or you may want to leave this off and just not support REALLY old browsers
    }

    function loadHandler() {
        setTimeout(doMyStuff, 0);
    }

    function doMyStuff() {
        // Your stuff here. All images in the original markup are guaranteed
        // to have been loaded (or failed) by the `load` event, and you know
        // that other handlers for the `load` event have now been fired since
        // we yielded back from our `load` handler
    }
})();

Это не означает, что другой код не запланировал себя запустить позже (например, через setTimeout, как мы делали выше).но с более длительным тайм-аутом), хотя.

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


(* Есть некоторые крайние случаи, когда поток может быть приостановлен в одном месте, а затем разрешить другому кодузапускать в другом месте [например, когда вызов ajax завершается, когда отображается сообщение alert, некоторые браузеры запускают обработчик ajax, даже если другая функция ожидает отклонения alert], но они на границеслучаев, и все еще активно выполняется только одна вещь.)

3 голосов
/ 05 февраля 2016

Создать загрузчик

Привет, поскольку javaScript может выполнять асинхронные функции или вызовы, мне также нужен был способ узнать, когда страница была в стабильном состоянии. Для этой цели я использую крошечный загрузчик в каждой из моих функций:

    var loading_var = 0;

    // some functions in your code that may not execute at the same time
    // or have to wait an async call
    function f1() {
      loading_var++;
      // code to be exectuted
      onready();
    }

    function f2() {
      loading_var++;
      // code to be exectuted
      onready();
    }

    // loader function
    function onready() {
      loading_var--;
      if(loading_var == 0) {
        // Means all functions have finished executing !
        }
    }

Я часто связываю его с функцией freezeClic , чтобы запретить пользователям взаимодействовать со страницей, когда существует сценарий, все еще ожидающий ответ ajax / async (и, возможно, отображающий значок или экран предварительного загрузчика).

2 голосов
/ 09 января 2012

Нет определенного способа сделать это, потому что вы не можете точно знать, что является последним, что другие сценарии запланировали для себя. Вам нужно будет решить, на что вы хотите нацелиться.

  1. Вы можете попытаться запустить ваш скрипт после всего, что может работать при загрузке DOM.
  2. Вы можете попытаться запустить ваш скрипт после всего, что может быть запущено, когда страница полностью загружена (включая изображения).

Не существует надежного кросс-браузерного способа узнать, какие из этих событий используются скриптами на странице.

В любом случае вы перехватываете соответствующее событие и затем используете setTimeout(), чтобы попытаться запустить ваш скрипт после всего, что наблюдает за этими событиями.

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

window.addEventListener("load", function() {
    setTimeout(function() {
        // put your code here
    }, 1);
}, false);

Вам придется использовать attachEvent() для более старых версий IE.

При использовании этого метода вам не нужно беспокоиться о том, где ваши скрипты загружаются на странице относительно других скриптов на странице, так как это планирует запуск вашего скрипта в определенное время после определенного события.

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