2010-10-27 3 views
0

J'ai un UL sur une page et sur le clic d'un bouton j'ajoute un li et l'évanouit dedans. Cela fonctionne très bien pour les clics simples. Cependant, lorsque le bouton est cliqué deux fois, la première animation s'arrête immédiatement et la seconde s'achève.Javascript - l'animation s'arrête quand une nouvelle est commencée

J'ai installé une page de test pour démontrer: http://anttears.co.uk/test (la page de test a été testé en FF seulement)

Mettre un console.log dans la fonction setOpacity pour la valeur de élém semble montrer le javascript travail comme prévu - les deux l'opacité de li = 1. Cependant, le premier li semble être un fragment dissasoiated avec le DOM réel.

J'essaie délibérément de faire fonctionner cela sans les bibliothèques habituelles, comme une expérience d'apprentissage.

Toute aide appréciée greatfully ... Ant

Répondre

1
this.prepend = function(string, elem) { 
    var content = elem.innerHTML; 
    content = string + content; 
    elem.innerHTML = content; 
} 

jamais ce faire.

Vous prenez le contenu DOM du elem (le growlList), le sérialisant en une nouvelle chaîne HTML, en ajoutant un peu de contenu HTML et en analysant le code HTML joint dans de nouveaux nœuds DOM. Cela entraîne la perte de tout contenu non sérialisable au format HTML, tel que les valeurs de champs de formulaire, les gestionnaires d'événements et les références JavaScript. L'animation a toujours une référence à l'ancien noeud HTMLElement, qui n'est plus dans le DOM, ayant été remplacé par des éléments nouvellement analysés à partir de content.

En effet, vous voulez généralement pour éviter de générer des chaînes HTML du tout:

growl = '<li id="' + gid + '" class="' + className + ' growl" style="display: none"><span class="close" title="close">x</span><h2>' + heading + '</h2><div class="growlContent">' + content + '</div></li>', 

Tous unescaped caractères HTML spéciaux d'ce contenu et vous avez cassé votre balisage au mieux. Au pire, les données proviennent d'un utilisateur malveillant et vous vous êtes donné un trou de sécurité XSS.

Au lieu de cela, utiliser des méthodes de style DOM, par exemple:

var span= document.createElement('span'); 
span.className=span.title= 'close'; 
span.appendChild(document.createTextNode('x')); 
var h2= document.createElement('h2'); 
h2.appendChild(document.createTextNode(heading)); 
var div= document.createElement('div'); 
div.className= 'growlContent'; 
div.appendChild(document.createTextNode(content)) 

var li= document.createElement('li'); 
li.id= gid; 
li.className= className; 
li.appendChild(span); 
li.appendChild(h2); 
li.appendChild(div); 

gl.insertBefore(li, gl.firstChild); 

Ceci est assez verbeux, mais il est facile d'écrire une fonction d'aide pour réduire la saisie, par exemple:

gl.insertBefore(el('li', {id: gid, className: className), [ 
    el('span', {className: 'close', title: 'close'}, 'x'), 
    el('h2', {}, heading), 
    el('div', {className: 'growlContent'}, content) 
]), gl.firstChild); 


// Element creation convenience function 
// 
function el(tag, attrs, content) { 
    var el= document.createElement(tag); 
    if (attrs!==undefined) 
     for (var k in attrs) 
      if (attrs.hasOwnProperty(k)) 
       el[k]= attrs[k]; 
    if (content!==undefined) { 
     if (typeof(content)==='string') 
      el.appendChild(document.createTextNode(content)); 
     else 
      for (var i= 0; i<content.length; i++) 
       el.appendChild(content[i]); 
    } 
    return el; 
}; 
+0

Salut Bobince , merci pour la réponse, mais je pense que vous avez manqué un peu le point - je n'utilise pas jQuery ou toute autre bibliothèque délibérément. En ce qui concerne les variables globales, j'utilise des virgules pour séparer les déclarations, de sorte qu'elles seront dans la portée. Et la page est juste une page de test pour démontrer le problème, pas la méthodologie finale, aussi, les valeurs ne sont jamais stockées dans un db ou réellement affiché, donc même si c'était le code final la seule personne vulnérable serait l'utilisateur courant d'une attaque suicide xss :). Des idées sur le problème réel et comment le résoudre d'une manière non jquery? – Ant

+0

Oups! Désolé, j'ai vu "animer" et "préfixer" et mon esprit passe instantanément en mode jQuery. Et je ne suis même pas * comme * jQuery! C'est la malédiction de cet endroit obsédé! Mis à jour pour inclure les versions de plain-JS. – bobince

+0

Je vois ce que vous faites maintenant avec les virgules, mais je ne le recommanderais pas: il est si facile d'éditer/réorganiser rapidement les lignes et de perdre le 'var'. Par exemple dans la page elle-même 'header' et' content' sont des globals accidentels, et comme il y a aussi des éléments avec les mêmes noms que 'id's, essayer de les assigner provoquera une exception dans IE (qui fait' id 'D éléments visibles en tant que globaux). Si vous utilisez var-comma-over-more-one-line, la pratique normale consiste à indenter les lignes suivantes pour montrer qu'elles font partie de la même instruction; Personnellement, je préfère FWIW 'var' s séparés. – bobince

Questions connexes