点击块,让小块动起来 - 函数封装

上一期我们主要讲解JS逻辑和DOM的结合 - JS设置标签的内容和样式,它是实现页面交互效果的重要基础知识。如果想具体了解JS设置标签的内容和样式,可以回复“标签”到微信公众号。今天我们要来学习简单的页面交互效果 - 点击块,让块运动起来。

本文内容概要

1 获取标签

2 绑定事件

3 设置样式

4 代码的封装与优化

5 课程小结

6 课程练习

1 获取标签

回顾一下前面学过的知识,如何获取网页中的标签?我们是通过给网页中的标签取一个id名(id名不能重复),再利用getElementById('id名')的方法获取相应的标签,具体看下面的案例。

实例:

<!-- 结构 -->
<div class="wrap">
    <h2 id="webName">HTML5学堂</h2>
    <p id="founder">刘国利 - 利利 & 陈能堡 - 堡堡</p>
</div>
<!-- 脚本 -->
<script type="text/javascript">
    // 获取标签
    var webNameEle = document.getElementById('webName'),
        founderEle = document.getElementById('founder');


    // 输出标签对象
    console.log(webNameEle);
    console.log(founderEle);


    // 输出标签内容
    console.log(webNameEle.innerHTML);
    console.log(founderEle.innerHTML);
</script>

结果:

今天我们要开始学习简单的页面交互效果,需要使用哪些知识点来实现简单的网页与用户的“交互”,那“交互”方面还需要涉及到哪些知识点呢?接着往下看吧。

2 绑定事件

2.1 事件是什么

从生活中的例子来理解事件,比如我们是通过按电灯的开关来控制开灯或熄灯,“电灯的开关功能”我们可以理解为事件,当我们触发这个事件(电灯的开关功能)的时候去执行开灯或熄灯的操作。在网页中事件又是怎么一回事呢?接下来将为您揭晓答案。

2.2 事件的种类

在JS中我们可以把事件分为三大类:一般事件、页面事件、表单事件。

Tips:下面给大家列举比较常用的JS事件类型。

一般事件

1 click - 在用户点击主鼠标按钮(一般是左边的按钮)或者按下回车键时触发;

2 mousedown - 在用户按下了任意鼠标按钮时触发;

3 mouseup - 用户释放鼠标按钮时触发;

4 mousemove - 当鼠标指针在元素内部移动时重复地触发;

5 mouseenter - 在鼠标光标从元素外部首次移动到元素范围之内时触发;

6 mouseleave - 在位于元素上方的鼠标光标移动到元素范围之外时触发;

页面事件

1 load - 当页面完全加载后(包括所有图像、JavaScript文件、CSS文件等外部资源),就会触发window上面的load事件;

2 unload - 在文档被完全卸载后触发。只要用户从一个页面切换到另外一个页面,就会触发unload事件;

3 resize - 当浏览器的窗口大小被改变时触发的事件;

4 scroll - 浏览器的滚动条位置发生变化时触发的事件;

表单事件

1 blur - 当前元素失去焦点时触发的事件;

2 change - 当前元素失去焦点并且元素的内容发生改变而触发的事件;

3 focus - 当某个元素获得焦点时触发的事件;

4 input - 当用户输入时触发;

5 reset - 事件会在表单中的重置按钮被点击时发生;

2.3 给标签绑定事件

了解完了JS的事件类型,那我们在网页中该如何使用这些事件类型呢?首先需要获取网页中的标签,再给标签绑定上相应的事件类型,然后通过触发事件去完成相应的页面交互。

语法:

1 标签对象.on事件类型 = function() { }

2 标签对象.on事件类型 = 函数名;

Tips:function类似于我们数学学过的函数,比如sin、cos等函数,当我们触发事件的时候会去执行function里面的代码语句;在JS里面我们是通过function关键字来进行声明函数,具体的下面的内容会讲解到。

