javascript - 将递归函数转换为异步 CPS 实现 (javascript)

标签 javascript jquery dom asynchronous callback

这是我的功能。

    function duplicate_step_through_highlighted (element_jq, target_jq, char_cb) {
        console.log( element_jq);
        var contents = element_jq.contents();
        for (var i = 0 ; i < contents.length; ++i) {
            // if text node, step
            if (contents[i].nodeType === 3) {
                // insert empty text node
                var new_tn = document.createTextNode('');
                target_jq.append(new_tn);

                // iterate it 
                var text = contents[i].nodeValue;
                for (var j = 0; j < text.length; j++) {
                    char_cb(text[j],new_tn);
                    new_tn.nodeValue += text[j];
                    // *** I want an async delay here *** 
                }
            } else { // type should be 1: element
                // target_jq gets a duplicate element inserted, copying attrs
                var new_elem = $(contents[i].cloneNode(false)).appendTo(target_jq);
                duplicate_step_through_highlighted($(contents[i]),$(new_elem),char_cb);

                // then a recursive call is performed on the newly created element as target_jq
                // and the existing one as element_jq. char_cb is passed in
            }
        }
    }

我正在做的是通过一次重建一个字符来重建 HTML 元素。这样做有一个很好的理由,我想要它“输入”的视觉效果。

所以现在没有延迟,所以我的元素会立即被复制。我已经检查结果是否一致,但我越来越清楚,我可能需要完全重写功能,以便能够在插入每个字符后插入异步延迟。

我需要重写它并有一个堆栈来跟踪我在元素中的位置吗?

最佳答案

您可能想看看我最近的answerthis older one ( Demo ),了解如何实现这样的效果。

<小时/>

提示:不要将元素克隆到新元素中,只需隐藏它们并使它们逐个显示即可。

此外,除了原生 DOM 元素之外,根本不处理 jQuery 实例可能会更容易。所以是的,重写可能会做:-)而且我认为它也确实需要一个堆栈。

function animate(elements, callback) {
/* get: array with hidden elements to be displayes, callback function */
    var i = 0;
    (function iterate() {
        if (i < elements.length) {
            elements[i].style.display = "block"; // show
            animateNode(elements[i], iterate); 
            i++;
        } else if (callback)
            callback();
    })();
    function animateNode(element, callback) {
        var pieces = [];
        if (element.nodeType==1) {
            while (element.hasChildNodes())
                pieces.push(element.removeChild(element.firstChild));
            setTimeout(function childStep() {
                if (pieces.length) {
                    animateNode(pieces[0], childStep); 
                    element.appendChild(pieces.shift());
                } else
                    callback();
            }, 1000/60);
        } else if (element.nodeType==3) {
            pieces = element.data.match(/.{0,2}/g); // 2: Number of chars per frame
            element.data = "";
            (function addText(){
                element.data += pieces.shift();
                setTimeout(pieces.length
                    ? addText
                    : callback,
                  1000/60);
            })();
        }
    }
}

animate($("#foo").children());

Demo at jsfiddle.net

它是如何工作的:

  • addText 函数向当前文本节点添加一些字符,并为其自身设置超时 - 动画!如果一切都完成,它会调用回调函数。
  • childStep 在子节点上运行动画,并将其自身作为回调传递,直到没有子节点离开 - 然后调用callback函数。
  • 两者结合在一起,animateNode 递归地运行节点树并按顺序为文本节点设置动画。
  • iterate 函数通过将自身作为回调传递,在所有输入元素上调用 animateNode(在取消它们之后)。所有输入元素完成后,它会调用外部回调,该回调作为animate的第二个参数给出。

关于javascript - 将递归函数转换为异步 CPS 实现 (javascript),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11665484/

相关文章:

javascript - 没有悬停的CSS父子循环过渡

javascript - 使用外部 jQuery 浏览 FullCalendar

javascript - 在 Javascript 中以 360° Angular 移动图像

JavaScript/DOM : how to prevent blur event if focus is lost to another window (application)

javascript - onclick 切换插入的元素

javascript - css将盒子居中,但没有理由居中

javascript - 如何避免日期时间选择器中的秒数?

javascript - 根据条件对 html 组件进行 jsx 循环包装

jquery - 使用 jQuery 遍历 DOM

javascript - 合并两个 html 表单中的数据元素无法正常工作