2010-10-27 86 views
0

我在頁面上點擊一個按鈕,並在一個按鈕上點擊我添加一個動畫並將其淡入。這適用於單擊。但是,當點擊兩次按鈕時,第一個動畫立即停止,第二個動畫完成。Javascript - 動畫停止,因爲新動畫開始

我已經建立了測試頁,以證明這一點:http://anttears.co.uk/test(測試頁面已經FF只測試)

在elem的價值setOpacity功能把一個的console.log似乎表明javascript的工作如預期的那樣 - 這兩個李達到不透明度= 1。但是,第一個li似乎是一個與實際DOM分散的片段。

我故意試圖在沒有平常的圖書館的情況下讓這項工作成爲一種學習體驗。

任何幫助greatfully讚賞... 螞蟻

回答

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

永遠不要這樣做。

您正在將elem(growlList)的DOM內容序列化爲新的HTML字符串,預先添加一些HTML內容,並將連接的HTML解析爲全新的DOM節點。這會丟失所有非HTML序列化內容,例如表單字段值,事件處理程序和JavaScript引用。該動畫仍舊引用舊的HTMLElement節點,該節點不再位於DOM中,而是由新解析的元素替換。

事實上,你平時要避免生成HTML字符串都:

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>', 

該內容的任何轉義HTML的特殊字符,你充其量打破您的標記。最糟糕的是,這些數據來自惡意用戶,您已經給自己一個XSS安全漏洞。

相反,使用DOM風格的方法,例如:

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); 

這是很羅嗦,但它很容易寫一個輔助函數來減少輸入,如:

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

Bobince喜,謝謝你的回答,但我認爲你已經錯過了一點 - 我沒有故意使用jQuery或任何其他庫。至於全局變量,我使用逗號分隔聲明,所以它們將在範圍內。而頁面只是一個測試頁面來演示問題,而不是最終的方法,而且值也不會存儲在數據庫中或實際發佈,因此即使它是最終代碼,唯一容易受到攻擊的人也會是當前用戶自殺xss攻擊:)。關於實際問題的任何想法,以及如何解決它在非jquery時尚? – Ant 2010-10-27 14:15:48

+0

糟糕!對不起,我看到「animate」和「prepend」,我的思緒立即切換到jQuery模式。而我甚至不喜歡* jQuery!這是這個迷戀的地方的詛咒!已更新爲包含純JS版本。 – bobince 2010-10-27 14:34:06

+0

我明白你現在在用逗號做什麼,但我不會推薦它:它很容易快速編輯/重新排列行並丟失'var'。例如,在頁面本身中,「header」和「content」是偶然的全局變量,並且由於也有與id相同名稱的元素,試圖分配給它們會在IE中導致異常(這使得id 'd元素可見爲全局變量)。如果使用var-comma-over-more-one-line,通常的做法是縮進後續行以顯示它們是同一語句的一部分;我個人更喜歡單獨的'var's FWIW。 – bobince 2010-10-27 14:37:22