我在这里阅读了关于在密集DOM处理(使用JavaScript)期间使用setTimeout()的帖子,但是如何将此函数与下面的代码集成?以下代码适用于少量选项,但当选项数量太大时,我的"请等待"动画GIF会在本地JavaScript处理时冻结.谢谢!
function appendToSelect() { $("#mySelect").children().remove() ; $("#mySelect").html( '' ); var j = 1 ; for (var i = 1; i < obj.data.length; i++) { $("#mySelect").append( '' ); } }
Jason Buntin.. 29
这是一个解决方案:
function appendToSelect() { $("#mySelect").children().remove(); $("#mySelect").html( '' ); obj.data.splice(0, 1); // we only want remaining data var appendOptions = function() { var dataChunk = obj.data.splice(0, 10); // configure this last number (the size of the 'chunk') to suit your needs for(var i = 0; i < dataChunk.length; i++) { $("#mySelect").append( '' ); } if(obj.data.length > 0) { setTimeout(appendOptions, 100); // change time to suit needs } }; appendOptions(); // kicks it off }
不像@Borgar的解决方案那么优雅,但你明白了.基本上,我正在做同样的事情,但是在你的一个函数中,而不是像他那样将它分解为更高阶的函数.我喜欢他的解决方案,但如果你不喜欢,也许这对你有用.
编辑:对于那些没有立即看到它的人来说,这个解决方案和@ Borgar之间的主要区别之一是这个解决方案允许你设置每次超时之间处理的数据"块"的大小.@Borgar在处理完每个数组成员后的超时时间.如果我有时间,我会尝试创建一个更高阶的函数来处理这个,所以它更优雅.虽然没有承诺!;)
编辑:所以,这是我改编的@Borgar的解决方案,它允许设置'块'大小并更容易配置超时值:
function incrementallyProcess(workerCallback, data, chunkSize, timeout, completionCallback) { var itemIndex = 0; (function() { var remainingDataLength = (data.length - itemIndex); var currentChunkSize = (remainingDataLength >= chunkSize) ? chunkSize : remainingDataLength; if(itemIndex < data.length) { while(currentChunkSize--) { workerCallback(data[itemIndex++]); } setTimeout(arguments.callee, timeout); } else if(completionCallback) { completionCallback(); } })(); } function appendToSelect() { $("#mySelect").children().remove(); $("#mySelect").html( '' ); obj.data.splice(0,1); // we only want remaining data incrementallyProcess(function(data) { $("#mySelect").append( '' ); }, obj.data, 10, 100, removeAnimatedGifFunction); // last function not required... }
希望有所帮助 - 我认为这结合了两种解决方案的优点.注意,第二个匿名函数不再使用索引值,而只是传递整个对象(带有value和name属性); 因为当迭代事物时,当前对象的索引通常不是那么有用,所以它会变得更清晰一些.
我相信仍然有一些事情可以做到更好,但这仍然是读者的练习.;)
这是一个解决方案:
function appendToSelect() { $("#mySelect").children().remove(); $("#mySelect").html( '' ); obj.data.splice(0, 1); // we only want remaining data var appendOptions = function() { var dataChunk = obj.data.splice(0, 10); // configure this last number (the size of the 'chunk') to suit your needs for(var i = 0; i < dataChunk.length; i++) { $("#mySelect").append( '' ); } if(obj.data.length > 0) { setTimeout(appendOptions, 100); // change time to suit needs } }; appendOptions(); // kicks it off }
不像@Borgar的解决方案那么优雅,但你明白了.基本上,我正在做同样的事情,但是在你的一个函数中,而不是像他那样将它分解为更高阶的函数.我喜欢他的解决方案,但如果你不喜欢,也许这对你有用.
编辑:对于那些没有立即看到它的人来说,这个解决方案和@ Borgar之间的主要区别之一是这个解决方案允许你设置每次超时之间处理的数据"块"的大小.@Borgar在处理完每个数组成员后的超时时间.如果我有时间,我会尝试创建一个更高阶的函数来处理这个,所以它更优雅.虽然没有承诺!;)
编辑:所以,这是我改编的@Borgar的解决方案,它允许设置'块'大小并更容易配置超时值:
function incrementallyProcess(workerCallback, data, chunkSize, timeout, completionCallback) { var itemIndex = 0; (function() { var remainingDataLength = (data.length - itemIndex); var currentChunkSize = (remainingDataLength >= chunkSize) ? chunkSize : remainingDataLength; if(itemIndex < data.length) { while(currentChunkSize--) { workerCallback(data[itemIndex++]); } setTimeout(arguments.callee, timeout); } else if(completionCallback) { completionCallback(); } })(); } function appendToSelect() { $("#mySelect").children().remove(); $("#mySelect").html( '' ); obj.data.splice(0,1); // we only want remaining data incrementallyProcess(function(data) { $("#mySelect").append( '' ); }, obj.data, 10, 100, removeAnimatedGifFunction); // last function not required... }
希望有所帮助 - 我认为这结合了两种解决方案的优点.注意,第二个匿名函数不再使用索引值,而只是传递整个对象(带有value和name属性); 因为当迭代事物时,当前对象的索引通常不是那么有用,所以它会变得更清晰一些.
我相信仍然有一些事情可以做到更好,但这仍然是读者的练习.;)
碰巧我刚刚在这里发布了这个帖子.这是一个定时循环函数:
function processLoop( actionFunc, numTimes, doneFunc ) { var i = 0; var f = function () { if (i < numTimes) { actionFunc( i++ ); // closure on i setTimeout( f, 10 ) } else if (doneFunc) { doneFunc(); } }; f(); }
对于您的情况,这将使用如下:
function appendToSelect () { $("#mySelect").children().remove() ; $("#mySelect").html( '' ); var j = 1 ; processLoop(function (i){ $("#mySelect").append( '' ); }, obj.data.length); }
您需要确保在迭代函数中有一个闭包或对obj变量的其他访问.
希望这可以帮助.