3

我对 JavaScript 和 jQuery 非常陌生,并且遇到了一些代码问题。

HTML:

<div class="toggle" style="display: block; width: 200px; height: 200px; background-color: red;">test</div>

JavaScript:

jQuery(document).ready(
    function()
    {
        jQuery(".toggle").on("click", function() {
            console.log("let the toggling begin!");

            jQuery(this).slideToggle(600, function(){ // slide up
                setTimeout(function(){ // wait 4 sec, then slide back down
                    jQuery(this).slideToggle(600)
                }, 4000);
            });
        });
    }
);

所以想法是你点击 div,它向上滑动,然后 4 秒后又向下滑动。它不起作用。

JSFIDDLE:http: //jsfiddle.net/zEqN9/2/

但是,如果我将this每个闭包的内部更改为".toggle",那么它确实有效。

JSFIDDLE:http: //jsfiddle.net/YZxMb/

很明显,问题是我对this.

我尝试将this作为参数传递给两个闭包函数中的每一个,但这给出了错误Unexpected token this

如何this从内部函数访问变量?

4

6 回答 6

6

this在 slideToggle 函数中创建一个引用。

 jQuery(document).ready(
    function()
    {
        jQuery(".toggle").on("click", function() {
            console.log("let the toggling begin!");

            jQuery(this).slideToggle(600, function(){ // slide up
                var self = this; // <-- notice this
                setTimeout(function(){ // wait 4 sec, then slide back down
                    jQuery(self).slideToggle(600)
                }, 4000);
            });
        });
    }
);
于 2013-09-04T13:20:39.707 回答
1

用于为您希望在上下文之外调用的函数bind指定 a 。this

var foo = {
    bar: function () {
        setTimeout(function () { // though in a setTimeout
            console.log(this);
        }.bind(this), 0); // binding to `this` here means
    }
};

foo.bar(); // invoking it still has `this` of `foo`
于 2013-09-04T13:19:23.377 回答
0

原因是对于 jQuery 事件,函数的上下文是显式设置的,以便this引用目标元素 - 这是由 jQuery 为您完成的。但是,匿名函数 forsetTimeout没有为您设置该上下文 - 它获取默认的全局上下文,因此this指的是窗口。

您需要做的是获取对单击事件上下文的引用,然后在超时中使用该引用:

jQuery(function () {
    jQuery(".toggle").on("click", function () {
        var $this = $(this);

        $this.slideToggle(600, function () { // slide up
            setTimeout(function () { // wait 4 sec, then slide back down
                $this.slideToggle(600);
            }, 4000);
        });
    });
});

但是,正如评论中指出的那样,这可以写成:

jQuery(function () {
    jQuery(".toggle").click(function () {
        jQuery(this).slideToggle(600).delay(4000).slideToggle(600);
    });
});
于 2013-09-04T13:19:38.623 回答
0
var yourThing = jQuery(this);

yourThing.slideToggle(600, function(){ // slide up
     setTimeout(function(){ // wait 4 sec, then slide back down
          yourThing.slideToggle(600)
     }, 4000);
});
于 2013-09-04T13:20:22.207 回答
0

只需在代码中添加这一行即可了解原因:

setTimeout(function(){ // wait 4 sec, then slide back down
      console.log(jQuery(this)); //this one
      jQuery(this).slideToggle(600)
      }, 4000);

打开你的控制台。您会看到,在setTimeout函数中,$(this) 指的是窗口对象。

于 2013-09-04T13:20:46.157 回答
0

您需要为此创建一个引用,因此当运行与 setTimeout 关联的函数时,您可以传递此引用。

 jQuery(document).ready(
        function()
        {
            jQuery(".toggle").on("click", function() {
                console.log("let the toggling begin!");
                var that = this; // <--- reference to this
                jQuery(this).slideToggle(600, function(){ // slide up
                    setTimeout(function(){ // wait 4 sec, then slide back down
                        jQuery(that).slideToggle(600)
                    }, 4000);
                });
            });
        }
    );
于 2013-09-04T13:25:43.227 回答