2008-10-16 2 views
16

Existe-t-il un outil qui vous permette d'échanger à chaud du contenu JavaScript lors de l'exécution d'une page Web?Existe-t-il un moyen de "remplacer à chaud" le code JavaScript dans le navigateur?

Je cherche quelque chose de similaire à ce que fait HotSpot pour Java, un moyen de "déployer à chaud" le nouveau code JS sans avoir à recharger toute la page.

Y at-il quelque chose comme ça là-bas?

clarifiant les cas ne comprennent pas « hot swap », comme indiqué par verrouillage:

par « hot swap » Je veux dire me permettant de modifier certaines parties du code figurant sur la page elle-même et ses fichiers .js.

Ensuite, ce cadre détecterait la modification - soit automagiquement ou d'après certaines indications de ma part - et rechargerait le code dynamiquement, en évitant la nouvelle publication côté serveur (recharger). Ce type d'approche simplifierait le débogage et la résolution des erreurs, puisque vous n'avez pas besoin de recharger la page et de recommencer l'interaction à partir de zéro.

+0

la meilleure façon de le faire est d'utiliser un système de modules comme RequireJS - https://medium.com/@the1mills/hot-reloading-with-react- requirejs-7b2aa6cb06e1 –

Répondre

4

idée intéressante :)

J'ai écrit le bookmarklet suivant:

function reload(){var scripts=document.getElementsByTagName("script");var head=document.getElementsByTagName("head")[0];var newScripts=[];var removeScripts=[];for(var i=0;i<scripts.length;i++){var parent=scripts[i].parentNode;if(parent==head&&scripts[i].src){var newScript={};newScript.src=scripts[i].src;newScript.innerHTML=scripts[i].innerHTML;newScripts.push(newScript);removeScripts.push(scripts[i]);}}for(var i=0;i<removeScripts.length;i++){head.removeChild(removeScripts[i]);}for(var i=0;i<newScripts.length;i++){var script=document.createElement("script");script.src=newScripts[i].src;script.type="text/javascript";script.innerHTML=newScripts[i].innerHTML;head.appendChild(script);}} 

ajouter que l'emplacement d'un nouveau signet, et il rechargera tous les javascripts référencés dans < tête >. Je ne sais pas si cela marchera en pratique, mais ça valait le coup :) Je suppose que vous devriez être très prudent dans la façon dont vous écrivez vos scripts, afin de ne pas avoir plusieurs choses ajoutées au corps de la page plusieurs fois, etc. Peut-être que le support d'un attribut 'reload = "true"' pourrait être utile, de cette façon vous ne pouvez étiqueter que vos bibliothèques comme rechargeables.

source complet:

function reload() { 
    var scripts = document.getElementsByTagName("script"); 
    var head = document.getElementsByTagName("head")[0]; 
    var newScripts = []; 
    var removeScripts = []; 
    for(var i=0; i < scripts.length; i++) { 
     var parent = scripts[i].parentNode; 
     if(parent == head && scripts[i].src) { 
      var newScript = {}; 
      newScript.src = scripts[i].src; 
      newScript.innerHTML = scripts[i].innerHTML; 
      newScripts.push(newScript); 
      removeScripts.push(scripts[i]); 
     } 
    } 

    for(var i=0; i < removeScripts.length; i++) { 
     head.removeChild(removeScripts[i]); 
    } 

    for(var i=0; i < newScripts.length; i++) { 
     var script = document.createElement("script"); 
     script.src = newScripts[i].src; 
     script.type = "text/javascript"; 
     script.innerHTML = newScripts[i].innerHTML; 
     head.appendChild(script); 
    } 
} 
0

Si vous voulez faire cela avec entiers fichiers JavaScript, voir this question pour quelque chose de suffisamment similaire que vous devriez être en mesure d'obtenir les bases de l'idée.

1

Je ne suis pas familier avec HotSport, mais si vous parlez de charger dynamiquement JavaScript, oui, vous pouvez le faire. MooTools vous permet de le faire, tout comme , Prototype, Dojo, et YUI, et je suis sûr que la plupart des autres frameworks le font aussi. Vous pouvez également le faire avec native JavaScript.

1

im sûr de ne pas trop de gens ici savent ce que vous entendez par hot swap mais comme virtuosiMedia dit Mootools permet que, si vous ne faire confiance Mootools beaucoup alors il y a un même plug-in pour jquery et encore si vous ne voulez pas que les cadres vous pouvez toujours ajouter ces scripts via dom

mais je suis sûr que vous n'êtes pas autorisé à modifier les scripts de niveau de la tête que vous avez déjà défini comme des scripts ajoutés dynamiquement par DOM est seulement le niveau du corps

+0

