Подтвердить что ты не робот

Как выгрузить javascript из html?

Как я могу выгрузить ресурс JavaScript со всеми его определенными объектами из DOM?

Im разрабатывает простую структуру, которая позволяет загружать фрагменты html в "основной" html. Каждый фрагмент является самодостаточным и может включать ссылки на дополнительные файлы JS и CSS. Ресурсы JS и CSS анализируются и динамически добавляются в html. Когда фрагмент удаляется/заменяется из DOM, я хочу удалить его JS и CSS.

Если я удалю элемент script в приведенном ниже примере, функции, определенные в page1.js, все еще доступны.

<html>
  <head>
    <script src="page1.js" type="text/javascript"></script>
  </head>
<body>
...

Есть ли способ выгрузить объекты page1.js из DOM?

========= Код проверки, который я использую =======

Я попробовал совет, который я получил в комментариях ниже; для удаления добавленных объектов с помощью функции очистки - но даже это не удается. Источники, которые я использовал для тестирования:

<html>
<head>
<script type="text/javascript">
    function loadJSFile(){
        var scriptTag = document.createElement("script");
        scriptTag.setAttribute("type", "text/javascript");
        scriptTag.setAttribute("src", "simple.js");

        var head = document.getElementsByTagName("head")[0];
        head.appendChild(scriptTag);
    }

    function unloadJSFile(){            
        delete window.foo;
        delete window.cleanup;
        alert("cleanedup. typeof window.foo is " + (typeof window.foo));
    }
</script>
</head>
<body>

  Hello JavaScript Delete

  <br/>
  <button onclick="loadJSFile();">Click to load JS</button>
  <br/>
  <button onclick="foo();">call foo()</button>
  <br/>
  <button onclick="unloadJSFile();">Click to unload JS</button>

</body>
</html>

simple.js источник:

var foo = function(){
    alert("hello from foo");
}
4b9b3361

Ответ 1

Это невозможно сделать.

Когда выполняется script, определения функций добавляются к глобальному объекту window. Могут быть отладочные символы, прикрепленные к функции, указывающей, откуда появилась функция, но эта информация недоступна для скриптов.

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

Ответ 2

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

var foo = 'bar';
var cleanup = function () {
    delete window.foo;
    delete window.cleanup;
};

// unload all resources
cleanup();

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

// creates the object using the second parameter as prototype.
// .create() is used as constructor
GlobalModuleHandlerThingy.addModule('my_module', {
    create: function () {
        this.foo = 'bar';
        return this;
    },
    foo: null,
    destroy: function () {
        // unload events, etc.
    }
});

GlobalModuleHandlerThingy.getModule('my_module').foo; // => bar
GlobalModuleHandlerThingy.unloadModule('my_module'); // calls .destroy() on the module and removes it.

Ответ 3

возможно, вам нужно условно загрузить его, а не условно разгружать его...

Ответ 4

Если вам нужно выгрузить определенный объект, это довольно просто: просто установите его на {}

т.е.: myobj = {};

Итак, если вы знаете, какие объекты создаются в определенном include, это не будет сложно.

С другой стороны, если вы не знаете, какие объекты создаются в конкретном include, то не существует mechansim, чтобы узнать - вы не можете попросить Javascript рассказать вам, что было определено в конкретном include.

Однако я бы сказал, что, если вы не знаете, какие объекты загружаются в конкретный файл javascript, вы, вероятно, не делаете никаких преимуществ при его загрузке (вы всегда должны иметь разумное представление о том, что делает код в ваш сайт), или при попытке выгрузить его вручную (если вы не знаете, что он делает, что подразумевает включение его третьей стороны, что означает, что отмена его вручную может привести к поломке вещей).

Ответ 5

Я сам что-то изучал и думал, что опубликую мои результаты

  • Оберните свой материал в глобальное пространство имен в файле js, чтобы его можно было легко удалить, т.е. var stuff = {blabla: 1, method: function() {}};

  • Когда вам нужно избавиться от него, просто установите stuff = {} или null даже

  • Удалить тег script со страницы

*** Если вы используете requirejs - require js удалить определение, чтобы принудительно перезагрузить

Примечание. До тех пор, пока вы не ссылаетесь на модули внутри пространства имен из любого места, все будет собрано GC, и вы хорошо пойдете.

Ответ 6

Я подумал об этом. Мне было интересно, как здесь дни находят ответ для этого, и я просто понял идеальный трюк, чтобы сделать это, не пытаясь выгрузить java Script. только вам нужно создать глобальную переменную типа currentPage на странице main java script, а при загрузке страницы назначьте имя страницы currentPage. то в любом другом файле .js используйте $('document').ajaxComplete() insted из $('document').ready() добавьте оператор if в первую строку внутри каждой функции $('document').ajaxComplete(). установите для параметра currentPage значение, равное новому имени страницы. добавить все другие события внутри оператора if. Я не очень хорошо знаю английский, поэтому проверьте мой код. и это мой первый ответ здесь, так извините, если я ошибаюсь.

main.html

<body>
    <div id='container></div>
    <button id="load1">
    <button id="load1">
</body>

main.js

var currentPage = "";

$(document).ready(function () {
    $('#load1').click(function () {
        loadSource('page1', 'body');
    });
    $('#load2').click(function () {
        loadSource('page2', 'body');
    });
});

function loadSource( page, element){
    currentPage = page;
    $('#container').load('views/' + page + '.php', element);
    $.getScript('js/' + page + '.js');
    $('#css').prop('disabled', true).remove();
    $('head').append('<link rel="stylesheet" href="css/' + page + '.css" type="text/css" />');
}

все мои скрипты и стили страниц находятся в отдельных представлениях папок, js, css.

page1.html

<body>
    <button id="test1">
    <button id="test2">
</body>

page1.js

$(document).ajaxComplete(function () {
    if(currentPage == 'page1'){
        /*$('#test1').click(function () {
            console.log('page1');
        });*/
        $('#test2').click(function () {
            console.log('page1');
        });
    }
});

page2.html

<body>
    <button id="test1">
    <button id="test2">
</body>

page2.js

$(document).ajaxComplete(function () {
    if(currentPage == 'page2'){
        $('#test1').click(function () {
            console.log('page2');
        });
        /*$('#test2').click(function () {
            console.log('page2');
        });*/
    }
});

Я прокомментировал одну кнопку в каждом script, чтобы проверить, действительно ли эта кнопка имеет старый script.