Soru Bir javascript'i bir html'den nasıl kaldırabilirsiniz?


Bir JavaScript kaynağını DOM'dan tanımlanmış tüm nesneleriyle nasıl kaldırabilirim?

Html fragmanlarının bir "ana" html'ye yüklenmesini sağlayan basit bir çerçeve geliştiriyorum. Her parça kendi kendini içerir ve ek JS ve CSS dosyalarına referanslar içerebilir. JS ve CSS kaynakları ayrıştırılır ve html'ye dinamik olarak eklenir. Parça DOM'dan kaldırıldığında / değiştirildiğinde, JS ve CSS'yi kaldırmak istiyorum.

Aşağıdaki örnekte komut dosyası öğesini kaldırırsam, page1.js'de tanımlanan işlevler hala kullanılabilir.

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

Page1.js nesnelerini DOM'dan kaldırmanın bir yolu var mı?

======== Kullandığım test kodu =======

Aşağıdaki yorumlarda aldığım tavsiyeyi denedim; Bir temizleme işlevini kullanarak eklenen nesneleri silmek için - ama bu bile başarısız olur. Test için kullandığım kaynaklar:

<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 kaynağı:

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

18
2017-12-06 09:47


Menşei


Eğer nesnel bir şekilde bakarsanız, aynı şeyi yapmaya çalışıyorsunuz: stackoverflow.com/questions/3830133/.... . iframe'ler temizleme ile ilgili olabildiğince fazla yapmak için oldukça normal bir yol gibi görünmektedir. - Ravindra Sane
@Ravindra: iFrames kullanamıyorum çünkü parçanın boyutunun ne olduğunu bilmiyorum, ek olarak, parçanın sayfadaki mevcut kodla iletişim kurması gerekiyor. - Totach
Kaynak JS sizin tarafınızdan muhafaza ediliyor mu? Eğer evet ise, JS çevresinde mimarlık biraz yardımı olacaktır. Aşağıdaki cdhowie ve elusive cevaplar yardımcı olacaktır - Ravindra Sane
Hayır, kaynaklar benim tarafımdan korunmuyor. Başkalarının kullanması için bir çerçeve. Bu benim ana sorunum, ben 3. parti geliştiriciler için belirli tasarım desenleri takip etmek gerek kalmadan onu kullanmak için mümkün olduğunca basit hale getirmek istiyorum. - Totach
Bunu gerçekten yapmak istiyorsanız sayfanızın en üstünde bir komut dosyası hazırlayın <script src=load_save.js></script> belge yükünü sonlandırır ve ardından AJAX kullanarak aynı sayfayı ister ya da betikleri değiştirir ve böylece ön-src = url olur. Değiştirilmiş ön src değerleriyle sayfa belgesi yükle komut dosyalarını değiştirin ve ardından hangi değişiklikleri yapın. - William


Cevaplar:


Bu yapılamaz.

Bir betik yürütüldüğünde, işlev tanımları global olarak eklenir window nesne. İşlevin nereden geldiğini gösteren işleve eklenen hata ayıklama sembolleri olabilir, ancak bu bilgiler komut dosyalarında kullanılamaz.

Böyle bir şeye ulaşabilmenin tek yolu, senaryoda bir sözde-ad alanı oluşturmak ve işiniz bittiğinde tüm ad alanını atmak olacaktır. Ancak, bu soru bana yanlış bir şey yapmaya çalıştığınızı gösteriyor. Belki de senaryonuza odaklanmak, alternatif çözümler sunmamıza yardımcı olacaktır.


14
2017-12-06 09:52



Teşekkürler - nesneleri bir ad alanına eklemek ve daha sonra silmek en iyi yaklaşım gibi görünüyor. - Totach
@Totach: Bu yaklaşımı kullanırken bellek sızıntıları hala bir sorun, ancak muhtemelen bununla ilgilenmişsinizdir. - jwueller


Hayır, bu mümkün değil. Bu dosyada tanımlanan tüm değişkenleri kaldıran basit bir temizleme işlevi oluşturabilirsiniz:

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

// unload all resources
cleanup();

Başka bir yaklaşım ise, parçalarınız için modüler bir obje yapısının kullanılmasıdır. Bu, biraz daha yüksek bir ek yükü içerir, ancak kodu okumanın ve korumanın daha kolay hale getirdiğinden, muhtemelen buna değerdir:

// 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.

6
2017-12-06 09:51