J'ai ajouté une clarification, faites le moi savoir si c'est mieux. – kolrie

3

Depuis que j'ai eu un problème similaire à résoudre, j'ai écrit lib un petit javascript pour hotswap, les fichiers css et les images.Il est bien sûr open source sur github: hotswap.js

Espérons que ça aide.

Mise à jour: J'ai joint la source de la bibliothèque complète ici. Pour l'utiliser il suffit de copier le contenu dans un fichier (par exemple: hotswap.js) et insérer la balise de script dans votre site web comme celui-ci:

<script src="hotswap.js"></script> 

API:

// refresh .js files 
hotswap.refreshAllJs(arrExcludedFiles); 
hotswap.refreshJs(arrIncludedFiles); 

// refresh .css files 
hotswap.refreshAllCss(arrExcludedFiles); 
hotswap.refreshCss(arrIncludedFiles); 

// refresh images 
hotswap.refreshAllImg(arrExcludedFiles); 
hotswap.refreshImg(arrIncludedFiles); 

// show a gui (this is optional and not required for hotswap to work) (Click on the "H"). 
hotswap.createGui(); 

// Examples: 
// refresh all .js files 
hotswap.refreshAllJs(); 

// refresh main.css only 
hotswap.refreshCss(["main.js"]); 

// refresh all images (img tags) except "dont-refreh-me.png". 
hotswap.refreshAllImg(["dont-refreh-me.png"]); 

source complet (0,2 v. .0):

J'ai dû supprimer tous les commentaires pour le faire sous la limite de réponse de 30000 caractères. Le html + css en ligne est moche je sais, mais je voulais garder ceci dans un seul fichier .js.

