【问题标题】:jQuery closures and event function (mouseover, mouseout, ...)jQuery 闭包和事件函数 (mouseover, mouseout, ...)
【发布时间】:2011-07-29 22:52:45
【问题描述】:

我正在努力了解如何将闭包与 jQuery 事件函数结合使用。

我目前的问题是在屏幕上圆形形状,使它们在鼠标悬停时停止并淡出,并在鼠标移出时淡出并重新启动。我必须使用图像映射来创建圆形鼠标悬停敏感区域。虽然动画效果很好,但我无法按照我的意愿使用鼠标悬停功能上的闭包。

鉴于此设置:

(function($){
  $.fn.xyz = function( option ) {
    // override defaults with specified option
    option = $.extend( {}, $.fn.xyz.option, option );

  return this.each(function(index, element) {
            // run works fine.
            function run(index) {
                $(".ball:eq(" + index + ")").css({top: 500).startAnimation({ top: -500}, 1000, "linear", (function (i) {
                    return function() {
                        run(i);
                }})(index));
            }

            //1 this version works great but I don't like the .parent().parent() especially as the animation requires 
            // just the ball I hover over gets the opacity assigned
            $("area").mouseover(
                function () {$(this).parent().parent().css('opacity', 0.5);}
            );

            //2 this version makes all balls transparent on page load
            $("area").mouseover(
                (function (activeElement) {
                    $(activeElement).css('opacity', 0.5);
                })(this)
            );

            //3 this version makes all balls transparent on the first mouse over event 
            $("area").mouseover(
                (function (activeElement) {
                    return function() {
                        $(activeElement).css('opacity', 0.5);
                    }
                })(this)
            );

            //4 also this version affecs all balls and not just the one that is mouse overed
            var activeBall = $(this);
            $("area").mouseover(function () {
                $(activeBall).css('opacity', 0.5);
            }).mouseout(function () {
                $(activeBall).css('opacity', 1);
            });

            run(index);
        });
    },

    $.fn.xyz.option = {};
})(jQuery);

为什么版本 2、3 和 4 以所有元素为目标,而不仅仅是主动悬停的元素。我将如何使用闭包来避免使用索引或类似的解决方法?

非常感谢!

【问题讨论】:

    标签: javascript jquery events closures


    【解决方案1】:

    您将其设为自调用匿名函数。基本上,使用 jQuery 对象自动调用它。您还将函数包装在函数中……我不明白。这应该有效:

    (function($){
      $.fn.xyz = function( option ) {
        // override defaults with specified option
        option = $.extend( {}, $.fn.xyz.option, option );
    
      return this.each(function(index, element) {
                // run works fine.
                function run(index) {
                    $(".ball:eq(" + index + ")").css({top: 500).startAnimation({ top: -500}, 1000, "linear", (function (i) {
                        return function() {
                            run(i);
                    }})(index));
                }
    
                //1 this version works great but I don't like the .parent().parent() especially as the animation requires 
                // just the ball I hover over gets the opacity assigned
                $("area").mouseover(
                    function () {$(this).parent().parent().css('opacity', 0.5);}
                );
    
                //2 this version makes all balls transparent on page load
                $("area").mouseover(
                    (function (activeElement) {
                        $(activeElement).css('opacity', 0.5);
                    })
                );
    
                //3 this version makes all balls transparent on the first mouse over event 
                $("area").mouseover(
                    (function (activeElement) {
                        return function() {
                            $(activeElement).css('opacity', 0.5);
                        }
                    })
                );
    
                //4 also this version affecs all balls and not just the one that is mouse overed
                var activeBall = $(this);
                $("area").mouseover(function () {
                    $(activeBall).css('opacity', 0.5);
                }).mouseout(function () {
                    $(activeBall).css('opacity', 1);
                });
    
                run(index);
            });
        },
    
        $.fn.xyz.option = {};
    })(jQuery);
    

    基本上,SIAF 正在做这样的事情:

    (function(txt) { alert(txt); })('Hello world!');

    你声明一个匿名函数(它没有名字),它接受一个参数,然后在末尾的括号中调用它,括号中的就是函数的参数。

    所以,当你说

            (function (activeElement) {
                return function() {
                    $(activeElement).css('opacity', 0.5);
                }
            })(this)
    

    编译器看到“以 this 对象作为参数激活函数”。看到这将如何在您声明的函数之外引用 jQuery 对象,jQuery 将其视为“使用 .css 函数更改我拥有的所有元素”。

    【讨论】:

    • 谢谢!您的回答解释了为什么在第二种情况下,所有元素在页面加载时都设置为不透明度 0.5。我已经弄清楚为什么所有元素都是目标。我应该使用 $(this).find("area").mouseover( (function (activeElement) { return function() { $(activeElement).css('opacity', 0.5); } }) );仅针对当前元素的区域。在上面的代码中,它确实将它分配给了所有元素。完全有道理,我的错!
    • 没问题。记得点击空白勾选接受答案(表明问题已解决。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-13
    • 1970-01-01
    • 2011-09-24
    • 1970-01-01
    • 1970-01-01
    • 2011-03-03
    • 1970-01-01
    相关资源
    最近更新 更多