实例:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />
    <title>HTML5Course - 梦幻雪冰</title>
    <link rel="stylesheet" type="text/css" href="reset.css" />
    <style type="text/css">
        .btn {
            width: 50px;
            height: 50px;
            border: 2px solid yellow;
            background-color: pink;
            line-height: 50px;
            text-align: center;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <!-- 结构 -->
    <div class="wrap">
        <div class="btn" id="btnEle">点击</div>
    </div>
 
    <!-- 脚本 -->
    <script type="text/javascript">
        // 获取标签
        var btnObj = document.getElementById('btnEle');


        // 绑定事件
        // 标签对象.on事件类型 = function() { }
        btnObj.onclick = function() {
            alert('你触发了click事件~');
        }
    </script>
</body>
</html>

结果:点击id名为btnEle标签,弹出弹窗,显示“你触发了click事件~”的内容;

分析:

1 代码28行我们获取了网页中id名为btnEle的标签;

2 代码32~34行通过标签对象.on事件类型 = function() {}的方式给标签绑定上click事件类型;

3 代码33行是事件处理程序代码,也就是触发click事件后需要执行的代码(实现某种功能);

4 因为给标签绑定上了click(点击)事件,当用户触发(点击)事件的时候,会执行function里面的代码,所以才会弹出弹窗;

3 设置样式

我们可以通过标签/元素.style.属性 = "属性值" 进行样式的控制或者通过控制类名进行样式的控制,接下来我们要结合JS的事件来设置标签的样式。

实例:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />
    <title>HTML5Course - 梦幻雪冰</title>
    <link rel="stylesheet" type="text/css" href="reset.css" />
    <style type="text/css">
        .btn {
            width: 50px;
            height: 50px;
            border: 2px solid yellow;
            background-color: pink;
            line-height: 50px;
            text-align: center;
            cursor: pointer;
        }
        .model {
            width: 130px;
            height: 130px;
            border: 2px solid gray;
            background-color: skyblue;
        }
    </style>
</head>
<body>
    <!-- 结构 -->
    <div class="wrap">
        <div class="btn" id="btnEle">点击</div>
        <div class="model" id="modelEle">我是小块,点击的时候我会动</div>
    </div>


    <!-- 脚本 -->
    <script type="text/javascript">
        // 获取标签
        var btnObj = document.getElementById('btnEle');
        var modelObj = document.getElementById('modelEle');
        // 定义变量
        var step = 0;


        // 绑定事件
        btnObj.onclick = function() {
            // 每执行一次加1
            step++;


            // 给小块标签设置样式
            modelObj.style.marginLeft = step + 'px';
        }
    </script>
</body>
</html>

结果:

分析:

1 代码43行每次触发click事件step都会在原来的基础上加1;

2 代码46行step变量的值赋值给标签的margin-left的值,需要注意的是不要忘记属性值的单位;

3 每次点击标签(触发click事件),小块会向左移动1px;

4 代码的封装与优化

现在点击块,让小块动起来是已经实现了,那么网页中如果又出现了相同的效果,我们该如何处理呢?把代码复制一遍?这样会产生代码冗余,所以我们需要对代码进行封装与优化;

函数封装

函数:

什么是函数呢?简单的说,函数就是把多条语句封装起来,可以在任意地方放置,也可以在任意地方调用执行。

函数的定义:

语法:

<script>
    function functionName(arg0, arg1, ..., argN) {
        // 具体函数内容 - HTML5学堂
    }
</script>

Tips:functionName代表的是函数名;arg0, arg1, ..., argN代表的是函数的形参(也可以理解为变量);

实例:

<script>
    function sayName(name, username) {
        alert(name + ':' + username);
    }
</script>

函数的执行:

sayName('刘国利', '陈能堡');

函数的参数:

在定义函数的时候括号中的参数叫做形参,调用函数的时候,括号中的参数叫做实参。如果我们规定了形参只有两个(即只有两个用于接收数据的参数),此时在调用的时候我们传递了1个参数或者3个参数进来,解析器也是能够正常解析的,至于原因我们后期的文章会讲解到。

理解函数封装:

实例:

<script type="text/javascript">
    /*
     * [sum 求两个数之间的和]
     * @param  {[数字]} startNum [开始的数]
     * @param  {[数字]} endNum   [结束的数]
     * @return {[数字]}          [求和的结果]
     * 示例:sum(10, 20)
     * author:陈能堡
     */ 
    function sum(startNum, endNum) {
        var result = 0;


        for (var i = startNum; i <= endNum; i++) {
            result += i;
        };


        return result;
    }


    // 第一次调用
    console.log(sum(1, 30));
    // 第二次调用
    console.log(sum(20, 30));
    // 第三次调用
    console.log(sum(32, 40));
</script>

结果:465 275 324

分析:

1 利用function封装了“求两个数之间的和”的sum功能函数;

2 代码21~25总共三次调用sum功能函数,共用相同的代码实现不同的效果;

3 利用函数封装可以减少代码冗余,提升代码的可读性和复用性;

4 函数封装的另外一个好处在于,你不需要了解函数里面的实现原理,只要懂得调用也能实现相应的效果,便于项目团队的开发;

函数封装的实例

函数封装前:

<script type="text/javascript">
    // 以下的命名只是为了让大家便于理解,请勿模仿!!!
    // 获取标签
    var btnObj1     = document.getElementById('btnEle1'),
        btnObj2     = document.getElementById('btnEle2'),
        modelObj1   = document.getElementById('modelEle1'),
        modelObj2   = document.getElementById('modelEle2'),
        step1       = 0,
        step2       = 0;
    // 绑定事件
    btnObj1.onclick = function() {
        // 每执行一次加1
        step1++;
        // 给小块标签设置样式
        modelObj1.style.marginLeft = step1 + 'px';
    }
 
    // 绑定事件
    btnObj2.onclick = function() {
        // 每执行一次加1
        step2++;
        // 给小块标签设置样式
        modelObj2.style.marginLeft = step2 + 'px';
    }
</script>

函数封装后:

<script type="text/javascript">
    // 以下的命名只是为了让大家便于理解,请勿模仿!!!
    // 获取标签
    var btnObj1     = document.getElementById('btnEle1'),
        btnObj2     = document.getElementById('btnEle2'),
        modelObj1   = document.getElementById('modelEle1'),
        modelObj2   = document.getElementById('modelEle2'),
        step1       = 0,
        step2       = 0;
    // 函数封装
    function move(eleObj, step) {
        // 给小块标签设置样式
        eleObj.style.marginLeft = step + 'px';
    }
 
    // 绑定事件
    btnObj1.onclick = function() {
        step1 += 2;
        move(modelObj1, step1);
    }
 
    // 绑定事件
    btnObj2.onclick = function() {
        step2 += 4;
        move(modelObj2, step2);
    }
</script>

结果:

分析:

1 提取了重复的JS代码 - 处理标签的样式,封装在move函数里面;

2 代码19和25行,分别调用move函数,并给函数传递两个实参,分别是标签对象和margin-left变化的值;

作用域

由于本篇文章的篇幅过长,关于作用域的知识安排到下一期进行讲解,请大家谅解~

this对象

this概念:this是JavaScript函数内部的对象(不需要我们声明);

this指向的一句话法则:永远指向其所在函数的所有者如果没有所有者时,指向window;

this的用法:

<!-- 结构 -->
<div class="wrap">
    <div class="btn" id="btnEle">点击</div>
</div>


<!-- 脚本 -->
<script type="text/javascript">
    // 全局函数中的this
    function show() {
        // 输出this的值
        console.log(this);
    }show();


    // 对象.方法中的this
    var obj = {
        name: '陈能堡',
        sayName: function() {
            // 输出this的值
            console.log(this);
        }
    };
    obj.sayName();


    // 鼠标点击事件等进行函数的绑定时,this的指向
    var btnObj = document.getElementById('btnEle');
    btnObj.onclick = function() {
        // 输出this的值
        console.log(this);
    }
</script>

结果:window对象 obj对象 btnObj对象

分析:

1 show这个函数没有所有者,因此此时this指向的是window;

2 obj.sayName表示的是sayName这个函数的所有者是对象obj,因此this应当是指向obj的;

3 onclick事件的拥有者是btnObj。因此,此处this指向btnObj;我们也可以将btnObj.onclick理解为对象.方法;

this对象的实例

继续优化上面“函数封装的实例”的JS代码;

实例:

<!-- 脚本 -->
<script type="text/javascript">
    // 以下的命名只是为了让大家便于理解,请勿模仿!!!
    // 获取标签
    var btnObj1     = document.getElementById('btnEle1'),
        btnObj2     = document.getElementById('btnEle2'),
        modelObj1   = document.getElementById('modelEle1'),
        modelObj2   = document.getElementById('modelEle2'),
        step1       = 0,
        step2       = 0;




    // 函数封装
    function move(eleObj, step) {
        // 给小块标签设置样式
        eleObj.style.marginLeft = step + 'px';
    }
 
    // 绑定事件
    btnObj1.onclick = function() {
        step1 += 2;


        // this代替btnObj1,扩展性更强
        move(this, step1);
    }
 
    // 绑定事件
    btnObj2.onclick = function() {
        step2 += 4;


        // this代替btnObj2,扩展性更强
        move(this, step2);
    }
</script>

分析:

1 代码24和32行利用了this对象做了优化;

2 如果我们修改了btnObj1或btnObj2命名时,click事件里面的代码不用发生改动,因为this指向的还是标签的对象,这样做有利于代码的扩展性;

5 课程小结

本文主要按照一个技术角度的思路来讲解简单页面交互效果的实现;

获取标签——>通过id名获取网页中的标签;

绑定事件——>给获取到的标签绑定JS事件;

设置样式——>触发JS事件的时候设置标签的样式来实现简单的页面交互效果;

代码的封装与优化——>利用function来实现函数的封装,利用this对象对代码进行优化;

6 课程练习

HTML5学堂小编 - 堡堡 耗时9h

欢迎沟通交流~

原文发布于微信公众号 - HTML5学堂(h5course-com)

原文发表时间:2016-05-19

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏对角另一面

lodash源码分析之List缓存

昨日我沿着河岸/漫步到/芦苇弯腰喝水的地方 顺便请烟囱/在天空为我写一封长长的信 潦是潦草了些/而我的心意/则明亮亦如你窗前的烛光/稍有暧昧之处/势所难免...

2586
来自专栏更流畅、简洁的软件开发方式

【自然框架】PowerDesigner 格式的元数据的表结构

自然框架里的元数据 元数据的职责:   自然框架里的元数据有三个职责:描述数据库(字段、表、视图等),描述项目(功能节点、操作按钮等),项目和数据库的关系(一...

2377
来自专栏PHP技术

PHP7标量类型声明RFC

一、总结 该RFC建议添加4种新的标量类型声明:int,float,string和bool,这些类型声明将会和PHP原来的机制保持一致的用法。RFC 更推荐给每...

3335
来自专栏Rgc

使用line_profiler查看api接口函数每行代码执行时间

项目情景描述:   在restful架构风格的项目交付测试的过程中,某接口出现 请求超时导致的http 502 Bad Gateway,于是开始排查具体是接口函...

3174
来自专栏mySoul

微信小程序继续入坑指南

上方完成了一次列表渲染,其中index为默认的遍历到的数组的小标,从0开始,item为当前遍历到的数组对应下标的元素。

688
来自专栏SDNLAB

Open vSwitch系列之openflow版本兼容

众所周知Open vSwitch支持的openflow版本从1.0到1.5版本(当前Open vSwitch版本是2.3.2)通过阅读代码,处理openflow...

41313
来自专栏python3

python Json与pickle数据序列化

在程序运行的过程中,所有的变量都是在内存中。一旦程序结束,变量所占用的内存就被操作系统全部回收。

691
来自专栏冰霜之地

Realm数据库 从入门到“放弃”

Realm是由Y Combinator公司孵化出来的一款可以用于iOS(同样适用于Swift&Objective-C)和Android的跨平台移动数据库。目前最...

522
来自专栏北京马哥教育

Python 函数库 APIs 编写指南

1654
来自专栏技术博客

Json和Jsonp

  JSON和JSONP虽然只有一个字母的差别,但其实他们根本不是一回事儿:JSON是一种数据交换格式,而JSONP是一种依靠开发人员的聪明才智创造出的一种非官...

642

扫描关注云+社区