2017-07-05 11 views
0

私の意図は非常に簡単です:私は新しいspanを作成し、main要素の最初の子の前にそれを挿入(またはmainが空の場合、それを追加します)newSpan()機能を持っており、 letterTyper()関数を使用して、挿入された要素をCONTENT定数に格納された文字列で塗りつぶし、逆方向の種類の効果を生成します。その考え方は、新しい要素を作成してから、その中のある特定の回数だけループを使ってwindow.onloadというエフェクトをトリガーすることです。が作成され、挿入されたDOM要素に関数を実行

しかし、私は、私はDOM内で終わる何

window.onload = function() { 
    newSpan(); 
    letterTyper(); 
    newSpan(); 
    letterTyper(); 
} 

window.onload匿名関数を満たしたときに、私はまた、効果なしに、DOMContentLoadedイベントを使用しようとした

<main> 
    <span id="#span1">lorem ipsum</span> 
    <span id="#span0"></span> 
</main> 

です。何故ですか?私は間違って何をしていますか?

マイコード:

const CONTENT = 'lorem ipsum'; 
var main = document.querySelector('main'); 
var spanId = 0; 
var charCount = CONTENT.length; 


window.onload = function() { 
    newSpan(); 
    letterTyper(); 
    newSpan(); 
    letterTyper(); 
} 

function newSpan() { 
    var newSpan = document.createElement('span'); 
    var isEmpty = main.innerHTML === ''; 

    newSpan.setAttribute('id', '#span' + spanId); 

    if (isEmpty) { 
    main.appendChild(newSpan); 
    } else { 
    main.insertBefore(newSpan, document.getElementById('#span' + (spanId - 1))); 
    } 

    spanId++; 
} 

function letterTyper() { 
    var targetSpan = main.firstChild; 
    targetSpan.textContent = CONTENT.substring(charCount, charCount + 1) + targetSpan.textContent.substring(0, targetSpan.textContent.length); 
    charCount--; 

    if (charCount < 0) { 
     clearTimeout(timer); 
     charCount = CONTENT.length; 
    } else { 
     timer = setTimeout('letterTyper()', 100); 
    } 
} 
+0

window.onloadは一度だけ実行し、また、そこに任意のループを置かないでください。 – Angels

答えて

0

setTimeoutは非同期です。最初にletterTyperに電話すると、window.onloadに戻り、次にnewSpan()letterTyper()がトリガーされます。

つまり、最初のスパンのループは、2番目のループが開始されたときに最初のループが終了していないため、2番目のループと干渉します。つまり、2番目のループは決して作成されませんが、letterTyperのすべての呼び出しはmainの最初の子として#span1要素(2番目のスパン要素)を参照します。

2番目のループを開始する前に、最初のループが終了するまで待つ必要があります。私はあなたがPromisesを見てみることをお勧めします。

それが今の約束を使用しているので、私はあなたのコード内でいくつかのことを変更:

const CONTENT = 'lorem ipsum'; 
 
var main = document.querySelector('main'); 
 
var spanId = 0; 
 
var charCount = CONTENT.length; 
 

 
window.onload = function() { 
 
    // start the first loop 
 
    letterTyper(newSpan()).then(function() { 
 
    // the first loop has finished, start the second loop 
 
    return letterTyper(newSpan()); 
 
    }).then(function() { 
 
    // the second loop has finished, start the third loop 
 
    return letterTyper(newSpan()); 
 
    }); 
 
} 
 

 
function newSpan() { 
 
    var newSpan = document.createElement('span'); 
 
    var isEmpty = main.children.length === 0; 
 

 
    newSpan.setAttribute('id', '#span' + spanId); 
 

 
    if (isEmpty) { 
 
    main.appendChild(newSpan); 
 
    } else { 
 
    main.insertBefore(newSpan, document.getElementById('#span' + (spanId - 1))); 
 
    } 
 

 
    spanId++; 
 
    charCount = CONTENT.length; // reset the character count 
 
    
 
    return newSpan; 
 
} 
 

 
function letterTyper(span) { 
 
    return new Promise(function (resolve, reject) { 
 
    // executes one tick (adds one character and calls itself after 100ms) 
 
    var tick = function() { 
 
     // prepend a new character 
 
     span.textContent = CONTENT[charCount -= 1] + span.textContent; 
 
     if (charCount > 0) { 
 
     // call tick again in 100ms 
 
     setTimeout(tick, 100); 
 
     } else { 
 
     // loop is finished, the "then" part will be called 
 
     resolve(); 
 
     } 
 
    }; 
 
    // start the loop 
 
    setTimeout(tick, 100); 
 
    }); 
 
}
<main></main>

関連する問題