《JavaScript_DOM编程艺术》Chapter10 动画效果 --20210509

10.1 动画基础知识

10.1.1 位置

CSS中position属性的属性值:

  • static是默认值,有关将按照它们在标记里出现的先后顺序出现在浏览器窗口里;
    relative含义与static含义相似,区别在于属性值为relative的元素可以(通过应用float属性)从文档正常的显示顺序里脱离出来;
  • 属性值为absolute的元素可以摆放到容纳它的“容器”的任何位置,这个容器要么是文档本身,要么是一个有着fixed或absolute属性的父元素,它的显示位置由top、left、right和bottom等属性决定;
  • fixed生成固定定位的元素,相对于浏览器窗口进行定位,显示位置由top、left、right和bottom等属性决定;为防止冲突,最好只使用top和bottom、left和right中的其中一个。
    #Whee.js
function positionMessage(){
     
    if (!document.getElementById) return false;
    if (!document.getElementById("message")) return false;
    var elem = document.getElementById("message");
    elem.style.position = "absolute";
    elem.style.left = "50px";
    elem.style.top = "100px";
}

function moveMessage(){
     
    if (!document.getElementById) return false;
    if (!document.getElementById("message")) return false;
    var elem = document.getElementById("message");
    elem.style.left = "200px";  
}

/*执行加载函数*/
addLoadEvent(positionMessage);
addLoadEvent(moveMessage);

#Whee.html


<html lang="en">
    <head>
        <meta charset="utf-8"/>
        <title>
            Cities
        title>
    head>
    <body>
        <p id="message">Whee!p>
        <script src="scripts/addLoadEvent.js">script>
        <script src="scripts/Whee.js">script>
    body>
html>

《JavaScript_DOM编程艺术》Chapter10 动画效果 --20210509_第1张图片

10.1.2 时间

  • setTimeout(“function()”,interval),能够让某个函数在经过一段预定的时间之后才开始执行。第一个参数通常是一个字符串,其内容是将要执行的那个函数的名字;第二个参数是一个数值,它以毫秒为单位设定了需要经过多长时间后才开始执行第一个参数所给出的函数。
  • 用clearTimeout的函数来取消“等待执行”队列里的某个函数,这个函数需要的参数就是保存着某个setTimeout函数调用返回值的变量:
variable = setTimeout("function()",interval);//声明为全局变量,可以在函数外被取消
clearTimeout(variable);

修改positionMessage函数,让它5秒之后才去调用moveMessage函数,5秒之后消失:

function positionMessage(){
     
    if (!document.getElementById) return false;
    if (!document.getElementById("message")) return false;
    var elem = document.getElementById("message");
    elem.style.position = "absolute";
    elem.style.left = "50px";
    elem.style.top = "100px";
    movement = setTimeout("moveMessage()",5000);
    
}

function moveMessage(){
     
    if (!document.getElementById) return false;
    if (!document.getElementById("message")) return false;
    var elem = document.getElementById("message");
    elem.style.left = "200px";  
}


/*执行加载函数*/
addLoadEvent(positionMessage);

《JavaScript_DOM编程艺术》Chapter10 动画效果 --20210509_第2张图片
《JavaScript_DOM编程艺术》Chapter10 动画效果 --20210509_第3张图片
#犯的错误如下:
setTimeout(“moveMessage()”,5000)写成setTimeout(“moveMessage”,5000)

10.1.3 时间递增量

parseInt(string)函数可以返回一个数字开头的字符串的整数,parseFloat(string)函数返回浮点数。
利用elem.style.left,elem.style.top实现逐渐变化的动画。
这个函数使得message元素以每次1像素的方式在浏览器窗口移动。一旦这个元素的top和left属性同时等于200px和100px,这个函数停止执行。
movement = setTimeout(“moveMessage()”,1000)可以使函数短暂停留1秒后继续执行。
#Whee.js

function moveMessage(){
     
    if (!document.getElementById) return false;
    if (!document.getElementById("message")) return false;
    var elem = document.getElementById("message");
    var xpos = parseInt(elem.style.left);
    var ypos = parseInt(elem.style.top);
    if (xpos == 200 && ypos ==100){
     
        return true;
    }
    if (xpos<200){
     
        xpos++;
    }
    if (xpos>200){
     
        xpos--;
    }
    if (ypos<100){
     
        ypos++;
    }
    if (ypos>100){
     
        ypos--;
    }
    elem.style.left = xpos + "px";
    elem.style.top = ypos + "px";
    movement = setTimeout("moveMessage",10)
}

#犯错1
函数未运动,因为movement = setTimeout(“moveMessage”,1000)应改为movement = setTimeout(“moveMessage()”,1000)。

10.1.4 抽象

将硬编码进行抽象化。注意repeat字符串的写法。
#Whee.js