Mümkün ancak temizleme işlemini manuel olarak tanımlamak ve bellek sızıntılarına neden olabilir. Tek bir html'nin ek JS ve CSS kaynaklarına bağlanan html fragmanlarını dinamik olarak yüklemesini sağlayan basit bir çerçeve im yazma için bu çözüme ihtiyacım var. Parçalar değiştirildiğinde, JS ve CSS bağlamlarını boşaltmam gerekir. - Totach
@Totach: Doğru, ama bu, bu değişkenlerden kurtulmanın tek yolu. Olayları ayırma, vb. Böyle yapıldığında dikkate alınmalıdır. Bu sadece basit bir örnektir. - jwueller
Çözümünüzü denedim ama garip bir nedenden dolayı - nesneler silinemez !? (false firefox içinde döndürülür). Komut dosyası bir komut dosyası etiketi oluşturarak dinamik olarak yüklenir. Herhangi bir fikir? çok teşekkürler! - Totach
@Totach: Firebugs konsolunu kullanarak aşağıdakileri denedim: var foo = 'bar', cleanup = function () { delete window.foo; delete window.cleanup; }; cleanup(); ve beklendiği gibi çalışıyor. Tam hata mesajınız nedir? - jwueller
Konsolda da benim için çalışıyor. Ancak html'de betiği bir komut dosyası etiketi oluşturarak yüklerim ve bunu başlık öğesine (JavaScript kullanarak) yüklerim. Eklenen komut dosyası tarafından eklenen nesneleri silmeye çalışırken "false" döndürülür ve nesneler tanımlanmış kalır. Dikkat ettiğim, bir ad alanı nesnesi kullanırsam, ad alanı nesnesinin silinemeyeceği, ancak ad alanında tanımlanmış nesnelerin silinebileceğidir ... (tekrar teşekkürler) - Totach


Belki de koşullu olarak onu boşalttığından daha koşullu olarak yüklemeyi düşünmelisiniz ...


4
2017-12-06 09:50





Belirli bir nesneyi kaldırmanız gerekiyorsa, oldukça kolaydır: {}

yani: myobj = {};

Öyleyse, hangi nesnelerin özel olarak yaratıldığını biliyorsanız, hiç de zor olmayacaktır.

Öte yandan, hangi nesnelerin özel olarak yaratıldığını bilmiyorsanız, bunu öğrenmek için bir mechansim yoktur - Javascript'in size özel olarak neyin tanımlandığını size söyleyememesini isteyemezsiniz.

Bununla birlikte, belirli bir javascript dosyasında hangi nesnelerin yüklendiğini bilmiyorsanız, muhtemelen yükleme konusunda herhangi bir iyilik yapmıyorsunuz demektir (sitenizde hangi kodun geçerli olduğu konusunda her zaman mantıklı bir fikre sahip olmalısınız). veya el ile boşaltmaya çalışırken (ne yaptığını bilmiyorsanız, bunun üçüncü bir tarafın içerdiğini ima eder, bu da el ile işaretlemenin elden çıkarılmasının muhtemel olduğu anlamına gelir).


1
2017-12-06 10:01



İşlevlerle de yapılabilirdi: function name()={} - jechaviz


Kendim gibi bir şey için araştırma yapıyordum ve bulgularımı yayınlayacağımı düşündüm.

  1. Malzemelerinizi js dosyasındaki genel bir ad alanında sarın, böylece kolayca kaldırılabilir, yani var stuff = {blabla: 1, yöntem: işlev () {}};

  2. Ondan kurtulmak gerektiğinde, sadece birşeyler = {}, veya null bile

  3. Komut etiketini sayfadan kaldır

*** requirejs kullanırsanız - js yeniden tanımlamak zorlamak için tanımı gerektirir

Not: Ad alanı içindeki modüllere başka bir yerden referans olmadıkça, her şey GC tarafından toplanacak ve gitmekte fayda var.


0
2017-08-05 15:19





Bunun için bir numara buldum. Bunun için bir cevap bulmak için günler merak ediyordum ve java Script'i boşaltmaya çalışmadan bunu yapmak için mükemmel bir numara yaptık. sadece yapmanız gereken gibi bir global değişken oluşturmak currentPage senin içinde main sayfanın java komut dosyası ve sayfayı yüklediğinizde sayfa adını currentPage . sonra birbirimize .js dosya kullanımı $('document').ajaxComplete() verilen $('document').ready() her birinde ilk satır olarak bir if ifadesi ekleyin $('document').ajaxComplete() işlevi. kontrol etmek için ayarla currentPage değişken, yeni bir sayfa adına eşittir. if deyiminin içindeki tüm diğer olayları ekleyin. İngilizceyi çok iyi bilmiyorum, bu yüzden kodumu kontrol et. Bu benim ilk cevabım, bazı hatalar yaparsam çok üzgünüm.

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" />');
}

tüm sayfalarım komut dosyaları ve stiller ayrı klasör görünümleri, 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');
        });*/
    }
});

Düğmenin hala eski komut dosyasının etkilenip etkilenmediğini kontrol etmek için her komut dosyasında bir düğme yorumladı.


0
2017-07-22 10:55





onları yapabilirsin = null

    function fnc1 (){

    }

    window.fnc1  = null
    //or
    window["fnc1"]  = null

0
2017-08-07 15:10