2010-04-01 5 views
0

Je veux donner un bloc javascript statique de code à un concepteur de modèle html, qui peut être:ordre d'exécution Javascript

  • soit en ligne ou externe, ou les deux
  • utilisé une ou plusieurs fois dans le modèle html

et chaque bloc peut déterminer sa position dans le modèle par rapport aux autres blocs de code javascript.

Un exemple pourrait être des bannières d'image servies en utilisant javascript. Je donne du code au concepteur de gabarits qui le place à deux endroits, une fois pour une bannière horizontale dans l'en-tête et une fois pour une bannière verticale. Le même code s'exécute dans les deux blocs mais sachant que leurs positions peuvent déterminer si servir une bannière d'image horizontale ou verticale.

Avez-vous du sens?

Autre exemple: Supposons que vous ayez les deux balises javascript identiques dans une page Web appelant un script externe sur un serveur. Le serveur et/ou les scripts peuvent-ils déterminer à quelle balise javascript il appartient?

NOTE: Peut-on dire que c'est un défi? Je sais que je peux très facilement éviter ce casse-tête mais je le rencontre régulièrement.

+3

Non, cela n'a pas de sens. Huh? – SLaks

+0

Quelle est votre question? –

+0

Ajout d'un autre exemple. @Aaron Pouvez-vous me donner le bloc de code s'il vous plaît? :) – zaf

Répondre

1

Merci pour tout le monde de conseils, mais je serai répondre à ma propre question.

J'ai trouvé plusieurs façons d'accomplir la tâche et je vous donne celle qui fonctionne bien et est facile à comprendre.

Le fragment de code suivant repose sur la sortie de divs factices et de jQuery.

<script> 
    // Unique identifier for all dummy divs 
    var rnd1="_0xDEFEC8ED_"; 
    // Unique identifier for this dummy div 
    var rnd2=Math.floor(Math.random()*999999); 
    // The dummy div 
    var d="<div class='"+rnd1+" "+rnd2+"'></div>"; 
    // Script which : 
    // Calculates index of THIS dummy div 
    // Total dummy divs 
    // Outputs to dummy div for debugging 
    var f1="<script>$(document).ready(function(){"; 
    var f2="var i=$('."+rnd1+"').index($('."+rnd2+"'))+1;"; 
    var f3="var t=$('."+rnd1+"').length;"; 
    var f4="$('."+rnd2+"').html(i+'/'+t);"; 
    var f5="});<\/script>"; 
    document.write(d+f1+f2+f3+f4+f5); 
</script> 
0

Pourquoi ne pas simplement placer l'appel de fonction sur la page au lieu du bloc de code entier? De cette façon, vous pouvez passer un paramètre pour lui dire quel type de publicité est nécessaire?

BuildAd('Tower'); 

BuildAd('Banner'); 

Javascript n'a pas la moindre idée de sa position dans une page. Vous devez cibler un contrôle sur la page pour obtenir son emplacement.

+0

J'ai besoin d'être statique. – zaf

+0

@zaf: Que voulez-vous dire par "statique"? –

+0

@ T.J. Crowder La fonction BuildAd (...) n'est pas "statique" car le paramètre change en fonction du placement. – zaf

0

Je ne pense pas qu'il soit possible que le code JavaScript sache d'où il a été chargé. Il ne fonctionne certainement pas au point où il est trouvé, puisque l'exécution n'est pas directement liée au processus de chargement (le code exécute généralement après le DOM entier est chargé). En fait, dans le cas d'externals, cela n'a même pas de sens, puisqu'une seule copie du code sera chargée quel que soit le nombre de fois qu'il est rencontré.

+0

Ce n'est pas complètement vrai; JavaScript en ligne s'exécute au moment où le navigateur a analysé la balise de fin; C'est pourquoi vous devez être prudent lorsque vous accédez au DOM en eux et pourquoi vous avez besoin de body.onload. –

+0

* "Le code s'exécute généralement après que le DOM entier soit chargé" * Cela n'est pas correct, sauf si vous spécifiez l'attribut 'defer' ou' async'. Si vous ne le faites pas, l'analyseur HTML doit s'arrêter et demander à l'interpréteur JavaScript d'exécuter le code pour le bloc de script dès qu'il le trouve, car le bloc de script peut émettre du code HTML (via 'document.write'). C'est pourquoi les balises de script peuvent retarder le rendu d'une page. IE a introduit l'attribut 'defer', et à la fois' defer' et 'async' ont été ajoutés au HTML5. Les deux (de différentes manières) permettent au parseur/rendu HTML de continuer sans attendre l'exécution du code. –

0

Il ne devrait pas être le même code pour chaque bannière - il y aura un paramètre passé à tout ce qui sert la bannière d'image qui spécifiera la taille prévue. Pouvez-vous donner un exemple précis de ce dont vous avez besoin pour cela?

Pour éditer votre exemple récent: La réponse simple est non. Je pourrais vous aider à aborder le problème d'une direction différente si vous postez les détails de votre problème

3

Le code JavaScript peut localiser tous les éléments <script> sur la page et il peut probablement examiner les attributs et le contenu pour vérifier de quel élément il provient . Mais ce n'est probablement pas ce que vous voulez.