function positionMessage(){
     
    if (!document.getElementById) return false;
    if (!document.getElementById("message")) return false;
    var elem = document.getElementById("message");
    elem.style.position = "absolute";
    elem.style.left = "50px";
    elem.style.top = "100px";
    moveElement("message",125,25,1000);
}

function moveElement(elementID,final_x,final_y,interval){
     
    if (!document.getElementById) return false;
    if (!document.getElementById(elementID)) return false;
    var elem = document.getElementById(elementID);
    var xpos = parseInt(elem.style.left);
    var ypos = parseInt(elem.style.top);
    if (xpos == final_x && ypos ==final_y){
     
        return true;
    }
    if (xpos<final_x){
     
        xpos++;
    }
    if (xpos>final_x){
     
        xpos--;
    }
    if (ypos<final_y){
     
        ypos++;
    }
    if (ypos>final_y){
     
        ypos--;
    }
    elem.style.left = xpos + "px";
    elem.style.top = ypos + "px";
    var repeat = "moveElement('"+elementID+"',"+final_x+","+final_y+","+interval+")";
    movement = setTimeout(repeat,interval);
}

/*执行加载函数*/
addLoadEvent(positionMessage);

#犯错函数未运动,因为引号和var没给对。

错误的示范
repeat = "moveElement('+elementID+','+final_x+','+final_y+','+interval+')";

正确的示范
var repeat = "moveElement('"+elementID+"',"+final_x+","+final_y+","+interval+")";

10.2 实用的动画

根据用户的行为移动一个页面元素起到增强网页的效果。
我们要做的事情:为所有的预览图片生成一张“集体照”形式的图片。隐藏这张“集体照”图片的绝大部分。当用户用鼠标悬停在某个链接上方时,只显示“集体照”图片的相应部分。

10.2.2 HTML

以下显示的是完整的“集体照”。
#list.html


<html lang="en">
    <head>
        <meta charset="utf-8"/>
        <title>Designtitle>
        <link rel="stylesheet" href="styles/layout.css" media="screen">
    head>
    <body>
        <h1>Designh1>
        <p>These are the things you should know.p>
        <ol id="linklist">
            <li><a href="structure.html">Structurea>li>
            <li><a href="presentation.html">Presentationa>li>
            <li><a href="behavior.html">Behaviora>li>
        ol>
        <div id="slideshow">
            <img src="images/topics.gif" alt="building blocks of web design" id="preview"/>
        div>
        <script src="scripts/addLoadEvent.js">script>
        <script src="scripts/moveElement.js">script>
        <script src="scripts/prepareSlideshow.js">script>
    body>
html>

《JavaScript_DOM编程艺术》Chapter10 动画效果 --20210509_第4张图片

10.2.3 CSS

CSS的overflow属性用来处理一个元素的尺寸。
overflow属性的可取值有4种:visible, hidden, scroll, auto

  • visible:不裁剪溢出的内容。浏览器将把溢出的内容呈现在其容器元素的显示区域以外,全部内容可见。
  • hidden:隐藏溢出的内容。内容只显示在其容器元素的显示区域里,只有一部分内容可见。
  • scroll:类似于hidden,浏览器将对溢出的内容进行隐藏,但显示一个滚动条以便让用户能够滚动看到内容。
  • auto:类似于scroll,但浏览器只在确实发生溢出时才显示滚动条。如果内容没有溢出,就不显示滚动条。

#layout.css

#slideshow{
     
    width: 150px;
    height: 100px;
    position: relative;
    overflow: hidden;
}

JavaScript包含

JavaScript包含 10.2.4 JavaScript, 10.2.5 变量作用域问题,10.2.6 改进动画效果,10.2.7 添加安全检查,10.2.8 生成HTML标记。

10.2.4 JavaScript

#prepareSlideshow.js

function prepareSlideshow(elementID,final_x,final_y,interval){
     
    //安全检查
    if (!document.getElementById) return false;
    if (!document.getElementsByTagName) return false;
    if (!document.getElementById("linklist")) return false;
    if (!document.getElementById("preview")) return false;
    //为图片应用样式
    var preview = document.getElementById("preview");
    preview.style.position = "absolute";
    preview.style.left = "0px";
    preview.style.top = "0px";
    //取得列表中的所有链接
    var list = document.getElementById("linklist");
    var links = list.getElementsByTagName("a");
    //为mouseover事件添加动画效果
    links[0].onmouseover = function(){
     
        moveElement("preview",-150,0,10);
    }
    links[1].onmouseover = function(){
     
        moveElement("preview",-300,0,10);
    }
    links[2].onmouseover = function(){
     
        moveElement("preview",-450,0,10);
    }
}


/*执行加载函数*/
addLoadEvent(prepareSlideshow);

10.2.5 变量作用域问题

