1

I'm replacing in a 'page' the html content of a div from MySQL (via php) and sometimes but not always inserting, from MySQL, any javascript needed for that content using $.getScript().

This all works OK. When the user clicks next page it gets new html and javascript from MySQL but after many many pages it has accumulated many scripts which seems like a bad idea to me as I don't want scripts no longer needed floating around. They can be re-loaded if the user clicks the 'previous page' button (what happens then - multiple instances of the same script?).

These scripts get audio content (ion.sound) with arrays of data ~100 elements. It seems that there's no way to delete those scripts and free up memory.

I'm worried about eventual performance issues. Or is this the completely wrong way of doing it?

Any help appreciated.

vsync
  • 118,978
  • 58
  • 307
  • 400
DumbBunny
  • 11
  • 2
  • I think it's not that easy out of the box, but this question seems to give some good suggestions (although it doesn't use the getScript option) https://stackoverflow.com/questions/4365062/how-to-unload-a-javascript-from-an-html – Icepickle May 31 '17 at 07:31

2 Answers2

0

This probably wouldn't work with the getScript functionality. The reason is that in general, items get added to the global namespace after they loaded. There is already a good discussion on this question

Based on those suggestions, you could load your script, and save the differences inside the global namespace, and when you remove the script, simply remove those object again from the global namespace.

The example here loads jQuery when you click on the button, then checks which changes were made to the global window object and upon removal, deletes those items again from the window object.

const jQueryId = "#jQuery-loaded-js-id";

function addJQuery( cb ) {
  if (document.querySelector(jQueryId)) {
    console.info('JQuery already loaded');
    return;
  }
  var scriptElem = document.createElement('script');
  scriptElem.id = jQueryId.substr(1);
  scriptElem.addEventListener('load', function( windowKeys, e ) {
    console.log( 'jQuery loaded' );
    // get the difference of keys between before load and after load
    // this will only work if no other scripts were loaded in between
    // which would mean, scripts should only be loaded one at the time
    var newKeys = Object.keys( window );
    var diff = newKeys.reduce( (set, item) => {
      if (windowKeys.indexOf(item) === -1) {
        set.push( item );
      }
      return set;
    }, []);
    scriptElem.dataset.globalKeys = diff;
  }.bind(this, Object.keys(window)) );
  scriptElem.src = 'https://code.jquery.com/jquery-2.2.4.min.js';
  document.body.appendChild( scriptElem );
}

function isJQueryAvailable() {
  // checks if jQuery exists
  alert( !!(window.jQuery || window.$) );
}

function removeJQuery() {
  var elem;
  if (!( elem = document.querySelector(jQueryId) )) {
    console.info('not available');
    return;
  }
  document.body.removeChild(elem);
  // removes any of the global keys added to the DOM
  var keys = elem.dataset.globalKeys.split(',');
  for (let i = 0; i < keys.length; i++) {
    delete window[keys[i]];
  }
  console.info('JQuery removed');
}
<button type="button" onclick="addJQuery()">Get JQuery</button>
<button type="button" onclick="isJQueryAvailable()">Does JQuery Exist?</button>
<button type="button" onclick="removeJQuery()">Remove JQuery</button>

The example shouldn't really be what you need to implement, because it oversimplifies what could happen when a script loads. Probably you need to think of a more module based approach, where the scripts you load have a way to dispose themselves. I am just giving you an example of a potential approach

Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175
Icepickle
  • 12,689
  • 3
  • 34
  • 48
0

It seems that scripts don't hang around after calling $.getScript() as it loads the script then executes it. I put in a simple mechanism to count scripts and the number varies per page but is not accumulated - I think. Anyway I'll blunder on.

DumbBunny
  • 11
  • 2