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;
};
Bobince喜,謝謝你的回答,但我認爲你已經錯過了一點 - 我沒有故意使用jQuery或任何其他庫。至於全局變量,我使用逗號分隔聲明,所以它們將在範圍內。而頁面只是一個測試頁面來演示問題,而不是最終的方法,而且值也不會存儲在數據庫中或實際發佈,因此即使它是最終代碼,唯一容易受到攻擊的人也會是當前用戶自殺xss攻擊:)。關於實際問題的任何想法,以及如何解決它在非jquery時尚? – Ant 2010-10-27 14:15:48
糟糕!對不起,我看到「animate」和「prepend」,我的思緒立即切換到jQuery模式。而我甚至不喜歡* jQuery!這是這個迷戀的地方的詛咒!已更新爲包含純JS版本。 – bobince 2010-10-27 14:34:06
我明白你現在在用逗號做什麼,但我不會推薦它:它很容易快速編輯/重新排列行並丟失'var'。例如,在頁面本身中,「header」和「content」是偶然的全局變量,並且由於也有與id相同名稱的元素,試圖分配給它們會在IE中導致異常(這使得id 'd元素可見爲全局變量)。如果使用var-comma-over-more-one-line,通常的做法是縮進後續行以顯示它們是同一語句的一部分;我個人更喜歡單獨的'var's FWIW。 – bobince 2010-10-27 14:37:22