javascript 全局变量与属性的区别?

JS DOM 编程艺术的一道题目

HTML:

<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">Behavior</a> </li> 
  </ol> 
  <div id="slideshow"> 
   <img src="img/topics.gif" alt="" id="preview" /> 
  </div> 
  <script src="js/addLoadEvent.js"></script> 
  <script src="js/moveElement.js"></script> 
  <script src="js/prepareSlideshow.js"></script> 
 </body>

CSS:

#slideshow {
    width: 100px;
    height: 110px;
    border: 5px solid yellowgreen;
    position: relative;
    overflow: hidden;
}

#preview {
    border: 5px solid red;
}

JS:
prepareSlideshow.js:

function prepareSlideshow() {
    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.top = "0px";
    preview.style.left = "0px";

    var list = document.getElementById("linklist");
    var links = list.getElementsByTagName("a");

    links[0].onmouseover = function() {
        moveElement("preview", -100, 0, 1);
    }
    links[1].onmouseover = function() {
        moveElement("preview", -200, 0, 1);
    }
    links[2].onmouseover = function() {
        moveElement("preview", -300, 0, 1);
    }
}
addLoadEvent(prepareSlideshow);

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);

    if (movement) {
        clearTimeout(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 + ")";

    movement = setTimeout(repeat, interval);
}

题目很长,谢谢耐心看到这。
我的问题是:书中说,moveElement.js中的clearTimeout函数清除积累在setTimeout队列里的事件。「可是如果在还没设置movement变量之前就执行这条语句,我们会收获一个错误.」
——对上面这句话,我的理解是:

if (movement) {
        clearTimeout(movement);
    }

由于写在开头,而movement在函数末尾才会设置。可是,if语句并不会由于movement不存在而报错啊? 顶多是判断不存在,而使得clearTimeout函数没有起到作用而已。
<我跑了代码,发觉确实程序无法执行我们的预定目标>
书中说,movement作为全局变量会导致上面的问题,而设置为局部变量也不行。那么就需要一种介乎全局变量局部变量之间的东西,即只与正在被移动的哪个元素有关的变量。答案是:"属性".
将开头设置为

if (elem.movement) {
        clearTimeout(elem.movement);
    }

结尾设置为:

elem.movement = setTimeout(repeat, interval);

即可。
我照样试了下,确实程序正常运行了,可是为什么?elem.movement在函数开头部分一样不存在啊,clearTimeout 一样无法正常得到入参而运行啊?
菜鸟求大大们解答。

阅读 2.3k
2 个回答

刚才看了下书本元内容。书中首先说不能使用全局变量movement,这是因为多个元素的动画使用同一个全局变量,快速的来回切换元素会造成动画的混乱。所以这时候只能考虑局部变量了,而局部变量在var movement = setTimeout(repeat, interval)之前是不能对movement做任何操作的,这会抛出一个错误。这是书中所要说的。

对于你这里,你把movemen变成了一个全局变量,所以他不会抛出错误。但是他会引起动画的混乱,在快速切换元素时。

它的意思是moveElement没申明 所以会报错 代码就执行不下去了

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题