(function() { 
    var root = this; 
    var previousHotswap = root.hotswap; 
    var hotswap = function() 
    { 
     if (!(this instanceof hotswap)) 
     { 
      return new hotswap(); 
     } 
     else 
     { 
      return this; 
     } 
    }; 
    root.hotswap = hotswap(); 
    hotswap.prototype.VERSION = '0.2.0'; 
    hotswap.prototype.RND_PARAM_NAME = 'hs982345jkasg89zqnsl'; 
    hotswap.prototype.FILE_REMOVAL_DELAY = 400; 
    hotswap.prototype.CSS_HTML_PREFIX = 'hs982345jkasg89zqnsl'; 
    hotswap.prototype._prefix = false; 
    hotswap.prototype._prefixCache = []; 
    hotswap.prototype._guiCache = {}; 
    hotswap.prototype._guiGuiRefreshInterval = null; 
    hotswap.prototype._guiHtml = '' + 
     '<style type="text/css">'+ 
     ' #PREFIX'+ 
     ' {'+ 
     '  display: block;'+ 
     '  position: fixed;'+ 
     '  top: 20%;/*distance from top*/'+ 
     '  right: 0;'+ 
     '  z-index: 99999;'+ 
     '  width: 20em;'+ 
     '  height: auto;'+ 
     '  color: black;'+ 
     '  background-color: #666666;'+ 
     '  font-family: Verdana, sans-serif;'+ 
     '  font-size: 0.8em;'+ 
     '  -webkit-box-shadow: 0 0px 0.3em 0.1em #999999;'+ 
     '  -moz-box-shadow: 0 0px 0.3em 0.1em #999999;'+ 
     '  box-shadow: 0 0px 0.3em 0.1em #999999;'+ 
     ' }'+ 
     ' #PREFIX.mini'+ 
     ' {'+ 
     '  width: 2.9em;'+ 
     '  height: 2.9em;'+ 
     '  overflow:hidden;'+ 
     ' }'+ 
     ' #PREFIX.mini .PREFIX-header input, #PREFIX.mini .PREFIX-list, #PREFIX.mini .PREFIX-footer'+ 
     ' {'+ 
     '  display:none;'+ 
     ' }'+ 
     '  #PREFIX.mini .PREFIX-header div'+ 
     ' {'+ 
     '  display: block;'+ 
     '  width: 100%;'+ 
     '  height: 100%;'+ 
     ' }'+ 
     ' #PREFIX input'+ 
     ' {'+ 
     '  font-size: 1.0em;'+ 
     '  border: 0.1em solid #999999;'+ 
     '  border-radius: 0.2em;'+ 
     '  padding: 0.2em 0.1em;'+ 
     '  }'+ 
     ' #PREFIX .PREFIX-header'+ 
     ' {'+ 
     '  height: 2.4em;'+ 
     '  overflow:hidden;'+ 
     '  padding: 0.4em;'+ 
     '  color: white;'+ 
     '  background-color: black;'+ 
     '  }'+ 
     ' #PREFIX .PREFIX-header input'+ 
     ' {'+ 
     '  width: 83.5%;'+ 
     '  height: 1.6em;'+ 
     ' }'+ 
     ' #PREFIX .PREFIX-header div'+ 
     ' {'+ 
     '  position: absolute;'+ 
     '  top:0;'+ 
     '  right:0;'+ 
     '  width: 14.5%;'+ 
     '  height: 1.6em;'+ 
     '  line-height: 1.4em;'+ 
     '  text-align: center;'+ 
     '  font-size: 2em;'+ 
     '  font-weight: bold;'+ 
     '  cursor: pointer;'+ 
     ' }'+ 
     ' #PREFIX .PREFIX-header div:hover'+ 
     ' {'+ 
     '  background-color: #444444;'+ 
     ' }'+ 
     ' #PREFIX .PREFIX-list'+ 
     ' {'+ 
     '  width: 100%;'+ 
     '  height: 22em;'+ 
     '  overflow: auto;'+ 
     ' }'+ 
     ' #PREFIX ul'+ 
     ' {'+ 
     '  list-style-type: none;'+ 
     '  list-style-position: inside;'+ 
     '  padding: 0;'+ 
     '  margin: 0.5em 0.5em 1.2em 0.5em;'+ 
     ' }'+ 
     ' #PREFIX ul li'+ 
     ' {'+ 
     '  margin: 0.3em;'+ 
     '  padding: 0.5em 0.5em;'+ 
     '  color: white;'+ 
     '  background-color: #717171;'+ 
     '  font-size: 0.9em;'+ 
     '  line-height: 1.5em;'+ 
     '  cursor: pointer;'+ 
     ' }'+ 
     ' #PREFIX ul li:hover'+ 
     ' {'+ 
     '  background-color: #797979;'+ 
     ' }'+ 
     ' #PREFIX ul li.template'+ 
     ' {'+ 
     '  display: none;'+ 
     ' }'+ 
     ' #PREFIX ul li.active'+ 
     ' {'+ 
     '  background-color: black;'+ 
     ' }'+ 
     ' #PREFIX ul li.PREFIX-headline'+ 
     ' {'+ 
     '  color: white;'+ 
     '  background-color: transparent;'+ 
     '  text-align: center;'+ 
     '  font-weight: bold;'+ 
     '  cursor: default;'+ 
     ' }'+ 
     ' #PREFIX .PREFIX-footer'+ 
     ' {'+ 
     '  padding: 0;'+ 
     '  margin:0;'+ 
     '  background-color: #444444;'+ 
     ' }'+ 
     ' #PREFIX .PREFIX-footer ul'+ 
     ' {'+ 
     '  margin: 0;'+ 
     '  padding: 0.5em;'+ 
     ' }'+ 
     ' #PREFIX .PREFIX-footer ul li'+ 
     ' {'+ 
     '  color: white;'+ 
     '  background-color: black;'+ 
     '  font-size: 1.0em;'+ 
     '  border-radius: 0.5em;'+ 
     '  text-align: center;'+ 
     '  height: 2.2em;'+ 
     '  line-height: 2.2em;'+ 
     ' }'+ 
     ' #PREFIX .PREFIX-footer ul li input.PREFIX-seconds'+ 
     ' {'+ 
     '  text-align: center;'+ 
     '  width: 2em;'+ 
     ' }'+ 
     ' #PREFIX .PREFIX-footer ul li:hover'+ 
     ' {'+ 
     '  background-color: #222222;'+ 
     '  }'+ 
     ' #PREFIX .PREFIX-footer ul li.inactive'+ 
     ' {'+ 
     '  background-color: #666666;'+ 
     '  cursor: default;'+ 
     ' }'+ 
     ' </style>'+ 
     ' <div id="PREFIX" class="mini">'+ 
     '  <div class="PREFIX-header">'+ 
     '   <input id="PREFIX-prefix" placeholder="prefix" type="text" name="" />'+ 
     '   <div id="PREFIX-toggle">H</div>'+ 
     '  </div>'+ 
     '  <div class="PREFIX-list">'+ 
     '   <ul id="PREFIX-css">'+ 
     '    <li class="PREFIX-headline">CSS</li>'+ 
     '    <li class="template"></li>'+ 
     '   </ul>'+ 
     '   <ul id="PREFIX-js">'+ 
     '    <li class="PREFIX-headline">JS</li>'+ 
     '    <li class="template"></li>'+ 
     '   </ul>'+ 
     '   <ul id="PREFIX-img">'+ 
     '    <li class="PREFIX-headline">IMG</li>'+ 
     '    <li class="template"></li>'+ 
     '   </ul>'+ 
     '  </div>'+ 
     '  <div class="PREFIX-footer">'+ 
     '   <ul>'+ 
     '    <li id="PREFIX-submit-selected">refresh selected</li>'+ 
     '    <li id="PREFIX-submit-start">refresh every <input class="PREFIX-seconds" type="text" value="1" /> sec.</li>'+ 
     '    <li id="PREFIX-submit-stop" class="inactive">stop refreshing</li>'+ 
     '    <li id="PREFIX-submit-refresh-list">refresh list</li>'+ 
     '   </ul>'+ 
     '  </div>'+ 
     ' </div>'; 
    var 
     xGetElementById  = function(sId){ return document.getElementById(sId) }, 
     xGetElementsByTagName = function(sTags){ return document.getElementsByTagName(sTags) }, 
     xAppendChild   = function(parent, child){ return parent.appendChild(child) }, 
     xCloneNode   = function(node){ return document.cloneNode(node) }, 
     xCreateElement  = function(sTag){ return document.createElement(sTag) }, 
     xCloneNode   = function(ele, deep){ return ele.cloneNode(deep) }, 
     xRemove = function(ele) 
     { 
      if(typeof ele.parentNode != "undefined" && ele.parentNode) 
      { 
       ele.parentNode.removeChild(ele); 
      } 
     }, 
     xAddEventListener = function(ele, sEvent, fn, bCaptureOrBubble) 
     { 
      if(xIsEmpty(bCaptureOrBubble)) 
      { 
       bCaptureOrBubble = false; 
      } 
      if (ele.addEventListener) 
      { 
       ele.addEventListener(sEvent, fn, bCaptureOrBubble); 
       return true; 
      } 
      else if (ele.attachEvent) 
      { 
       return ele.attachEvent('on' + sEvent, fn); 
      } 
      else 
      { 
       ele['on' + sEvent] = fn; 
      } 
     }, 
     xStopPropagation = function(evt) 
     { 
      if (evt && evt.stopPropogation) 
      { 
       evt.stopPropogation(); 
      } 
      else if (window.event && window.event.cancelBubble) 
      { 
       window.event.cancelBubble = true; 
      } 
     }, 
     xPreventDefault = function(evt) 
     { 
      if (evt && evt.preventDefault) 
      { 
       evt.preventDefault(); 
      } 
      else if (window.event && window.event.returnValue) 
      { 
       window.eventReturnValue = false; 
      } 
     }, 
     xContains = function(sHaystack, sNeedle) 
     { 
      return sHaystack.indexOf(sNeedle) >= 0 
     }, 
     xStartsWith = function(sHaystack, sNeedle) 
     { 
      return sHaystack.indexOf(sNeedle) === 0 
     }, 
     xReplace = function(sHaystack, sNeedle, sReplacement) 
     { 
      if(xIsEmpty(sReplacement)) 
      { 
       sReplacement = ""; 
      } 
      return sHaystack.split(sNeedle).join(sReplacement); 
     }, 
     xGetAttribute = function(ele, sAttr) 
     { 
      var result = (ele.getAttribute && ele.getAttribute(sAttr)) || null; 
      if(!result) { 
       result = ele[sAttr]; 
      } 
      if(!result) { 
       var attrs = ele.attributes; 
       var length = attrs.length; 
       for(var i = 0; i < length; i++) 
        if(attrs[i].nodeName === sAttr) 
         result = attrs[i].nodeValue; 
      } 
      return result; 
     }, 
     xSetAttribute = function(ele, sAttr, value) 
     { 
      if(ele.setAttribute) 
      { 
       ele.setAttribute(sAttr, value) 
      } 
      else 
      { 
       ele[sAttr] = value; 
      } 
     }, 
     xGetParent = function(ele) 
     { 
      return ele.parentNode || ele.parentElement; 
     }, 
     xInsertAfter = function(refEle, newEle) 
     { 
      return xGetParent(refEle).insertBefore(newEle, refEle.nextSibling); 
     }, 
     xBind = function(func, context) 
     { 
      if (Function.prototype.bind && func.bind === Function.prototype.bind) 
      { 
       return func.bind(context); 
      } 
      else 
      { 
       return function() { 
        if(arguments.length > 2) 
        { 
         return func.apply(context, arguments.slice(2)); 
        } 
        else 
        { 
         return func.apply(context); 
        } 
       }; 
      } 
     }, 
     xIsEmpty = function(value) 
     { 
      var ret = true; 
      if(value instanceof Object) 
      { 
       for(var i in value){ if(value.hasOwnProperty(i)){return false}} 
       return true; 
      } 
      ret = typeof value === "undefined" || value === undefined || value === null || value === ""; 
      return ret; 
     }, 
     xAddClass = function(ele, sClass) 
     { 
      var clazz = xGetAttribute(ele, "class"); 
      if(!xHasClass(ele, sClass)) 
      { 
       xSetAttribute(ele, "class", clazz + " " + sClass); 
      } 
     }, 
     xRemoveClass = function(ele, sClass) 
     { 
      var clazz = xGetAttribute(ele, "class"); 
      if(xHasClass(ele, sClass)) 
      { 
       xSetAttribute(ele, "class", xReplace(clazz, sClass, "")); 
      } 
     }, 
     xHasClass = function(ele, sClass) 
     { 
      var clazz = xGetAttribute(ele, "class"); 
      return !xIsEmpty(clazz) && xContains(clazz, sClass); 
     }; 
    hotswap.prototype._recreate = function(type, xcludedFiles, xcludeComparator, nDeleteDelay, bForceRecreation) 
    { 
     if(typeof nDeleteDelay == "undefined") 
     { 
      nDeleteDelay = 0; 
     } 

     if(typeof bForceRecreation == "undefined") 
     { 
      bForceRecreation = false; 
     } 

     var tags = this._getFilesByType(type, xcludedFiles, xcludeComparator); 
     var newTags = []; 
     var removeTags = []; 
     var i, src, detected, node, srcAttributeName; 
     for(i=0; i<tags.length; i++) 
     { 
      node = tags[i].node; 
      srcAttributeName = tags[i].srcAttributeName; 
      var newNode = { 
       node: null, 
       oldNode: node, 
       parent: xGetParent(node) 
      }; 
      if(bForceRecreation) 
      { 
       newNode.node = xCreateElement("script"); 
      } 
      else 
      { 
       newNode.node = xCloneNode(node, false); 
      } 
      for (var p in node) { 
       if (node.hasOwnProperty(p)) { 
        newNode.node.p = node.p; 
       } 
      } 
      src = xGetAttribute(node, srcAttributeName); 
      xSetAttribute(newNode.node, srcAttributeName, this._updatedUrl(src)); 
      newTags.push(newNode); 
      removeTags.push(node); 
     } 
     for(var i=0; i < newTags.length; i++) { 
      xInsertAfter(newTags[i].oldNode, newTags[i].node); 
     } 
     if(nDeleteDelay > 0) 
     { 
      for(var i=0; i < removeTags.length; i++) { 
       xSetAttribute(removeTags[i], "data-hotswap-deleted", "1"); 
      } 

      setTimeout(function() { 
       for(var i=0; i < removeTags.length; i++) { 
        xRemove(removeTags[i]); 
       } 
      }, nDeleteDelay); 
     } 
     else 
     { 
      for(var i=0; i < removeTags.length; i++) { 
       xRemove(removeTags[i]); 
      } 
     } 
    }; 
    hotswap.prototype._reload = function(type, xcludedFiles, xcludeComparator) 
    { 
     var tags = this._getFilesByType(type, xcludedFiles, xcludeComparator); 
     var i, src, node, srcAttributeName; 
     for(i=0; i<tags.length; i++) 
     { 
      node = tags[i].node; 
      srcAttributeName = tags[i].srcAttributeName; 
      // update the src property 
      src = xGetAttribute(node, srcAttributeName); 
      xSetAttribute(node, srcAttributeName, this._updatedUrl(src)); 
     } 
    }; 
    hotswap.prototype._getFilesByType = function(type, xcludedFiles, xcludeComparator) 
    { 
     var files; 
     switch(type) 
     { 
      case "css": 
       files = this._getFiles(
        "css", 
        "link", 
        function(ele) 
        { 
         return (xGetAttribute(ele, "rel") == "stylesheet" || xGetAttribute(ele, "type") == "text/css"); 
        }, 
        "href", 
        xcludedFiles, 
        xcludeComparator 
       ) 
       break; 

      case "js": 
       files = this._getFiles(
        "js", 
        "script", 
        function(ele) 
        { 
         return (xGetAttribute(ele, "type") == "" || xGetAttribute(ele, "type") == "text/javascript"); 
        }, 
        "src", 
        xcludedFiles, 
        xcludeComparator 
       ) 
       break; 

      case "img": 
       files = this._getFiles(
        "img", 
        "img", 
        function(ele) 
        { 
         return (xGetAttribute(ele, "src") != ""); 
        }, 
        "src", 
        xcludedFiles, 
        xcludeComparator 
       ) 
       break; 
     } 

     return files; 
    } 
    hotswap.prototype._getFiles = function(type, tagName, tagFilterFunc, srcAttributeName, xcludedFiles, xcludeComparator) 
    { 
     if(typeof xcludedFiles == "undefined" || !xcludedFiles) 
     { 
      xcludedFiles = []; 
     } 

     if(typeof xcludeComparator == "undefined" || !xcludeComparator) 
     { 
      xcludeComparator = false; 
     } 

     var fileNodes = []; 
     var tags = xGetElementsByTagName(tagName); 
     var src, detected, node; 
     for(var i=0; i<tags.length; i++) { 
      node = tags[i]; 
      src = xGetAttribute(node,[srcAttributeName]); 
      if(xIsEmpty(xGetAttribute(node, "data-hotswap-deleted"))) 
      { 
       if(src && tagFilterFunc(node)) 
       { 
        detected = false; 
        for(var j=0; j<xcludedFiles.length; j++) { 
         if(xContains(src,xcludedFiles[j])) 
         { 
          detected = true; 
          break; 
         } 
        } 
        if(detected == xcludeComparator) 
        { 
         fileNodes.push({ 
          type: type, 
          node : node, 
          tagName : tagName, 
          srcAttributeName : srcAttributeName 
         }); 
        } 
       } 
      } 
     } 

     return fileNodes; 
    }; 
    hotswap.prototype._updatedUrl = function(url, getCleanUrl) 
    { 
     var cleanUrl; 
     if(typeof getCleanUrl == "undefined") 
     { 
      getCleanUrl = false; 
     } 
     url = cleanUrl = url.replace(new RegExp("(\\?|&)"+this.RND_PARAM_NAME+"=[0-9.]*","g"), ""); 
     var queryString = "", randomizedQueryString = ""; 
     if(xContains(url, "?")) 
     { 
      if(xContains(url, "&" + this.RND_PARAM_NAME)) 
      { 
       queryString = url.split("&" + this.RND_PARAM_NAME).slice(1,-1).join(""); 
      } 
      randomizedQueryString = queryString + "&" + this.RND_PARAM_NAME + "=" + Math.random() * 99999999; 
     } 
     else 
     { 
      if(xContains(url, "?" + this.RND_PARAM_NAME)) 
      { 
       queryString = url.split("?" + this.RND_PARAM_NAME).slice(1,-1).join(""); 
      } 
      randomizedQueryString = queryString + "?" + this.RND_PARAM_NAME + "=" + Math.random() * 99999999; 
     } 
     var foundAt = -1; 
     if(!xIsEmpty(this._prefixCache)) 
     { 
      for(var i=0; i<this._prefixCache.length; ++i) 
      { 
       if(!xIsEmpty(this._prefixCache[i]) && foundAt < 0) 
       { 
        for(var h=0; h<this._prefixCache[i].length; ++h) 
        { 
         if(this._prefixCache[i][h] == cleanUrl + queryString) 
         { 
          cleanUrl = this._prefixCache[i][0]; 
          foundAt = i; 
          break; 
         } 
        } 
       } 
      } 
     } 

     var prefixHistory = [cleanUrl + queryString]; 
     var applyPrefix = true; 
     if(prefixHistory[0].match(new RegExp('^[A-Za-z0-9-_]+://'))) 
     { 
      applyPrefix = false; 
     } 
     var prefix = this._prefix; 
     if(!xIsEmpty(this._prefix) && this._prefix) 
     { 
      prefixHistory.push(this._prefix + cleanUrl + queryString); 
      if(foundAt >= 0) 
      { 
       this._prefixCache[foundAt] = prefixHistory; 
      } 
      else 
      { 
       this._prefixCache.push(prefixHistory); 
      } 
     } 
     else 
     { 
      prefix = ""; 
     } 
     if(!applyPrefix) 
     { 
      prefix = ""; 
     } 
     url = prefix + cleanUrl + randomizedQueryString; 

     return (getCleanUrl) ? (cleanUrl + queryString) : url; 
    } 
    hotswap.prototype.refreshAllJs = function(excludedFiles) 
    { 
     if(typeof excludedFiles == "undefined" || !excludedFiles) 
     { 
      excludedFiles = [] 
     } 
     excludedFiles.push("hotswap.js"); 

     this._recreate("js", excludedFiles, false, 0, true); 
    }; 
    hotswap.prototype.refreshJs = function(includedFiles) 
    { 
     this._recreate("js", includedFiles, true, 0, true); 
    }; 
    hotswap.prototype.refreshAllCss = function(excludedFiles) 
    { 
     this._recreate("css", excludedFiles, false, this.FILE_REMOVAL_DELAY); 
    }; 
    hotswap.prototype.refreshCss = function(includedFiles) 
    { 
     this._recreate("css", includedFiles, true, this.FILE_REMOVAL_DELAY); 
    }; 
    hotswap.prototype.refreshAllImg = function(excludedFiles) 
    { 
     this._reload("img", excludedFiles, false); 
    }; 
    hotswap.prototype.refreshImg = function(includedFiles) 
    { 
     this._reload("img", includedFiles, true); 
    }; 
    hotswap.prototype.setPrefix = function(prefix) 
    { 
     this._prefix = prefix; 
     var gui = xGetElementById(this.CSS_HTML_PREFIX + "_wrapper"); 
     if(gui) 
     { 
      if(!xIsEmpty(this._prefix) && this._prefix) 
      { 
       xGetElementById(this.CSS_HTML_PREFIX+"-prefix").value = this._prefix; 
      } 
      else 
      { 
       xGetElementById(this.CSS_HTML_PREFIX+"-prefix").value = ""; 
      } 
     } 
    } 
    hotswap.prototype.getPrefix = function() 
    { 
     return this._prefix; 
    } 
    hotswap.prototype.createGui = function(nDistanceFromTopInPercent) 
    { 
     if(xIsEmpty(nDistanceFromTopInPercent)) 
     { 
      nDistanceFromTopInPercent = 20; 
     } 
     var gui = xGetElementById(this.CSS_HTML_PREFIX + "_wrapper"); 
     if(gui) 
     { 
      xRemove(xGetElementById(this.CSS_HTML_PREFIX + "_wrapper")); 
     } 
     gui = xCreateElement("div"); 
     xSetAttribute(gui, "id", this.CSS_HTML_PREFIX + "_wrapper"); 
     var guiHtml = xReplace(this._guiHtml, "PREFIX", this.CSS_HTML_PREFIX); 
     guiHtml = xReplace(guiHtml, '20%;/*distance from top*/', nDistanceFromTopInPercent+'%;/*distance from top*/'); 
     gui.innerHTML = guiHtml; 
     xAppendChild(xGetElementsByTagName("body")[0], gui); 
     if(!xIsEmpty(this._guiCache)) 
     { 
      this._guiCache = {}; 
     } 
     this._guiCreateFilesList(); 
     if(!xIsEmpty(this._prefix) && this._prefix) 
     { 
      xGetElementById(this.CSS_HTML_PREFIX+"-prefix").value = this._prefix; 
     } 
     var self = this; 
     xAddEventListener(xGetElementById(this.CSS_HTML_PREFIX+"-toggle"), "click", function(evt) 
     { 
      var gui = xGetElementById(self.CSS_HTML_PREFIX); 
      if(xHasClass(gui, "mini")) 
      { 
       xRemoveClass(gui, "mini"); 
      } 
      else 
      { 
       xAddClass(gui, "mini"); 
      } 
     }); 
     xAddEventListener(xGetElementById(this.CSS_HTML_PREFIX+"-prefix"), "blur", function(evt) 
     { 
      self._guiPrefixChanged(evt.target); 
     }); 
     xAddEventListener(xGetElementById(this.CSS_HTML_PREFIX+"-submit-selected"), "click", function(evt) 
     { 
      self._guiRefreshSelected() 
     }); 
     xAddEventListener(xGetElementById(this.CSS_HTML_PREFIX+"-submit-start"), "click", function(evt) 
     { 
      if(xGetAttribute(evt.target, "class") != this.CSS_HTML_PREFIX+"-seconds") 
      { 
       var input, nSeconds = 1; 
       var children = evt.target.children; 
       for(var i=0; i<children.length; ++i) 
       { 
        if(xGetAttribute(children[i], "class") == this.CSS_HTML_PREFIX+"-seconds") 
        { 
         nSeconds = children[i].value; 
        } 
       } 

       self._guiRefreshSelected(); 
       self._guiRefreshStart(nSeconds); 
      } 
     }); 
     xAddEventListener(xGetElementById(this.CSS_HTML_PREFIX+"-submit-stop"), "click", function(evt) 
     { 
      self._guiRefreshStop(); 
     }); 
     xAddEventListener(xGetElementById(this.CSS_HTML_PREFIX+"-submit-refresh-list"), "click", xBind(self.guiRefreshFilesList,self)); 
    } 

    hotswap.prototype._guiCreateFilesList = function() 
    { 
     this._guiCache.files = []; 
     this._guiCache.activeFiles = { 
      "css" : [], 
      "js" : [], 
      "img" : [] 
     }; 

     var self = this; 
     var createFilesList = function(list, files) 
     { 
      var i, j, r, clone, template, file, fileName, nodesToRemove = []; 
      for(j=0; j<list.children.length; ++j) 
      { 
       if(xHasClass(list.children[j], "template")) 
       { 
        template = list.children[j]; 
       } 
       else 
       { 
        if(!xHasClass(list.children[j], self.CSS_HTML_PREFIX + "-headline")) 
        { 
         nodesToRemove.push(list.children[j]); 
        } 
       } 
      } 
      for(r=0; r<nodesToRemove.length; ++r) 
      { 
       xRemove(nodesToRemove[r]); 
      } 
      for(i=0; i<files.length; ++i) 
      { 
       file = files[i]; 
       clone = xCloneNode(template); 
       xRemoveClass(clone, "template"); 
       fileName = self._updatedUrl(xGetAttribute(file.node, file.srcAttributeName), true); 
       if(!xContains(self._guiCache.files,fileName)) 
       { 
        self._guiCache.files.push(fileName); 
        clone.innerHTML = fileName; 
        xAppendChild(list, clone); 
        xAddEventListener(clone, "click", (function(type, fileName){ 
         return function(evt){ 
          xStopPropagation(evt); 
          xPreventDefault(evt); 
          self._guiClickedFile(evt.target, type, fileName); 
         }; 
        })(file.type, fileName) 
        ); 
       } 
      } 
     } 

     createFilesList(xGetElementById(this.CSS_HTML_PREFIX+"-css"), this._getFilesByType("css")); 
     createFilesList(xGetElementById(this.CSS_HTML_PREFIX+"-js"), this._getFilesByType("js", ["hotswap.js"])); 
     createFilesList(xGetElementById(this.CSS_HTML_PREFIX+"-img"), this._getFilesByType("img")); 
    } 
    hotswap.prototype.deleteGui = function() 
    { 
     var gui = xGetElementById(this.CSS_HTML_PREFIX + "_wrapper"); 
     if(gui) 
     { 
      xRemove(xGetElementById(this.CSS_HTML_PREFIX + "_wrapper")); 
     } 
    } 
    hotswap.prototype._guiPrefixChanged = function(ele) 
    { 
     if(ele) 
     { 
      this.setPrefix(ele.value); 
     } 
    }, 

    hotswap.prototype._guiClickedFile = function(ele, sType, sFileName) 
    { 
     var activeFiles = this._guiCache.activeFiles[sType]; 
     if(xContains(activeFiles, sFileName)) 
     { 
      xRemoveClass(ele, "active"); 
      activeFiles.splice(activeFiles.indexOf(sFileName), 1) 
     } 
     else 
     { 
      xAddClass(ele, "active"); 
      activeFiles.push(sFileName); 
     } 
    }, 

    hotswap.prototype._guiRefreshSelected = function() 
    { 
     var activeFiles = this._guiCache.activeFiles; 
     if(activeFiles['css'].length > 0) 
     { 
      this.refreshCss(activeFiles['css']); 
     } 
     if(activeFiles['js'].length > 0) 
     { 
      this.refreshJs(activeFiles['js']); 
     } 
     if(activeFiles['img'].length > 0) 
     { 
      this.refreshImg(activeFiles['img']); 
     } 
    }, 

    hotswap.prototype._guiRefreshStart = function(nSeconds) 
    { 
     if(this._guiGuiRefreshInterval !== null) 
     { 
      this._guiRefreshStop(); 
     } 
     var self = this; 
     this._guiGuiRefreshInterval = setInterval(xBind(this._guiRefreshSelected, this), nSeconds * 1000); 
     xAddClass(xGetElementById(this.CSS_HTML_PREFIX+"-submit-start"), "inactive"); 
     xRemoveClass(xGetElementById(this.CSS_HTML_PREFIX+"-submit-stop"), "inactive"); 
    }, 

    hotswap.prototype._guiRefreshStop = function() 
    { 
     if(this._guiGuiRefreshInterval !== null) 
     { 
      clearInterval(this._guiGuiRefreshInterval); 
     } 
     this._guiGuiRefreshInterval = null; 
     xRemoveClass(xGetElementById(this.CSS_HTML_PREFIX+"-submit-start"), "inactive"); 
     xAddClass(xGetElementById(this.CSS_HTML_PREFIX+"-submit-stop"), "inactive"); 
    } 

    hotswap.prototype.guiRefreshFilesList = function() 
    { 
     this._guiCreateFilesList(); 
    } 

}).call(this); 
+0

Désolé, ce n'était pas mon intention. J'ai mis à jour la réponse pour contenir le code source complet et quelques exemples. – geoathome

+0

merci ...... :-) – kleopatra

1

Vous pouvez facilement chaud recharger le code JavaScript avec le RequireJS système de module frontal, j'ai écrit un article à ce sujet récemment (Septembre 2015)

https://medium.com/@the1mills/hot-reloading-with-react-requirejs-7b2aa6cb06e1

vous supprimez essentiellement le cache un module AMD et RequireJS iront chercher le nouveau à partir du système de fichiers. L'astuce consiste à utiliser websockets (socket.io fonctionne bien) pour indiquer au navigateur que le fichier a été modifié, et pour supprimer le cache et requérir de nouveau le fichier.

le reste de l'info est dans l'article

Questions connexes