我在一个DOM元素中使用javascript创建一个属性,该函数也使用setInterval
来回读这些值。
但是我发现从之前设置此属性的相同元素不再具有定义的值。这是相当奇特的,一种可能的解释是解释器认为不再存在对此属性的引用(即使赋予setInterval
的匿名函数访问它)。
这很难解释所以我会在这里粘贴整个代码以及一些行号。
294 function toCamelCase(variable) {
295 return variable.replace(/-([a-z])/g,function(str,letter){return letter.toUpperCase();});
296 }
297 function parseRGBStr(rgb) {
298 return rgb.match(/rgba?\(([0-9]+),\s?([0-9]+),\s?([0-9]+)/).slice(-3);
299 }
300
301 // the goal for this function is to create a self contained timer-driven
302 // method for animating a fading color onto an arbitrary set of elements
303 // and some particular style property belonging to them.
304 // Furthermore, when multiple colors are to be set to the same property,
305 // their colors are to be blended. Colors specified in a [r,g,b] format
306 function createFadeEffect(elems, styleprop, colorBegin, duration) {
307 var startTime = (new Date).getTime(); // start the effect immediately
308 var endTime = startTime + duration;
309 function lerpColors(colA, colB, alpha) {
310 //alert("a: "+colA+" b: "+colB+' al: '+alpha);
311 if (alpha < 0) alpha = 0;
312 if (alpha > 1) alpha = 1;
313 return [(1.0-alpha)*colA[0] + alpha*colB[0],
314 (1.0-alpha)*colA[1] + alpha*colB[1],
315 (1.0-alpha)*colA[2] + alpha*colB[2]];
316 }
317 var fade_anim_values = [startTime,endTime,colorBegin];
318 for(var i=0;i<elems.length;i++) {
319 var f_a = elems[i].fade_anim;
320 if (f_a == undefined) elems[i].fade_anim = {};
321 f_a = elems[i].fade_anim;
322
323 if (f_a[styleprop] == undefined) {
324 f_a[styleprop] = {arr:[], def:parseRGBStr(document.defaultView.getComputedStyle(elems[i],'').getPropertyValue(styleprop ))};
325 //buffer.push([startTime,elems[i],f_a[styleprop].def]);
326 }
327 f_a[styleprop].arr.push(fade_anim_values); // store reference rather than making copies
328 }
329 var handle = setInterval(function () {
330 var nowTime = (new Date).getTime();
331 if (nowTime > endTime) {
332 // i'm expired. Clean myself up entirely from everything I've touched.
333 clearInterval(handle); // don't run me anymore
334 for (var i=0;i<elems.length;i++) {
335 var f_a = elems[i].fade_anim;
336 for (var j=0;j<f_a[styleprop].arr.length;j++) {
337 if (f_a[styleprop].arr[j] == fade_anim_values) { // that's me!
338 f_a[styleprop].arr.splice(j,1);
339 break;
340 }
341 }
342 if (f_a[styleprop].arr.length == 0) {
343 elems[i].style[toCamelCase(styleprop)] = '';
344 }
345 }
346 return;
347 }
348 for (var i=0;i<elems.length;i++) {
349 var f_a = elems[i].fade_anim;
350 if (f_a[styleprop].arr.length == 0) { alert('encountered empty styleprop array in handler'); continue; } // nothing to do here
351 // only require one interval-closure to process a particular element-styleprop combination.
352 if (f_a[styleprop].arr.length == 1 // i am the only interval attached to this element for this prop
353 || f_a[styleprop].arr[0] == fade_anim_values) // I am the zero-indexed handler
354 {
355 var colorValue = f_a[styleprop].def;
356 for (var j=0;j<f_a[styleprop].arr.length;j++) {
357 var data = f_a[styleprop].arr[j];
358 var alpha = (nowTime - data[0]) / (data[1]-data[0]);
359 var f_c = lerpColors(data[2],f_a[styleprop].def,alpha);
360 colorValue[0] += f_c[0];
361 colorValue[1] += f_c[1];
362 colorValue[2] += f_c[2];
363 }
364 // clamp-norm
365 var max = Math.max(colorValue[0],colorValue[1],colorValue[2]);
366 if (max > 255) {
367 colorValue[0] *= 1.0/max * 255;
368 colorValue[1] *= 1.0/max * 255;
369 colorValue[2] *= 1.0/max * 255;
370 }
371 var propstr = 'rgb('+Math.floor(colorValue[0])+','+Math.floor(colorValue[1])+','+Math.floor(colorValue[2])+')';
372 elems[i].style[toCamelCase(styleprop)] = propstr;
373 }
374 }
375 },30);
376 }
这里发生的是我将一个元素数组传递给主函数createFadeEffect
。此函数将为每个指定元素的.fade_anim
属性创建并保存值。它附加到包含在其中的数组中。然后它使用匿名函数生成一个间隔,该函数检查每个元素中的.fade_anim
。当调用createFadeEffect
的多个调用,并且都指定相同的元素和相同的样式属性时,意图是元素的.fade_anim.arr
累积指定的颜色值。在修改元素的适当样式时,间隔闭包循环遍历此数组以考虑所有颜色。
正在发生的是,对于某些元素,多次输入从第323行开始的块。我无法想出一种简单的方法来显示它们是什么特定元素,当它发生时,但我知道.def
值被设置为中间值,这是过程的结果本身。这应该永远不会发生,因为无论何时设置值,我都不会自己删除它。
这是GC与我联系吗?我正在寻找有关如何更好地调试它以便跟踪.fade_anim
s正在发生的事情的建议。
答案 0 :(得分:0)
console.debug()
是你的朋友(对于非IE)。
答案 1 :(得分:0)
我取得了一些进展。在355行,我需要做一个深层复制。当我只想修改一个临时变量时,我所做的就是使用存储的值。
另外......回应负面反馈。是的,我确实责怪系统行为不端,但可能不是。任何程序员都可以说他们从未这样做过吗?我想我应该重命名这个标题。