zoukankan      html  css  js  c++  java
  • 【DOM编程艺术】实时动画---幻灯片

    onmouseover事件被触发时显示一张图片。我们将沿用图片库案例中的脚本----只需把每个链接上的事件处理函数从onclikc改为onmouseover。它能工作,但图片显示得不够流畅:当用户第一次把鼠标指针悬停在某个链接上时,新图片将被加载过去。

    即使实在一个高速的网络连接上,这多少也需要花费点儿时间,而我们希望能够立刻响应。

    解决问题:如果为每个链接分别准备一张预览图片,在切换显示这些图片时总会有一些延迟。除此之外,简单地切换显示这些图片也不是我们期望的效果。我们想要的是一种更快更好的东西。

         下面是我们要做的事情。

          ■ 为所有的预览图片生成为一张"集体照"形式的图片。

          ■ 隐藏这张"集体照"图片的绝大部分。

          ■ 当用户把鼠标指针悬停在某个链接的上方时,只显示这张"集体照"图片的相应部分。

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Web Design</title>
    <style type="text/css">
    #slideshow{width:100px; height:100px; position:relative; overflow:hidden;}
    </style>
    </head>
    
    <body>
    <h1>Web Design</h1>
    <p>These are the things you should know.</p>
    <ol id='linklist'>
        <li><a href="structure.html">Structure</a></li>
        <li><a href="presentation.html">Presentation</a></li>
        <li><a href="behavior.html">Behavior</a></li>
    </ol>
    <div id='slideshow'>
        <img src="images/topics.gif"  alt='building blocks of web design' id='preview' />
    </div>
    <script>
    window.onload = prepareSlideshow;
    function prepareSlideshow(){
        /*为图片应用样式*/
        var preview = document.getElementById('preview');
        preview.style.position = 'absolute';
        preview.style.left = '0px';
        preview.style.top = '0px';
        var list = document.getElementById('linklist');
        var item = list.getElementsByTagName('a');
        item[0].onmouseover = function(){
              moveElement('preview',-100,0,10);
        }
        item[1].onmouseover = function(){
              moveElement('preview',-200,0,10);
        }
        item[2].onmouseover = function(){
              moveElement('preview',-300,0,10);
        }
    }
    function moveElement(elementId,final_x,final_y,interval){
        if( !document.getElementById) return false;
        if( !document.getElementById(elementId)) return false;
        var elem = document.getElementById(elementId);
        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,10);
    }
    
    </script>
    </body>
    </html>

     绿色代码不存在的情况下,事情好像有点不太对头:如果把鼠标指针在链接之间快速地来回移动,动画效果将变得混乱起来。

    解析:动画效果不正确的问题是由一个全局变量引起的。

       这留下了一个隐患:每当用户把鼠标指针悬停在某个链接上,不管上一次调用是否已经把图片移动到位,moveElement函数都会被再次调用并试图把这个图片移动到另一个地方去。于是,当用户在链接之间快速移动鼠标时,movement变量就会像

                一条拔河绳那样来回变化,而moveElement函数就会试图把图片同时移动到两个不同的地方去。

       如果用户移动鼠标的速度够快,积累在setTimeout队列里的事件就会导致动画效果产生滞后。为了消除动画滞后的现象,可以用clearTimeout消除积累在setTimeout队列里的事件:

       clearTimeout(movement);

       可是,如果在还没有设置movement变量之前就执行这条语句,我们会收获一个错误。

       我不能使用局部变量:var movement = setTimeout(repeat,interval);

       如果这样做,clearTimeout函数调用语句将无法工作,因为局部变量movement在clearTimeout函数的上下文里不存在。

         也就是说,既不能使用全局变量,也不能使用局部变量。我们需要一种介乎它们二者之间的东西,需要一个只与正在被移动的那个元素有关的变量。

       只与某个特定元素有关的变量是存在的。事实上,我们一直在使用它们。那就是"属性"。

       到目前为止,我们一直在使用由DOM提供的属性,如element.firstChild、elemen.style等等。Javascript允许我们为元素创建属性:element.property = value;

       例:element.foo = 'bar'; 这很像是在创建一个变量,但区别是这个变量专属于某个特定的元素。

       我们把变量movement从一个全局变量改变为正在被移动的那个元素(elem元素)的属性。

    最终效果:于是,不管moveElement函数正在移动的是哪个元素,该元素都将获得一个名为movement的属性。如果该元素在moveElement函数开始执行时已经有了一个movement属性,就应该用clearTimeout函数对它进行复位。

                  这样一来,即使因为用户快速移动鼠标指针而使得某个元素需要向不同的方向移动,实际执行的也只有一条setTimeout函数调用语句。

  • 相关阅读:
    pl/sql 编程!
    oracle中的常用函数、字符串函数、数值类型函数、日期函数,聚合函数。
    oracle 相关查询和非相关查询,oracle 去除重复数据,以及oracle的分页查询!
    初识 oracle!
    分页查询。
    利用ajax技术 实现用户注册。
    quartz CronExpression
    SQL 面试题
    什么是HTTP协议?常用的状态码有哪些?
    聚集索引与非聚集索引
  • 原文地址:https://www.cnblogs.com/positive/p/3680997.html
Copyright © 2011-2022 走看看