【问题标题】:Function variable closure函数变量闭包
【发布时间】:2012-03-05 05:16:15
【问题描述】:

这是一个简单的滑块代码,我想了解可变函数闭包是如何工作的......

(function($) {
var sliderUL = $('div.slider').css('overflow', 'hidden').children('ul'),
    imgs = sliderUL.find('img'),
    imgWidth = imgs[0].width, // 600
    imgsLen = imgs.length, // 4
    current = 1,
    totalImgsWidth = imgsLen * imgWidth; // 2400

$('#slider-nav').show().find('button').on('click', function() {
    var direction = $(this).data('dir'),
        loc = imgWidth; // 600

    // update current value
    **( direction === 'next' ) ? ++current : --current;
    // if first image
    if ( current === 0 ) {
        current = imgsLen;
        loc = totalImgsWidth - imgWidth; // 2400 - 600 = 1800
        direction = 'next';
    } else if ( current - 1 === imgsLen ) { // Are we at end? Should we reset?
        current = 1;
        loc = 0;
    }
    transition(sliderUL, loc, direction);**
});

function transition( container, loc, direction ) {
    var unit; // -= +=

    if ( direction && loc !== 0 ) {
        unit = ( direction === 'next' ) ? '-=' : '+=';
    }

    container.animate({
        'margin-left': unit ? (unit + loc) : loc
    });
}

})(jQuery);

在这部分:

    $('#slider-nav').show().find('button').on('click', function() {
    var direction = $(this).data('dir'),
        loc = imgWidth; // 600

    // update current value
    ( direction === 'next' ) ? ++current : --current;

    // if first image
    if ( current === 0 ) {
        current = imgsLen;
        loc = totalImgsWidth - imgWidth; // 2400 - 600 = 1800
        direction = 'next';
    } else if ( current - 1 === imgsLen ) { // Are we at end? Should we reset?
        current = 1;
        loc = 0;
    }

    transition(sliderUL, loc, direction);
});

在if(current === 0)块中,变量current、loc、direction是不是在第一个块中改变后更新了,然后传递给下面的transition函数?

我认为如果 else if ( current - 1 === imgsLen ) 为真,那么 current 和 loc 会覆盖之前分配给它们的值,然后传递给转换函数?

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:

    directionloc 是在“点击”回调函数的范围内定义的。每次调用回调函数时,它们都会被初始化——每次点击。 direction 由与按钮关联的“数据目录”初始化,loc 被初始化为imgWidth 的当前值(这是在主函数范围内定义的变量)。

    初始化后,directionloc 可以通过if-else if 逻辑进行修改,然后将它们传递给函数transition()。 (注意sliderIU 也被传递给transition(),但这不是必需的,因为它具有您的主函数的范围,并且可以直接在transition() 中使用,而无需作为参数container 传递。但是它可能将它作为参数传递并不是一个坏主意,因为当您可以从函数的参数中看到它所作用的值时,它会产生更清晰的编程风格。)

    在回调单击函数中使用的变量current 未定义在该回调单击函数的范围内,但具有主函数范围(在主函数开头定义)。这是必要的,因为您希望在每次单击按钮时更改其值——并记住更改。回调点击函数是一个闭包,因为它可以访问(读+写)外部变量current。变量directionloc 与闭包无关;它们只是传递给函数的变量。

    【讨论】:

      【解决方案2】:

      您突出显示的代码的步骤如下: - 从被点击的按钮中获取 'dir' 的值 - 将 loc 的默认值设置为图像的宽度 (imgWidth) - 如果方向是“下一个”,则将 1 加到当前,否则从当前减去 1

      现在,此时,我们可能会遇到一种情况,即 current 可能为 0 或 imgLen + 1。其中任何一个都不是一个好的值。所以我们执行以下操作 - 如果电流为 0 - 将当前设置为 imgsLen(转到最后一张图片) - 将 loc 设置为最大可能的有效值 - 设置方向 = '下一个' - 如果当前超出最后一个图像 - 设置 current = 0(转到第一张图片) - 将 loc 设置为 0(可能的最小有效值) - 使用更新的参数值调用转换函数

      希望这能回答你的问题。

      【讨论】:

      • 是的!这意味着根据满足的条件,这些变量将设置为这些值,然后将这些值插入到转换滑块中。谢谢阿米特!
      猜你喜欢
      • 1970-01-01
      • 2013-04-24
      • 2013-04-24
      • 2021-05-28
      • 2022-01-24
      • 2014-12-04
      • 2012-04-01
      • 2012-08-28
      • 2016-12-12
      相关资源
      最近更新 更多