2012-08-23 4 views
0

Je suis actuellement en train d'apprendre les espaces de noms javascript comme je construis un site web et j'ai les exigences suivantes: je veux rendre tout mon code privé afin que d'autres scripts publics sur la page (éventuellement publicités , je ne suis pas trop sûr à ce stade) ne peut pas remplacer ou modifier mon javascript. le problème que je prévois est que les scripts publics peuvent utiliser window.onload et je ne veux pas qu'ils remplacent ma version privée de window.onload. Je veux toujours les laisser courir window.onload cependant.javascript combinant public et privé window.onload

jusqu'à présent i ont la disposition suivante:

//public code not written by me - i'm thinking this will be executed first 
window.onload = function() { 
    document.getElementById('pub').onclick = function() { 
     alert('ran a public event'); 
    }; 
}; 

//private code written by me 
(function() { 
    var public_onload = window.onload; //save the public for later use 
    window.onload = function() { 
     document.getElementById('priv').onclick = function() { 
      a = a + 1 
      alert('ran a private event. a is ' + a); 
     }; 
    }; 
    if(public_onload) public_onload(); 
    var a = 1; 
})(); 

j'ai pas mal de questions au sujet de cette ...

tout d'abord, est-ce une bonne structure pour écrire mon code javascript, ou est-il un meilleur? (Je prévois de mettre tout mon code dans la fonction anonyme). mon code privé est-il vraiment privé, ou y a-t-il un moyen pour que le javascript public puisse y accéder? Je suppose que la réponse à cette question est "oui - en utilisant des techniques d'évaluation délicate, n'insérez pas de code que vous ne faites pas confiance", mais j'aimerais savoir comment cela serait fait si c'est le cas.

Ensuite, lorsque je clique sur le lien public, l'événement n'est pas déclenché. Pourquoi est-ce?

Enfin, si je commente la ligne if(public_onload) public_onload(); puis a est renvoyé correctement lorsque je clique sur le bouton privé. mais si je laisse cette ligne alors la valeur de a est nan. Pourquoi est-ce?

Répondre

1

Vous pouvez joindre des écouteurs d'événements pour éviter leur primordial d'une certaine façon comme ceci:

<ol id="res"></ol> 

<script type="text/javascript"> 
    var res = document.getElementById('res'); 

    function log(line) { 
     var li = document.createElement('li'); 
     li.innerHTML = line; 
     res.appendChild(li); 
    } 

    // global code: 
    window.onload = function() { 
     log('inside the global window.onload handler'); 
    }; 

    // private code: 
    (function(window) { 
     function addEvent(el, ev, fn) { 
      if (el.addEventListener) { 
       el.addEventListener(ev, fn, false); 
      } else if (el.attachEvent) { 
       el.attachEvent('on' + ev, fn); 
      } else { 
       el['on' + ev] = fn; 
      } 
     } 
     addEvent(window, 'load', function() { 
      log('inside the second window.onload handler in "private section"'); 
     }); 
    })(window); 
</script>​ 

DEMO

L'exemple de l'organisation du code vous a demandé:

HTML:

<ol id="res"></ol>​

JavaScript:

/* app.js */ 

// in global scope:  
var MyApp = (function(app) { 
    var res = document.getElementById('res'); 

    app.log = function(line) { 
     var li = document.createElement('li'); 
     li.innerHTML = line; 
     res.appendChild(li); 
    }; 

    app.doWork = function() { 
     app.log('doing a work'); 
    }; 

    return app; 
})(MyApp || {}); 

/* my-app-module.js */ 

// again in global scope: 
var MyApp = (function(app) { 

    app.myModule = app.myModule || {}; 

    app.myModule.doWork = function() { 
     app.log('my module is doing a work'); 
    }; 

    return app; 
})(MyApp || {}); 

/* somewhere after previous definitions: */ 

(function() { 
    MyApp.doWork(); 
    MyApp.myModule.doWork(); 
})(); 

DEMO

MyApp is accessible from outside
Nothing is accessible from outside

+0

merci pour l'homme de réponses. Je n'ai pas pensé à passer l'objet 'window' au private 'module' dans votre premier exemple. Je suppose que je pensais que 'window' serait global dans le module privé ... Dans votre deuxième exemple d'organisation de code, j'espérais garder mon module complètement inaccessible à l'autre code public - c'est-à-dire illisible ou inscriptible. cela signifierait-il simplement changer '(MyApp || {})' en '()'? – mulllhausen

+0

Si vous le modifiez, vous ne pourrez pas étendre votre espace de nom initial dans d'autres fichiers. Ici, dans mon exemple, la variable 'MyApp' est partagée entre les modules et fournit une interface publique à votre application. –

+0

ah je vois. Je prévois de tout mettre dans un "module" pour l'ensemble du projet - dans l'espoir de le garder inaccessible.si j'expose l'objet 'MYApp' comme ça, les autres scripts ne pourraient-ils pas écrire dans' MyApp' et m'empêcheraient de créer une méthode (si mon code s'exécute en second) ou écraseraient certaines de mes méthodes (si mon code s'exécute en premier)? – mulllhausen