使用JavaScript的降雪动画&;CSS-无法读取属性';长度';未定义的

使用JavaScript的降雪动画&;CSS-无法读取属性';长度';未定义的,javascript,arrays,loops,object,methods,Javascript,Arrays,Loops,Object,Methods,计划 我想用JavaScript和CSS制作一个动画,计划是让雪花从div的顶部落到底部。简言之,目前我创建了一个div,只添加了几个子DOM元素,这些元素将使用JavaScript创建并附加到已经创建的父元素。当浏览器窗口更改时,雪也将拾取,然后自动创建。代码是使用OOP完成的,它当前将更改每个新的子DOM元素的CSS属性,这些子DOM元素是为了增加顶部和左侧属性而创建的(它们都将设置为绝对位置)一旦DOM元素离开屏幕,它将重置并重新开始,只需确保坚持使用我在Object属性中设置的限制 问

计划

我想用JavaScript和CSS制作一个动画,计划是让雪花从div的顶部落到底部。简言之,目前我创建了一个div,只添加了几个子DOM元素,这些元素将使用JavaScript创建并附加到已经创建的父元素。当浏览器窗口更改时,雪也将拾取,然后自动创建。代码是使用OOP完成的,它当前将更改每个新的子DOM元素的CSS属性,这些子DOM元素是为了增加顶部和左侧属性而创建的(它们都将设置为绝对位置)一旦DOM元素离开屏幕,它将重置并重新开始,只需确保坚持使用我在Object属性中设置的限制


问题

当前,如果我在
setInterval
中运行此方法
snow.animate
,则表示找不到我将所有创建的子DOM元素推入的数组的长度属性,但如果我
console.log()
数组并尝试获取数组的
长度
,然后它实际上会显示
长度
。我在
for
循环之前和循环内部进行了日志记录,以检查是否可以获取数组的长度,它是否可以获取,但在运行
setInterval
时无法获取


问题

我的问题是,我是否遗漏了一些东西,或者我是否只需要单独设置
函数
,而不使用
对象
来存储所有
方法

注意-我在动画
方法中做了一个while循环
-我觉得这样做很不舒服。这是安全的还是不好的做法?是否有另一种方法可以使用
while循环
来创建子元素,这些子元素将被推送到数组中,以便在后面的for循环中使用


演示代码-JSFIDDLE:

HTML

CSS

JS

var-snow={
//变数
宽度:窗。内部宽度,高度:650,片数:10,
重力:0.7,风速:20,雪花:[],
currentFlake:0,snowGlobe:document.getElementById('snowGlobe'),
//方法
getRandom:函数(最小值、最大值){
返回Math.floor(Math.random()*(max-min)+min);
},
设置动画:函数(){
//while循环
while(this.currentFlake此高度){
positionY=0-parseInt(flakes[i].style.fontSize);
位置X=getRandom(0,宽度);
}
//新X位置
如果(!positionX)positionX=parseFloat(flakes[i].style.left)+Math.sin(positionY/this.windSpeed);
如果(位置X<-20)位置X=此宽度+20;
如果(位置X>this.width+20)位置X=-20;
//重新定位
薄片[i].style.top=positionX+'px';
薄片[i].style.left=positionX+'px';
}
}
}
//检查浏览器窗口,是否调整了大小?
window.onresize=函数(){
snow.width=window.innerWidth;
控制台。原木(雪。宽度);
}
设置间隔(snow.animate,1000/60);
//如果您愿意,请退出上面的一行并取消注释下面的一行,以查看雪荷载
//设置动画();


提前感谢

问题是
未设置为正确的对象。有关详细信息,请参阅

您可以这样调用该方法:

setTimeout( function(){ snow.animate(); }, 1000/60 );
但最好使用:

您可以通过调用
snow.animate()
来启动动画

我还擅自修复了一些错误,这些错误您可能不知道,因为代码无法运行(引用
width
而没有
this
等等)。 这是一个例子


我让你的初始化循环保持原样;由于它只运行一次,通常您会将其放在单独的方法中,通常是构造函数或初始化方法。这里唯一的缺点是,在每个动画帧上检查while条件会带来开销

我走过去,明白了你的意思。为我的无知道歉,但谢谢你的回答!我会看看你发送的链接和请求的动画帧:)哦,没问题在完全运行JavaScript之前,您无法确定它是否正常工作。我只是好奇地看着它工作:-)
var snow = {
    //variables
    width: window.innerWidth,height: 650,flakeCount: 10,
    gravity: 0.7,windSpeed: 20,flakes: [],
    currentFlake: 0,snowGlobe: document.getElementById('snowglobe'),
    //methods
    getRandom: function(min,max){
        return Math.floor(Math.random() * (max - min) + min);
    },
    animate: function(){
        //while loop
        while (this.currentFlake < this.flakeCount){
            var flake = document.createElement('div'),
            newFlake;
            flake.className = "flake";
            flake.style.fontSize = this.getRandom(20,50) + 'px';
            flake.style.top = this.getRandom(0,this.height) + 'px';
            flake.style.left = this.getRandom(0,this.left) + 'px';
            flake.innerHTML = "*";
            newFlake = this.snowGlobe.appendChild(flake);
            //set a speed property to the newflake obj
            newFlake.speed = this.getRandom(1,100);
            this.flakes.push(newFlake);
            this.currentFlake++;
        }
        var flakes = this.flakes;
        //use the array of dom elements
        for(var i = 0; i < flakes.length; i++){
            positionX = false;
            positionY = false;
            //new Y position
            positionY = parseFloat(flakes[i].style.top) + (flakes[i].speed / 100) * this.gravity;
            if(positionY > this.height){
                positionY = 0 - parseInt(flakes[i].style.fontSize);
                positionX = getRandom(0, width);
            }
            //new X position
            if (!positionX) positionX = parseFloat(flakes[i].style.left) + Math.sin(positionY / this.windSpeed);
            if (positionX < -20) positionX = this.width + 20;
            if (positionX > this.width + 20) positionX = -20;
            // Set new position
            flakes[i].style.top = positionX + 'px';
            flakes[i].style.left = positionX + 'px';
        }
    }
}
//check browser window, did it resize?
window.onresize = function(){
    snow.width = window.innerWidth;
    console.log(snow.width);
}
setInterval(snow.animate, 1000/60);
//if you want, coment out the above line and uncoment the one below to see the snow loading
//snow.animate();
setTimeout( function(){ snow.animate(); }, 1000/60 );
var snow = {
    ...
    animate: function() {
        ...
        window.requestAnimationFrame( (function(){ this.animate() }).bind(this) );
    }
}