看了180分钟的视频,写了半天的代码

观视频《月薪4万的程序员有多强?半小时原生JS开发打气球游戏,征服现场数万人!》

清晨,日常打开B站,被首页此视频的标题所吸引,虽一看就是标题党,但还是没能抑制住好奇心。 视频共计60*3分钟,学习到了很多东西。其中后半部分有许多正三观的见解也非常认同。 视频地址:https://www.bilibili.com/video/av15152538/ 在线试玩:http://sandbox.runjs.cn/show/luderhbq 参考视频写的demo:https://coding.net/u/yimocoding/p/WeDemo/git/tree/气球大战

看了视频,自己来实现试试

花了半天的时间,人生中的第二个游戏终于完成了,想起第一次做拼图游戏也已经是3年前了~ 来吧,试玩一下,看能消灭多少个气球【笑哭】:http://sandbox.runjs.cn/show/luderhbq 然后,一起来一步步构建自己的【气球大战】(文中代码为核心代码,后续有优化,故非完整代码),可以在runjs中去查看

1.用css3画一个气球

看视频的时候觉得自己这个会那个也会,写代码的时候才发现没有智能提示啥都不会,打错单词的次数不是一次两次~

气球效果预览

css代码

//html→→_→→<div class="balloon"></div>

body{margin:0;padding:0}
.balloon{width:150px;height:150px;position:absolute;left:0;top:0;background-color:pink;border-radius:50% 50% 10% 50%;transform:rotate(45deg);box-shadow:1px 1px 20px 20px red inset}
.balloon:after{width:20px;height:20px;content:"";display:block;background:0 0;position:absolute;right:-15px;bottom:-15px;border-left:5px solid red;border-top:5px solid red}
.balloon:before{width:2px;height:50px;content:"";display:block;background:pink;position:absolute;right:-10px;top:100%;margin-top:-16px;transform:rotate(-45deg)}

2.随机创建气球

首先定义了一些变量

    var bnElements=[];//存放所有气球
    var random=Math.random;//随机函数
    var wW=window.innerWidth;//窗口宽度
    var wH=window.innerHeight;//窗口高度
    var ballW=160;//气球的宽度
    var ballH=300;//气球的宽度
    var minSpeed=3;//最小速度,每次向上移动至少3px
    var speedNum=8;//速度的定量
    var defBnNumber=10;//初始化气球

首先编写并调用初始化方法生成气球

生成气球代码

    init(defBnNumber);
    //初始化气球
    function init(num){
        //创建一个虚拟文档节点
        var docFragment=document.createDocumentFragment();
        for(var i=0;i<num;i++){
            var bnElement=document.createElement('div');
            bnElement.className='balloon';
            //速度随机,限定最小值
            var speed=Math.max(minSpeed,~~(random()*speedNum));
            bnElement.setAttribute('speed',speed);//~~取整 移动速度
            bnElement.setAttribute('id','ball-'+(bnElements.length+i+1));
            //分散排列
            var x=(~~(random()*wW))-ballW;
            x=Math.max(0,x);
            bnElement.style.left=x+'px';                
            bnElement.style.top=wH+'px';//露一点出来         
            
            //1.先将创建的气球放入创建的虚拟文档节点
            docFragment.appendChild(bnElement);
            bnElements.push(bnElement);
        }
        //2.将虚拟文档节点添加到body中
        document.body.appendChild(docFragment);
    }

效果预览

3.气球向上移动

创建一个move方法并在初始化后调用

气球移动代码

    move();//移动气球 只需要调用一次即可
   function move(){
    var bl=bnElements.length
    for(var i=0;i<bl;i++){
            var currentElement=bnElements[i]
            if(currentElement==null){
                continue;
            }
            var offsetTop=currentElement.offsetTop;
        if(offsetTop>-ballH){//窗口中
                var speed=currentElement.getAttribute('speed');
                currentElement.style.top=offsetTop-speed+'px'
            }
            else{
                //移除dom节点
                document.body.removeChild(currentElement);
                //移除数组中
                bnElements.splice(i,1);
                init(1);
            }
    }
    setTimeout(move,1000/30);
}

效果预览

4.点击气球,气球消失

发现颜色有点丑~~遂改。

气球消失代码

bindClick();
//绑定点击气球事件
function bindClick(){
    document.body.addEventListener('click',function(e){
        if(e.target.className=='balloon'){
            boom.call(e.target,function(){
                e.target.parentNode.removeChild(e.target);
                bnElements.splice(bnElements.lastIndexOf(e.target),1);
                init(1);
            });
        }
    });
}
function boom(callback){
    //var that=this; //替换了上下文,但是没有使用this的意义.
    var speed=this.getAttribute('speed');
    this.timer=setInterval(function(){
        this.style.opacity=0.1*(speed--)
        console.log(this.offsetWidth);
        if(speed<1){
            callback&&callback();
            clearInterval(this.timer);
        }
    }.bind(this),1000/30);
}

