五、JS函数与DOM

一、函数

1. 什么是函数?函数为变成带来了那些便利?

  • 函数是语句的封装,可以让这些代码方便的被复用
  • 便利
    • “一次定义,多次调用”
    • 使用函数可以简化问题,让代码更具有可读性

2. 函数的参数和返回值

3. 函数的相关算法题

  • 喇叭花数:其每一位数字的阶乘之和恰好等于它本身,即abc = a! + b! + c!,其中abc代表一个三位数
    【思路】将计算某个数字的结成封装成函数
function plus(n){
    var sum = 1;

    for (var i= 1; i<=n;i++){
        sum *= i;
    }
    return sum;
}

for(var j = 100; j<=999; j++){
    var s = j.toString();
    var a = Number(s[0]);
    var b = Number(s[1]);
    var c = Number(s[2]);
  • JS内置sort()函数
    • 数组排序可以用sort方法,这个方法的参数又是一个函数
var arr = [22, 33, 55, 66];
arr.sort(  function(a,b){}  )

【难点】

1. 递归、递归算法题(深克隆、扁平化数组、计算阶乘)

  • 递归
    • 函数的内部语句可以调用这个函数本身,从而发起对函数的一次迭代
    • 递归的要素
      • 边界条件:确定递归到什么时候中止,也叫做递归出口
      • 递归模式:大问题是如何分解成小问题的,也叫做递归体
  • 深克隆
    • 这里就用到了递归的思想
// 实现深克隆
var arr1 = [2,3,5,[1,32],[2,4,6]];

function deepcopy(arr){
    var newarr = [];
    for(var i= 0; i<=arr.length; i++){
        if(Array.isArray(arr[i])){
             newarr.push(deepcopy(arr[i]));
        }
        else{
             newarr.push(arr[i]);
        }
    }
    return newarr;
}
var arr2 = deepcopy(arr1);
console.log(arr2);

2. 作用域和闭包

  • 作用域链
    • 一个函数内部也可以定义一个函数,和局部变量类似,定义在一个函数内部的函数时局部函数
    • 作用域链则时,在函数嵌套中,变量会从内到外的寻找他的定义
  • 闭包
    • 闭包时函数本身和函数所处环境的结合体,函数可以记忆住他所处的环境,调用一个函数内部的函数,他也能访问定义时所处的变量
    • 功能
      • 记忆性:当闭包产生时,函数所处环境的状态会始终保持在内存中,不会在外层函数调用后被自动清除,这就是闭包的记忆性。
      • 模拟私有变量:像C++、Java中都有私有属性的概念,但是js只能用闭包来模拟,要求这个a只能被进行指定操作
//这是一道面试题
function addCount(){
    var count = 0;
    return function () {
        count = count + 1;
        console.log(count);
    };
}
var fun1 = addCount();
var fun1 = addCount();
fun1();
fun2();
fun2();
fun1();

3. IIFE

立即执行函数

  • 函数必须转为函数表达式才能被调用
  • 作用
    • 为变量赋值
    • 将全局变量作为局部变量
(function(){
	statements
})()
var arr = [];
for (var i=0;i<5;i++){
	(function(i){
		arr.push(function(){
		alert(i);
		}
		})(i)
}

二、DOM

DOM是什么?

  • DOM(Document Object Model,文档对象模型)是JS操控HTML文档和CSS的接口
  • 最大的特点就是将文档表示为节点树

1. 访问元素节点有哪些方法?

  • getelementbyid
  • getelementsbyclassname
  • getelementsbytagname
  • document.querySelector() 通过选择器得到元素
  • document.querySelectorAll()通过选择器得到元素组

2.节点的关系有哪些?

  • childNode子节点
  • parentNode父节点
  • firstChild第一个子节点
  • lastChild最后一个子节点
  • previouSibling前一个兄弟节点
  • nextSibling后一个兄弟节点

3.常用节点操作有哪些?

  • 改变元素节点中的内容
    • innerHTML:可以以HTML语法设置节点中的内容
      • 如果符合W3C可以直接修改,例:oBox.style.color=('red');
      • 如果不符合W3C要用setAttribute()getAttribute设置和读取
    • innerText :只能以纯文本的方式设置节点的内容

4.节点的创建、移除和克隆要如何实现?

  • 节点的创建 var node = document.createElement("**")
  • 节点的移除 ``
  • 节点的克隆(先克隆再上树) var li = ***.clonenode 父节点.appendchild(子节点);

上树有两种方式

  • 父节点.appendChild(子节点);
  • 父节点.insertBefore(孤儿节点,标杆节点);

【难点】

1. 事件捕获和冒泡是什么?应该如何设置?

  • 事件流是人为规定的一个方向,会从最外层元素传播到最内层元素,然后从最内层元素传播会最外层元素,向内层传播我们称为捕获阶段,向外层传播我们称为冒泡阶段。先捕获后冒泡。为了监听捕获阶段和冒泡阶段,这里使用DOM二级,即addEventListener(true)(里面的参数如果是 true就是捕获,如果是false就是冒泡)(如果是DOM零级 on**(例:onclick)都是事件的冒泡阶段)

2. 什么是事件委托?什么时候要用事件委托?

  • 利用事件冒泡的机制可以将子元素委托给父元素,这时点击了子元素可以视为点击了父元素,当子元素过多,用循环语句内存消耗过大,这时使用事件委托比较合适;或者要动态添加子元素时,事件委托也是个最好的选择。

3. 使用定时器和CSS3的过度实现动画

  • 使用定时器setIterval(function(){},2000);时,注意“设表先关 ”
		var timer;

        //动画封装成函数
        function move() {
            //设表先关
            clearInterval(timer);
            timer= setInterval(function(){
                left -= 2;
                if(left < -800){
                    left = 0;
                }
                list.style.left = left + 'px';
            },20);
        } 
  • 动画过渡时,要注意“函数节流”
//设定一个开的锁
var lock = true;
function(){
	if(!lock) return;
	lock = false;
	setTimeout(function(){
		lock = true;
},500);
} 
  • 动画过渡两个(代码在最后)
    • 跑马灯轮播图:将图片拍成一排,设置右按钮时,首先拷贝第一张图片到最后一张,当idx>4时,图片立即切换到第一张图片;设置左按钮时,首先跳转到假的第一张图片(即克隆好的最后一张图片),再进行轮播
    • 呼吸轮播图:将图片重叠放置,第一张的透明度设为1(opacity = 1),其他的透明度都设置为0

三、BOM基础

什么是BOM?

  • BOM(Browser Object Model)浏览器对象模型,是JS与浏览器窗口交互的接口

1. 窗口相关属性有哪些?

  • innerHeight:浏览器内容区域的高度(包括水平滚动条)
  • innerWidth:浏览器内容区域的宽度(包括垂直滚动条)
  • outerHeight:浏览器窗口的外部高度
  • outerWidth:浏览器窗口的外部宽度
  • document.documentElement.clientWidth:获得不包含滚动条的窗口宽度
  • window.onresize window.addEventListener('resize):窗口大小改变
  • window.scrillY:垂直方向已滚动的像素值

2.窗口卷动事件是什么?如何得到卷动值?

  • 当卷动窗口时触发事件
 window.onscroll = function(){\
 	var scrollTop = document.documentElement.scrollTop;//获取卷动值
}

3.要学会使用navigator对象、History对象、Location对象常用属性和方法

  • navigator对象,他内部包含用户此次活动的浏览器的相关属性和标识

    • appName:浏览器官方名称
    • appVersion:浏览器版本
    • userAgent:浏览器的用户代理(含有内核信息和分装壳信息)【常用来识别用户浏览器品牌】
    • platform:用户操作系统
  • history对象,提供了操作浏览器绘画窗口的接口

    • window.go(-1);等同于点击浏览器的回退按钮
    • window.back();
  • Location对象

    • 通过给这个属性赋值让浏览器进行跳转

    window.location.href = 'http://www.baidu.com'

    • 调用location的reload方法重新加载当前页面

    window.location.reload(true);
    // 参数true表示从服务器强制加载

    • 浏览器的GET请求查询参数

    console.log(window.location.search);

【跑马灯轮播图】

 跑马灯轮播图 -->
<body>
    <!-- <style>
        * {
            margin: 0;
            padding: 0;
        }
        .carousel {
            width: 650px;
            height: 360px;
            border: 1px solid #000;
            margin: 50% auto;
            position: relative;
            /* overflow: hidden; */
        }
       .carousel ul {
            list-style: none;
            width: 5000px;
            position: relative;
            transition: left .5s ease 0s;
        }
        .carousel ul li {
            float: left;
        }
        .carousel .leftbtn{
            position:absolute;
            left: 20px;
            width: 50px;
            height: 50px;
            background-color: rgb(183, 207, 235);
            border-radius: 50%;
            position: absolute;
            top: 50%;
            margin-top: -25px;
        }
        .carousel .rightbtn{
            position:absolute;
            right: 20px;
            width: 50px;
            height: 50px;
            background-color: rgb(183, 207, 235);
            border-radius: 50%;
            position: absolute;
            top: 50%;
            margin-top: -25px;
        }
    </style>
 <body>
 <head>
   跑马灯轮播图
    <div class="carousel" >
        <ul id="list">
            <li><img src="images/0.jpg" alt=""></li>
            <li><img src="images/1.jpg" alt=""></li>
            <li><img src="images/2.jpg" alt=""></li>
            <li><img src="images/3.jpg" alt=""></li>
            <li><img src="images/4.jpg" alt=""></li>
        </ul>
        <a href="javascript:;" class="leftbtn" id="leftbtn"></a>
        <a href="javascript:;" class="rightbtn" id="rightbtn"></a>
    </div>
    
    <script>
        var leftbtn = document.getElementById('leftbtn');
        var rightbtn = document.getElementById('rightbtn');
        var list = document.getElementById('list');

        //克隆第一张图片
        var cloneli = list.firstElementChild.cloneNode(true);//这里的true表示深克隆
        list.appendChild(cloneli);
        //设置一个参数,表明是第几张图片
        var idx = 0;
        var lock =true;

        leftbtn.onclick = function(){
            if(!lock) return;
            lock = false;

            //判断是不是第0张,如果是,就要用假的瞬间替换真的
            list.style.transition = 'left .5s ease 0s';
            if(idx == 0)
            {
                list.style.transition = 'none';
                list.style.left = 650 * -5 +'px';
                //设置延时器,这个延时器 的延时时间可以是0毫秒,虽然是0毫秒,但是可以让我们过渡显示取消,然后再加上
                setTimeout(function(){
                    list.style.transition ='left .5s ease 0s';
                    idx = 4;
                    list.style.left = idx * -650 + 'px';
                },0);
            }
            else {
                idx --;
                list.style.left = idx * -650 + 'px';

            }
            //函数节流
            setTimeout(function(){
                lock = true;
            },500);
            
        }

        rightbtn.onclick = function(){

            if(!lock) return;
            lock = false;
            //这里给list加过渡是因为后面取消了过渡
            list.style.transition = 'left .5s ease 0s';
            idx ++;
            if(idx > 4){
               setTimeout(function(){
                   list.style.left = 0;
                   list.style.transition = 'none';
                   idx = 0;
               },500);
            }
            list.style.left = idx * -650 + 'px';
            
            setTimeout(function(){
                lock = true;
            },500);
        }
    </script>
 </head>

【呼吸轮播图】

<head>
	<style>

        /* 呼吸轮播图 */
        * {
            margin: 0;
            padding: 0;
        }
        .carousel {
            width: 650px;
            height: 360px;
            border: 1px solid #000;
            margin: 50% auto;
            position: relative;
            /* overflow: hidden; */
        }
       .carousel ul {
            list-style: none;

            position: relative;
            /* transition: op 1s ease 0s; */
        }
        .carousel ul li {
            left: 0;
            right: 0;
            position: absolute;
            float: left;
            /* 透明度都是零 */
            opacity: 0;
            transition: opacity 1s ease 0s;
        }
        .carousel ul li:first-child {
            opacity: 1;
        }
        .carousel .leftbtn{
            position:absolute;
            left: 20px;
            width: 50px;
            height: 50px;
            background-color: rgb(183, 207, 235);
            border-radius: 50%;
            position: absolute;
            top: 50%;
            margin-top: -25px;
        }
        .carousel .rightbtn{
            position:absolute;
            right: 20px;
            width: 50px;
            height: 50px;
            background-color: rgb(183, 207, 235);
            border-radius: 50%;
            position: absolute;
            top: 50%;
            margin-top: -25px;
        }
    </style>
</head> 
<body> 
    <!-- 呼吸轮播图 -->
    <div class="carousel" >
        <ul id="list">
            <li><img src="images/0.jpg" alt=""></li>
            <li><img src="images/1.jpg" alt=""></li>
            <li><img src="images/2.jpg" alt=""></li>
            <li><img src="images/3.jpg" alt=""></li>
            <li><img src="images/4.jpg" alt=""></li>
        </ul>
        <a href="javascript:;" class="leftbtn" id="leftbtn"></a>
        <a href="javascript:;" class="rightbtn" id="rightbtn"></a>
    </div>
    
    <script>
        var leftbtn = document.getElementById('leftbtn');
        var rightbtn = document.getElementById('rightbtn');
        var list = document.getElementById('list');
        var li = document.getElementsByTagName('li');
        var pic = 0;

        var lock = true;

        leftbtn.onclick = function (){
            if(!lock) return;
            lock = false;

            li[pic].style.opacity = 0;
            pic --;
            if(pic < 0) pic = 4;
            li[pic].style.opacity = 1;

            setTimeout(function(){
                lock = true;
            },1000);
            
        }
        rightbtn.onclick = function (){
            if(!lock) return;
            lock = false;
            li[pic].style.opacity = 0;
            pic ++;
            if(pic > 4) {
                pic = 0;
            }
            li[pic].style.opacity = 1;

            setTimeout(function(){
                lock = true;
            },1000);
        }


        var arr = [];
        for(var i=0;i<5;i++){
            (function(i){
                arr.push(function(){
                    alert(i);
                })
            })(i);
        }
        arr[2]();
    </script>
<body>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值