在创建和插入的DOM元素中执行函数

时间:2017-07-05 15:23:57

标签: javascript dom

我的意图非常简单:我有一个newSpan()函数,它创建一个新的span并将其插入到main元素的第一个子元素之前(或者如果{main元素的话,将其附加到letterTyper()元素。 1}}是空的)和CONTENT函数,它使用存储在window.onload常量中的字符串填充插入的元素,同时生成一种向后键入效果。我们的想法是创建一个新元素,然后在window.onload中使用循环触发其中的效果给定次数。

但是当我用

填充window.onload = function() { newSpan(); letterTyper(); newSpan(); letterTyper(); } 匿名函数时
<main>
  <span id="#span1">lorem ipsum</span>
  <span id="#span0"></span>
</main>

我在DOM中最终得到的是

DOMContentLoaded

我还尝试使用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); } } 事件,但没效果。这是为什么?我做错了什么?

我的代码:

{{1}}

1 个答案:

答案 0 :(得分:0)

df = df.sort_values(['user_id', 'user_time']) df['COUNTIFS'] = df.groupby('user_id').cumcount() + 1 是异步的。当您第一次致电setTimeout时,它会返回letterTyper并触发下一个window.onloadnewSpan()

这意味着第一个跨度的letterTyper()循环会干扰第二个循环,因为第一个循环在第二个循环启动时尚未完成。换句话说,永远不会创建第二个循环,但letterTyper的所有调用都会将letterTyper元素(第二个span元素)视为#span1的第一个子元素。

在开始第二个循环之前,必须等到第一个循环结束。我建议你看一下Promises

我在代码中更改了一些内容,现在使用promises:

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