问题描述
这是我的功能.
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 元素.这样做有一个很好的理由,我想要它被输入"的视觉效果.
What I'm doing is rebuilding an HTML element by reconstructing it one character at a time. There is a good reason for doing this, I want the visual effect of it getting "typed in".
所以现在没有延迟,所以我的元素会立即复制.我已经检查过结果是否一致,但我越来越清楚,我可能需要完全重新编写功能,以便我能够在插入每个字符后进行异步延迟.
So right now there are no delays so my element gets duplicated instantly. I have checked that the result is consistent, but it is becoming clear to me that I will probably need to completely re-write the functionality in order for me to be able to put in an asynchronous delay after each character is inserted.
我是否需要重写它并有一个堆栈来跟踪我在元素中的位置?
Will I need to re-write it and have a stack to keep track of my position within the elements?
推荐答案
你可能想看看我最近的答案 或 这个较旧的 (Demo),关于如何实现这样的效果.
You might want to have a look at my recent answer or this older one (Demo), on how to implement such an effect.
提示:不要将元素克隆到新元素中,只需隐藏它们并让它们部分显示即可.
Tip: Don't clone the elements into new ones, just hide them and make them appear part-for-part.
此外,除了原生 DOM 元素之外,根本不处理 jQuery 实例可能更容易.所以是的,重写可能会 :-) 而且我认为它确实也需要一个堆栈.
Also, it might be easier not to deal with jQuery instances at all but native DOM elements. So yes, a rewrite might do :-) And I think it does need a stack as well.
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());
工作原理:
addText
函数向当前文本节点添加一些字符,并为自身设置超时 - 动画!如果一切都完成了,它会调用callback
函数.childStep
在子节点上运行动画,并将自身作为回调传递,直到没有子节点剩下 - 然后调用callback
函数.- 两者一起,
animateNode
递归地遍历节点树并按顺序为文本节点设置动画. iterate
函数通过将自身作为回调传递给所有输入元素调用animateNode
(在取消隐藏它们之后).在所有输入元素完成后,它调用外部callback
,它作为animate
的第二个参数给出.
- The
addText
function adds some character to the current text node, and sets a timeout for itself - animation! In case everything is done, it invokes thecallback
function. childStep
runs the animation on a childnode, and passes itself as the callback until no children are left - then nvokes thecallback
function.- Both together,
animateNode
recursively runs over the node tree and animates the textnodes in thier order. - the
iterate
function callsanimateNode
(after unhinding them) on all input elements, by passing itself as the callback. After all input elements are finished, it invokes the outercallback
which is given as the second argument toanimate
.
这篇关于将递归函数转换为异步 CPS 实现 (javascript)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!