效果预览

核心代码终于写完,在我的纯静态工具站点生成二维码扫一扫,在我的小米手机上玩了玩,ok正常,然后再新入手的ipad中试了试。。。擦。坑爹呢,点了咋没反应啊。 好吧,为了ipad能玩,强忍着泪水(饿的)解决了iOS的safari兼容问题~

5.解决遇到的safari浏览器兼容问题

  • 问题一:Safari中单击事件不能绑定到document.body上~~,因为无效~ 解决方法:给元素加了个父级~,若click事件有问题则还需要将click换成touchend~
  • 问题二:transform变换z-index层级渲染异常 解决方法:未变换的元素上添加样式:transform: translateZ(120px); 参考文章:http://www.zhangxinxu.com/wordpress/2016/08/safari-3d-transform-z-index/

总结

get了几个以前不知道没用过的新技能

  • 文档片段 当需要将一堆节点添加到dom中可以使用document.createDocumentFragment();创建虚拟文档节点,让后将节点先添加到此虚拟节点中,再将此节点追加到指定元素,能够降低dom渲染次数
  • 使用位运算符取整 取0-9的随机数 ~~(Math.random()*10) //Math.random()大于等于 0.0 且小于 1.0
  • Math.max() Math.min() 可以用来限定边界值
  • setInterval问题:
    • 可能会丢帧(浏览器的刷新频率为60FPS,一秒最大可以重绘60次),故理论上setinterval()间隔时间大于1000/60就不会参数丢帧的情况
    • 时间线偏移(甚至重叠没执行完就执行下一次任务了),若需要每次都执行完才执行下次任务则使用setTimeout+递归
    • this的传递(可以使用bind()去绑定this,不能使用call,会提示没有权限) 传递this到setInterval中:setInterval(function(){}.bind(this),1000/30)
  • 值的相等判断使用===会比==性能好一点,大部分情况应当使用===
  • 判断回调函数并执行回调函数 以前我是这样写的:if(typeof(callback)==='function')callback(); 视频中有用短路运算符实现即:callback&&callback()
  • 踩了踩safari的坑
  • 最可怕的事情,不是别人比你强,而是比你强的人比你还努力!!!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏葡萄城控件技术团队

前端代码标准最佳实践:CSS篇

上一篇《前端代码标准最佳实践:javascript》发表后,大家讨论还是很热烈,从侧面体现了前端工程师对写标准的前端代码的重视程度很高。这些最佳标准实践并不是那...

22710
来自专栏数据的力量

10个提高你工作效率的Excel技巧

3084
来自专栏AndroidTv

关于RecyclerView你知道的不知道的都在这了(上)前言目录正文

1.2K6
来自专栏程序员互动联盟

【专业文章】六种常见的HTML5写法误用(二)

四、figure元素的常见错误 figure以及figcaption的正确使用,确实是难以驾驭。让我们来看看一些常见的错误, 不是所有的图片都是figure 上...

2935
来自专栏AndroidTv

属性动画 ValueAnimator 运行原理全解析

好,废话不多说,之前我们已经分析过 View 动画 Animation 运行原理解析,那么这次就来学习下属性动画的运行原理。

4358
来自专栏从零开始学 Web 前端

UTF8最好不要带BOM

摘自:http://www.cnblogs.com/findumars/p/3620078.html

1446
来自专栏Alice

ios 继承UITableViewController,更改tableview样式

// 继承UITableViewController,更改tableview样式 - (instancetype)initWithStyle:(UITableV...

3546
来自专栏腾讯AlloyTeam的专栏

构建流式应用:RxJS 详解

本文结合作者自己对 RxJS 理解,通过 RxJS 的实现原理、基础实现及实例来一步步分析,提供 RxJS 较为全面的指引,感受下使用 RxJS 编码是怎样的体...

2.9K2
来自专栏静晴轩

Vue 各类数据绑定

『天下武功,唯快不破』√,这一直是对武学造诣方面的追捧,虽然对于这个丝毫不会;更是对待现实工作不懈渴求,乃至苛求。因为这已不是遁隐修行,而是职场卖命,唯有先快速...

3947
来自专栏nimomeng的自我进阶

抓住iOS的未来 - 30天学习编写30个Swift小程序

=======================================================

4842

扫码关注云+社区

领取腾讯云代金券