动画效果不正确的问题是由moveElement.js的一个全局变量movement引起的。
不管moveElement函数正在移动的是哪个元素,该元素都将获得一个名为movement的属性。如果该元素在moveElement函数开始执行之前已有一个moveElement属性,就应该用clearTimeout函数对它进行复位。
JavaScript允许我们自行创建属性,如element.property = value;
#moveElement.js

function moveElement(elementID,final_x,final_y,interval){
     
    if (!document.getElementById) return false;
    if (!document.getElementById(elementID)) return false;
    var elem = document.getElementById(elementID);
    //清除已累积的movement
    if (elem.movement){
     
        clearTimeout(elem.movement);
    }
    var xpos = parseInt(elem.style.left);
    var ypos = parseInt(elem.style.top);
    if (xpos == final_x && ypos ==final_y){
     
        return true;
    }
    if (xpos<final_x){
     
        xpos++;
    }
    if (xpos>final_x){
     
        xpos--;
    }
    if (ypos<final_y){
     
        ypos++;
    }
    if (ypos>final_y){
     
        ypos--;
    }
    elem.style.left = xpos + "px";
    elem.style.top = ypos + "px";
    var repeat = "moveElement('"+elementID+"',"+final_x+","+final_y+","+interval+")";
    elem.movement = setTimeout(repeat,interval);
}

#犯错:
clearTimeout(elem.movement)写成了clearTimeout(elem.moveElement);导致图片不断抖动。

10.2.6 改进动画效果

改变移动速度。
#moveElement.js

function moveElement(elementID,final_x,final_y,interval){
     
    if (!document.getElementById) return false;
    if (!document.getElementById(elementID)) return false;
    var elem = document.getElementById(elementID);
    //清除已累积的movement
    if (elem.movement){
     
        clearTimeout(elem.movement);
    }
    var xpos = parseInt(elem.style.left);
    var ypos = parseInt(elem.style.top);
    if (xpos == final_x && ypos ==final_y){
     
        return true;
    }
    if (xpos<final_x){
     
        dist = Math.ceil((final_x - xpos)/10);
        xpos = xpos+dist;
    }
    if (xpos>final_x){
     
        dist = Math.ceil((xpos - final_x)/10);
        xpos = xpos-dist;
    }
    if (ypos<final_y){
     
        dist = Math.ceil((final_y-ypos)/10);
        ypos = ypos+dist;
    }
    if (ypos>final_y){
     
        dist = Math.ceil((ypos-final_y)/10);
        ypos = ypos-dist;
    }
    elem.style.left = xpos + "px";
    elem.style.top = ypos + "px";
    var repeat = "moveElement('"+elementID+"',"+final_x+","+final_y+","+interval+")";
    elem.movement = setTimeout(repeat,interval);
}

10.2.7 添加安全检查

假设elem元素肯定有一个left样式属性和一个top样式属性,设为默认值。

    if (!elem.style.left){
     
        elem.style.left="0px";
    }
    if (!elem.style.top){
     
        elem.style.top="0px";
    }

10.2.8 生成HTML标记

生成以下HTML标记。

        <div id="slideshow">
            <img src="images/topics.gif" alt="building blocks of web design" id="preview"/>
        div>

《JavaScript_DOM编程艺术》Chapter10 动画效果 --20210509_第5张图片
#prepareSlideshow.js

function prepareSlideshow(elementID,final_x,final_y,interval){
     
    //安全检查
    if (!document.getElementById) return false;
    if (!document.getElementsByTagName) return false;
    if (!document.getElementById("linklist")) return false;
    //if (!document.getElementById("preview")) return false;
    //为图片应用样式,并不意味着出现在浏览器的左上角,而是容器的左上角
    //var preview = document.getElementById("preview");
    //preview.style.position = "absolute";
    //preview.style.left = "0px";
    //preview.style.top = "0px";
    var slideshow = document.createElement("div");
    slideshow.setAttribute("id","slideshow");
    var preview = document.createElement("img");
    preview.setAttribute("src","image/topics.gif");
    preview.setAttribute("alt","building blocks of web design");
    preview.setAttribute("id","preview");
    slideshow.appendChild(preview);
    //取得列表中的所有链接
    var list = document.getElementById("linklist");
    insertAfter(slideshow,list);
    var links = list.getElementsByTagName("a");
    //为mouseover事件添加动画效果
    links[0].onmouseover = function(){
     
        moveElement("preview",-150,0,10);
    }
    links[1].onmouseover = function(){
     
        moveElement("preview",-300,0,10);
    }
    links[2].onmouseover = function(){
     
        moveElement("preview",-450,0,10);
    }
    
}

/*执行加载函数*/
addLoadEvent(prepareSlideshow);

#layout.css

删除以下
preview.style.position = "absolute";

新增
#preview{
     
	position:absolute;
}

#犯错:未引入insertAfter.js

<script src="scripts/insertAfter.js">script>

你可能感兴趣的:(笔记)