我要對答案的工作在一個時間步和大家分享一下,我去。
第一個簡單的步驟是一些非常小的重新格式化,只是爲了縮短行長度並使其更容易看到代碼。在實踐中,我可能就不會擔心該導線長度在這一點上,但更短的行會顯示更好地在這裏:
axis = [ "X","Y","Z" ];
document.write(
"@keyframes tumble { "+
"12% {transform:rotate" +
axis[Math.floor(Math.random()*3)] +
"(-" + Math.floor(Math.random()*180) + "deg) rotate" +
axis[Math.floor(Math.random()*3)] +
"(" + Math.floor(Math.random()*180) + "deg) rotate" +
axis[Math.floor(Math.random()*3)] +
"(" + Math.floor(Math.random()*180) + "deg)}" +
"32% {transform:rotate" +
axis[Math.floor(Math.random()*3)] +
"(-" + Math.floor(Math.random()*180) + "deg) rotate" +
axis[Math.floor(Math.random()*3)] +
"(" + Math.floor(Math.random()*180) + "deg) rotate" +
axis[Math.floor(Math.random()*3)] +
"(" + Math.floor(Math.random()*180) + "deg)}" +
"50% {transform:rotate" +
axis[Math.floor(Math.random()*3)] +
"(" + Math.floor(Math.random()*180) + "deg) rotate" +
axis[Math.floor(Math.random()*3)] +
"(" + Math.floor(Math.random()*180) + "deg) rotate" +
axis[Math.floor(Math.random()*3)] +
"(" + Math.floor(Math.random()*180) + "deg)}" +
"66% {transform:rotate" +
axis[Math.floor(Math.random()*3)] +
"(" + Math.floor(Math.random()*180) + "deg) rotate" +
axis[Math.floor(Math.random()*3)] +
"(" + Math.floor(Math.random()*180) + "deg) rotate" +
axis[Math.floor(Math.random()*3)] +
"(" + Math.floor(Math.random()*180) + "deg)}" +
"84% {transform:rotate" +
axis[Math.floor(Math.random()*3)] +
"(" + Math.floor(Math.random()*180) + "deg) rotate" +
axis[Math.floor(Math.random()*3)] +
"(" + Math.floor(Math.random()*180) + "deg) rotate" +
axis[Math.floor(Math.random()*3)] +
"(" + Math.floor(Math.random()*180) + "deg)}" +
"}</style>"
);
兩個項目跳出馬上:它看起來像有一個遺漏<style>
標籤在生成的代碼開始(最後有一個</style>
)。axis = ...
聲明中缺少var
。
這是顯而易見的,接下來的事情就是發生了一遍又一遍在代碼中這兩種模式:
Math.floor(Math.random()*3)
Math.floor(Math.random()*180)
讓我們寫一些功能,使那些簡單,做一個簡單的搜索和替換,以改變現有的代碼使用這些功能:
// Return a random integer n in the range 0 <= n < limit
function randInt(limit) {
return Math.floor(Math.random() * limit);
}
// Return a random integer n in the range 0 <= n < 3
function rand3() {
return randInt(3);
}
// Return a random integer n in the range 0 <= n < 180
function rand180() {
return randInt(180);
}
var axis = [ "X","Y","Z" ];
// Write a <style> tag to the document with a random animation
document.write(
"<style>@keyframes tumble { "+
"12% {transform:rotate" +
axis[rand3()] +
"(-" + rand180() + "deg) rotate" +
axis[rand3()] +
"(" + rand180() + "deg) rotate" +
axis[rand3()] +
"(" + rand180() + "deg)}" +
"32% {transform:rotate" +
axis[rand3()] +
"(-" + rand180() + "deg) rotate" +
axis[rand3()] +
"(" + rand180() + "deg) rotate" +
axis[rand3()] +
"(" + rand180() + "deg)}" +
"50% {transform:rotate" +
axis[rand3()] +
"(" + rand180() + "deg) rotate" +
axis[rand3()] +
"(" + rand180() + "deg) rotate" +
axis[rand3()] +
"(" + rand180() + "deg)}" +
"66% {transform:rotate" +
axis[rand3()] +
"(" + rand180() + "deg) rotate" +
axis[rand3()] +
"(" + rand180() + "deg) rotate" +
axis[rand3()] +
"(" + rand180() + "deg)}" +
"84% {transform:rotate" +
axis[rand3()] +
"(" + rand180() + "deg) rotate" +
axis[rand3()] +
"(" + rand180() + "deg) rotate" +
axis[rand3()] +
"(" + rand180() + "deg)}" +
"}</style>"
);
正如你看到的,代碼已經多簡單。
現在讓我們來看看這五個相似的代碼塊之間有什麼相同以及不同之處。將這些塊加載到可逐字符(intraline)差異的程序中很有用。我爲此使用Araxis Merge。 Beyond Compare是另一個不錯的選擇。這些都是商業產品;毫無疑問,這也是很好的免費選擇。
這裏是Araxis合併顯示,當我們第一塊與上次比較:
(如果你不喜歡的字體,不怪Araxis,這只是我的個人設置。並與自動換行寬度較窄只是爲了使其適合在列這裏)
我們可以看到,只有兩個區別:第一行的百分比數,以及"(-"
與"("
第三線。的確,這些是所有區塊中唯一的兩個區別。
所以,我們現在可以做的是編寫一個函數,返回這段代碼,讓我們插入這兩個值。
// Return a transform:rotate string with the specified
// percent and flag
function makeTransform(percent, flag) {
return (
percent + "% {transform:rotate" +
axis[rand3()] +
"(" + flag + rand180() + "deg) rotate" +
axis[rand3()] +
"(" + rand180() + "deg) rotate" +
axis[rand3()] +
"(" + rand180() + "deg)}"
);
}
現在看看這個函數,還有中的重複那幾個東西。但是這一點非常簡單,重複是相當小的。由於我們在這,但是,讓我們看看我們如何重構代碼多一點:
// Return a random axis and degree string
function randAxisDegree(flag) {
return axis[rand3()] + "(" + flag + rand180() + "deg)";
}
// Return a transform:rotate string with the specified
// percent and flag
function makeTransform(percent, flag) {
return (
percent + "% {transform:rotate" +
randAxisDegree(flag) + " rotate" +
randAxisDegree("") + " rotate" +
randAxisDegree("") +
"}"
);
}
當然,現在我們可能會注意到,rand3()
和rand180()
功能我早些時候是不是真的有必要,因爲他們現在每個人只使用一個地方,根本就不需要單獨的功能。
其實,回看代碼,這兩個功能都沒有,即使他們是稱爲多處真正有用的:rand3()
幾乎比randInt(3)
更好,或保持相同的簡潔,甚至重命名功能rand()
所以我們可以說rand(3)
而不是rand3()
。
我很想試着編輯這個答案,從一開始就採取這種方法,但讓我們單獨留下來,以顯示重構可能帶來的有點歪曲的路徑。現在,我們將雖然刪除它們,並直接從randAxisDegree()
調用randInt()
:
// Return a random axis and degree string
function randAxisDegree(flag) {
return axis[randInt(3)] + "(" + flag + randInt(180) + "deg)";
}
現在我們可以看到這一切是如何結合在一起的:
// Return a random integer n in the range 0 <= n < limit
function randInt(limit) {
return Math.floor(Math.random() * limit);
}
var axis = [ "X", "Y", "Z" ];
// Return a random axis and degree string
function randAxisDegree(flag) {
return axis[randInt(3)] + "(" + flag + randInt(180) + "deg)";
}
// Return a transform:rotate string with the specified
// percent and flag
function makeTransform(percent, flag) {
return (
percent + "% {transform:rotate" +
randAxisDegree(flag) + " rotate" +
randAxisDegree("") + " rotate" +
randAxisDegree("") +
"}"
);
}
// Write a <style> tag to the document with a random animation
document.write(
"<style>@keyframes tumble { " +
makeTransform(12, "-") +
makeTransform(32, "-") +
makeTransform(50, " ") +
makeTransform(66, " ") +
makeTransform(84, " ") +
"}</style>"
);
對於這樣的問題,也許你最好關閉,以更好地http://codereview.stackexchange.com/ – Nobita 2013-03-11 00:47:11