search

Home  >  Q&A  >  body text

javascript - How will the object pointed to by this change in nested functions?

I wrote a demo whose function is that when the mouse moves in, the length of the rectangular block becomes longer, and then the height becomes higher. I encountered the following problems:

When executing the following function nesting

    op[0].onmouseover = function(){
        that = this;
        changeStyle(that,'width',400,function(){
            changeStyle(that,'height',300);
        });
    }

You must use that=this to pass parameters, otherwise the browser will report the following error

Uncaught TypeError: Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'.

I posted the entire code at the end. I want to know why using that=this to pass parameters can solve the problem? If no parameters are passed, who does this point to twice? Is there any good debugging method in Chrome and Firefox that can monitor every change of this value and display it?

html code:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>animation</title>
    <link rel="stylesheet" href="animation.css" />
</head>
<body>
    <p class="wrap"></p>
    <script src="animation.js"></script>
</body>
</html>

css code:

.wrap{
    width: 200px;
    height: 100px;
    margin: 10px;
    background-color: #f00;
    border: 4px solid black;
}

js code:

window.onload = function(){
    var op = document.getElementsByTagName('p');
    op[0].timer = null;
    op[0].onmouseover = function(){
        that = this;
        changeStyle(that,'width',400,function(){
            changeStyle(that,'height',300);
        });
    }
}
function changeStyle(obj,attr,iTarget,fn){
    clearInterval(obj.timer);
    var curValue = 0;
    obj.timer = setInterval(function(){
        curValue = parseInt(getStyle(obj,attr));
        var speed = (iTarget - curValue) / 20;
        speed = (speed > 0) ? Math.ceil(speed) : Math.floor(speed);
        if (curValue == iTarget) {
            clearInterval(obj.timer);
            if (fn) {
                fn();
            }
        }
        else{
            obj.style[attr] = curValue + speed + 'px';    
        }
    },30);
}
function getStyle(obj,attr){
    if (obj.currentStyle) {
        return obj.currentStyle[attr];
    }
    else{
        return getComputedStyle(obj,null)[attr];
    }
}
習慣沉默習慣沉默2754 days ago667

reply all(5)I'll reply

  • 黄舟

    黄舟2017-05-19 10:12:31

    The this of the function called through the event points to the element that triggered the event, so the this of the function called by the op[0].onmouseover event points to op[0];

    The this of the callback function passed in by the changeStyle function points to the window, because if (fn) { fn();} is equivalent to the window calling the function

    If you want to track the execution of the code, you can use breakpoint debugging to see the assignment of each variable during operation

    reply
    0
  • 我想大声告诉你

    我想大声告诉你2017-05-19 10:12:31

    This represents an internal object automatically generated when the function is running and can only be used inside the function.
    As the function is used in different situations, the value of this will change. But there is a general principle, that is, this refers to the object that calls the function. I think you can read this article by Ruan Yifeng: http://www.ruanyifeng.com/blo...

    reply
    0
  • 曾经蜡笔没有小新

    曾经蜡笔没有小新2017-05-19 10:12:31

    Forget the worries of thispointing, (es6) please use arrow functions

    reply
    0
  • PHP中文网

    PHP中文网2017-05-19 10:12:31

    If you don’t pass that, do you know whose style your change function changes? If you use this directly, this points to the window. As mentioned on the first floor, you will know the breakpoint as soon as you break it

    reply
    0
  • 给我你的怀抱

    给我你的怀抱2017-05-19 10:12:31

    If you do not use that=this to bind this to the current lexical scope, then this points to the global object window, which is the default binding of this.

    reply
    0
  • Cancelreply