Ce que vous voulez est un morceau de JavaScript qui remplace les balises sur la page avec des bannières publicitaires. La solution habituelle consiste à ajouter un élément spécial, par exemple un IMG, et donner IMG un id ou un class ou peut-être même un attribut personnalisé (comme adtype="vertical"), puis utiliser JavaScript pour localiser ces éléments et remplacer le contenu en changeant le Attribut src.

Par exemple, en utilisant jQuery, vous pouvez devriez vos images comme ceci:

<img src="empty.gif" width="..." height="..." class="ad" adtype="..." /> 

Ensuite, vous pouvez localiser chaque image avec

$('img.ad') 

[EDIT] Eh bien, le serveur connaît évidemment quel script appartient à quelle balise de script, car elle insère le script. Donc, c'est une évidence.

Si le script veut savoir où il est dans le DOM, ajouter quelque chose qu'il peut utiliser pour s'identifier, dire:

<script>var id= '329573485745'; 

Ensuite, vous pouvez marcher tous les script balises et vérifier que l'on contient la valeur de la variable id.

Si vous appelez un script externe, alors vous pouvez faire la même chose, mais vous devez ajouter l'ID à la balise de script que vous émettez le code HTML:

<script id="329573485745" src="..." /> 

Ensuite, le script externe peut examiner les DOM et recherche l'élément avec cet identifiant. Vous voudrez utiliser un UUID pour cela, btw. De cette façon, un morceau de JS peut localiser le marqueur de script qui s'est ajouté à la page.

+0

+1 pour reconstituer ce que ce mec essayait de faire !! LOL – used2could

+0

Se réchauffer. La localisation des balises de script donne plus d'indices. En ce qui concerne l'utilisation d'attributs ou d'éléments spéciaux - non, je ne veux pas charger le mauvais concepteur de modèles. – zaf

+1

Bien @zaf Je vous suggère de regarder autour du web. Ce qu'Aaron décrit est en fait ce que tout le monde fait réellement. – Pointy

0

Le terme «bloc de code statique» laisse beaucoup de place à l'interprétation.

Les scripts en ligne (par exemple ceux qui s'appuient sur document.write et doivent donc être analysés et exécutés pendant la phase d'analyse HTML) ne peuvent pas indiquer où ils se trouvent dans le DOM au moment de l'exécution. Vous devez leur dire (comme dans l'une des premières réponses que vous avez).

Je pense que vous trouverez probablement que vous avez besoin de changer votre approche.

Une façon courante de conserver le code et le balisage différent (ce qui est utile pour fournir des outils pour les concepteurs HTML qui ne sont pas des codeurs) est de les utiliser une balise de script comme ceci:

<script defer async type='text/javascript' src='pagestuff.js'></script> 

... qui se déclenche ensuite lorsque la page est chargée (en utilisant window.onload si nécessaire, mais il existe plusieurs techniques pour être déclenchées plus tôt que cela, ce que vous voulez car window.onload ne se déclenche pas tant que les images ne sont pas toutes chargées). Ce script recherche ensuite les marqueurs dans le balisage et manipule la page en conséquence. Par exemple (cet exemple utilise Prototype, mais vous pouvez faire la même chose avec JavaScript brut, jQuery, fermeture, etc.):

document.observe("dom:loaded", initPage); 
function initPage() { 
    var verticals = $$('div.vertical'); 
    /* ...do something with the array of "vertical" divs in `verticals`, 
     such as: */ 
    var index; 
    for (index = 0; index < verticals.length; ++index) { 
     vertical.update("I'm vertical #" + index); 
    } 
} 

Les concepteurs peuvent alors avoir des blocs sur la page qui sont remplis par le code qu'ils signaler d'une manière normale pour eux (classes ou attributs, etc.). Le code détermine ce qu'il doit faire en fonction des classes/attributs des blocs qu'il trouve lorsqu'il s'exécute.

1

La meilleure chose serait probablement de faire une insertion une fois la fonction, puis de lui faire insérer seulement l'appel de fonction si nécessaire.

Comme ceci:

timescalled=0 
function buildad(){ 
    var toinsert="" //Code to generate the desired piece of HTML 
    document.write(toinsert) 
    timescalled+=1 //So you can tell how many times the function have been called 
} 

maintenant un bloc de script appelant la fonction peut être simplement inséré chaque fois qu'une bannière est nécessaire

<script type="text/javascript">buildad()</script> 
+0

Y at-il une garantie que les balises de script sont exécutées les unes après les autres? Si non, votre fonction n'aidera pas. – zaf

+0

@zaf: Oui, les balises de script sont exécutées dans l'ordre strict des documents sauf si elles ont l'attribut 'defer' ou' async'. Chaque balise de script maintient l'analyse HTML et passe à l'interpréteur JavaScript, puis lorsque l'interpréteur JavaScript est terminé avec le bloc, l'analyseur HTML continue. C'est pourquoi 'document.write' fonctionne, mais pas seulement pour les blocs contenant' document.write'. –

+0

@eBusiness: +1 pour se rapprocher de ce qu'il veut vraiment faire. Hors sujet: Bien que JavaScript ait cette notion d '"insertion de point-virgule", c'est * une très mauvaise idée * de l'utiliser réellement.Incluez toujours les points-virgules, notamment parce qu'ils clarifient votre intention (envers les autres personnes et l'interprète) et qu'ils permettent d'utiliser des mini-compresseurs/compresseurs/packers qui ne fonctionnent pas avec du code reposant sur l'insertion de points-virgules. –