Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: JavaScript: Ajaxilla ladatun Js-tiedoston poistaminen

Sivun loppuun

dartvaneri [10.01.2017 14:27:49]

#

Lataan JavaScript-tiedoston käyttäen jQuery-kirjaston Ajax-funktiota seuraavaan tapaan:

$.ajax({
  url: "Testi.js",
  dataType: "script",
  cache: true,
  success: function(Data){

  }

Tuossa ei mitään ongelmaa, JavaScript-tiedosto latautuu hienosti. Mutta tahtoisin myös saada poistettua ko. tiedoston, mutten löydä ohjetta siihen.

Jos käytän JavaScriptin natiivi-funktioita ja luon niillä uuden script-elementin, toimii se muutoin hyvin, mutta se lataa aina palvelimelta uudelleen tiedostot, eikä käytä välimuistia lainkaan.

Koodi natiivi-funktiolla toteutettuun lataamiseen:

var head = document.getElementsByTagName("head")[0],
	script = document.createElement('script');
script.type = 'text/javascript';
script.src = "Testi.js";
head.appendChild(script);

Grez [10.01.2017 15:25:18]

#

dartvaneri kirjoitti:

Mutta tahtoisin myös saada poistettua ko. tiedoston, mutten löydä ohjetta siihen.

Mistä se pitäisi saada poistettua? Palvelimellahan se on tiedostona, mutta ei sitä clientista käsin saa poistettua palvelimelta, ellet tee palvelimelle jotain skriptiä sen poistamiseen.

dartvaneri [10.01.2017 15:44:44]

#

Se pitää saada poistettua DOMista, jottei ko. tiedoston koodit enää ole käytettävissä.

Esimerkkinä:
On modulaarinen järjestelmä, jota pitää pystyä päivittämään ajonaikaisesti. Olen nyt tehnyt uuden version yhdestä moduulista, ja päivittänyt kantaan versionumeron. Ohjelma pyytää palvelimelta uusimman versionumeron, ennen moduulin käyttöä, ja nyt kun versio on vaihtunut, ladataan palvelimelta uudet resurssit(js,css,html). Tämän lisäksi pitäisi vanha versio JavaScriptistä saada poistettua DOMista, jotta sen koodit eivät sotkisi ohjelman toimintaa.

Toivottavasti selkeni.

Metabolix [10.01.2017 16:06:02]

#

DOM ei sisällä JavaScriptin funktioita. DOM sisältää tekstimuotoisen koodin, ja kun se on suoritettu, funktiot ovat olemassa aivan DOMista riippumatta.

Tilanne on ihan sama jQueryllä, perus-DOMilla tai vaikka evalilla:

var s = "function f() { alert('foo'); }";
eval(s);
s = null;
f(); // f pysyy, vaikka s on "poistettu".

JavaScriptissa funktio on olio ja funktion nimi on muuttuja. Tavallaan voit poistaa funktioita asettamalla arvoksi null:

function f() { alert('foo'); }
f(); // ok
f = null
f(); // fail

Tämä ei silti poista funktioita, jotka on esimerkiksi sidottu tapahtumankäsittelijöihin, eli kaikki paikat pitää siivota itse.

Yksi mahdollisuus on suunnitella sivu niin, että esimerkiksi tapahtumankäsittelijöiden sisältä kutsutaan globaalin olion funktioita, jolloin tapahtumankäsittelijöitä ei tarvitse uudistaa päivityksen yhteydessä.

var G = {};
elementti.addEventListener("click", function(e) { G.click.call(this, e); });
G.click = function(e) { alert('foo'); }; // voi ongelmitta päivittää näin

Helpointa on vain ladata sivu uudestaan, jos koodia ei voi turvallisesti päivittää lennossa. Jos et käytä liikaa globaaleja muuttujia, voit tehdä saumattoman päivityksen niin, että päivitysvaiheessa tallennat sivun tilan jonnekin, päivität koko DOMin ja skriptit JS:llä ja palautat tilan säilöstä.

dartvaneri [10.01.2017 18:54:24]

#

Okei. Mistä se johtuu, ettei sitä JS-koodia voi päivittää? (Jos sitä joskus jotain oppis)

Globaaleihin muuttujiinhan(5-20kpl/moduuli) tuo tila pääsääntöisesti on tallennettu. Talteen ne menee varmaan helpoiten tällä tavalla:

function GlobalVariablesToStorage(prefix) {
	for (var prop in window) {
		if (prop.indexOf(prefix) == 0){
			var Data = typeof window[prop] == 'object' ? JSON.stringify(window[prop]) : window[prop];
			localStorage.setItem(prop, Data);
		}
	}
}

Tuohon kaveriksi sitten jonkilainen skripti tilan palauttamiseksi. Jos en keksi, miten saan DOMin ja skriptit päivitettyä JS:llä, niin täytynee sitten tyytyä tuohon sivun uudelleenlataamiseen, ja tilan palauttamiseen.

Metabolix [10.01.2017 19:29:50]

#

dartvaneri kirjoitti:

Okei. Mistä se johtuu, ettei sitä JS-koodia voi päivittää? (Jos sitä joskus jotain oppis)

Esimerkiksi C++-ohjelmaa ei voi päivittää ajon aikana muokkaamalla sen lähdekoodia, koska koodi on jo käännetty ja suoritettavana. Ihan samanlainen asia pätee JavaScriptiin: script-tagin sisältämä koodi käännetään ja suoritetaan yhden kerran, ja myöhempi koodin muuttaminen ei vaikuta siihen, mitä aiemmasta suorituksesta jo tuli.

JS-funktio ei ole tekstinpätkä tiedostossa, ja JS-tulkki ei etsi funktiota nimen perusteella tiedostosta. JS-funktion ”määrittely” on suoritettavaa koodia, jossa luodaan olio (funktio-olio) ja sijoitetaan se muuttujaan. Jos tuota muuttujaa (funktio-oliota) on sitten kopioitu muualle, kaikki kopiot eivät häviä vain alkuperäisen muuttujan vaihtamisella.

The Alchemist [11.01.2017 13:55:41]

#

dartvaneri kirjoitti:

Esimerkkinä:
On modulaarinen järjestelmä, jota pitää pystyä päivittämään ajonaikaisesti. Olen nyt tehnyt uuden version yhdestä moduulista, ja päivittänyt kantaan versionumeron. Ohjelma pyytää palvelimelta uusimman versionumeron, ennen moduulin käyttöä, ja nyt kun versio on vaihtunut, ladataan palvelimelta uudet resurssit(js,css,html). Tämän lisäksi pitäisi vanha versio JavaScriptistä saada poistettua DOMista, jotta sen koodit eivät sotkisi ohjelman toimintaa.

Jostain syystä et onnistunut vastaamaan kysymykseen: Miksi käyttäjän selaimessa oleva koodi pitäisi erikseen päivittää? Koodihan päivittyy automaattisesti silloin, kun sivu ladataan uudestaan. Et tarvitse erillistä päivitysten hallintaa siihen.

dartvaneri [11.01.2017 14:39:50]

#

Järjestelmä on luonteeltaan sellainen, että se voi olla jatkuvasti auki, eikä sitä sivua siis kovinkaan usein päivitetä. Näin ollen, esimerkiksi tietoturvapäivityksessä päivitystä ei välttämättä saada käyttäjälle riittävän nopeasti. Enkä voi laittaa pakotettua sivun päivitystäkään, koska käyttäjällä voi olla jotain tärkeää meneillään.

fergusq [11.01.2017 19:35:01]

#

Kaiken koodin päivittäminen on helpointa lataamalla sivu uudestaan. Entä, jos päivityksen tullessa käyttäjälle näytettäisiin alert-ilmoitus ja jos käyttäjä ei vastaa siihen 30 sekunnin kuluessa, sivu päivitetään uudestaan.

dartvaneri [11.01.2017 21:50:38]

#

Niin, voi olla, että on näissä puitteissa helpoin ja järkevin tehdä tuon tyylinen ratkaisu.

Grez [12.01.2017 18:35:43]

#

En mä kyllä nää mitään ongelmaa miksikö en voisi päivittää sivun käyttämää koodia sen jälkeen kun se on ladattu lataamatta koko sivua uudelleen, jos niin haluaisin tehdä. Kuulostaa vaan siltä että viritetään taas jotain ihme himmeliä kun voisi jotain järkevääkin tehdä :/

groovyb [13.01.2017 01:56:43]

#

Yleisesti ottaen, et päivitä vanhoja koodeja, vaan versioit uudet (Jos nyt tuotantoympäristöstä puhutaan). ja kun olet testannut uudet versiot, vaihdat ne käyttöön. Vaikka sitten ajamalla pakkorefreshin. tämänkin voit tehdä helposti esim websocketilla, ja työnnät clientteihin ko. käskyn. Reaaliaikaisesti nuo javascriptit saa esim webpackillä streamattua bundlena suoraan, jolloin ne myös päivittyy kun koodeja muutetaan.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta