3

我刚刚开始使用模块模式(感谢 Christian Heilmann 的原始教程)来组织我的 jQuery,我遇到了一个奇怪的问题。考虑以下 javascript 代码:

var Gallery = function(){

  var $obj, $thumbs, $mainPic;

  function init($e){

    $obj = $e;
    $thumbs = $obj.find('.thumbnail');
    $mainPic = $obj.find('.main-pic');

    $obj.find($thumbs).bind('click',updateMainPic);

  };

  function updateMainPic() {
    $thumbs.removeClass('selected');
    $thumb = $thumbs.filter(this);
    $thumb.addClass('selected');
    newPicUrl = $thumb.data('src');    
    $mainPic.attr('src',newPicUrl);    
  };

  return {
    init:init
  }

}();

以下 HTML 中包含和使用的内容:

<div id="gallery1">
  <img src="" class="main-pic">
  <ul>
    <li class="thumbnail" data-src="photo1.jpg">Photo 1</li>
    <li class="thumbnail" data-src="photo2.jpg">Photo 2</li>
    <li class="thumbnail" data-src="photo3.jpg">Photo 3</li>
    <li class="thumbnail" data-src="photo4.jpg">Photo 4</li>
  </ul>
</div>
<script type="text/javascript">
  Gallery.init($('#gallery1'));
</script>

<div id="gallery2">
  <img src="" class="main-pic">
  <ul>
    <li class="thumbnail" data-src="photo1.jpg">Photo 1</li>
    <li class="thumbnail" data-src="photo2.jpg">Photo 2</li>
    <li class="thumbnail" data-src="photo3.jpg">Photo 3</li>
    <li class="thumbnail" data-src="photo4.jpg">Photo 4</li>
  </ul>
</div>
<script type="text/javascript">
  Gallery.init($('#gallery2'));
</script>

我遇到的问题是单击#gallery1 上的缩略图正在交换#gallery2 的图像,但#gallery2 正在按预期工作。看起来 $obj 变量在实例之间共享,但我认为它的范围仍然是函数的私有实例。

任何有关如何正确确定范围和工作的建议都将不胜感激。

4

3 回答 3

4

问题是 Gallery 是一个单例。在调用第二个 init 的那一刻,您正在替换内部 $obj 变量。

在这种情况下,我不会使用模块模式。如果您仍然使用 jQuery,编写 jQuery 插件(简单)或 jQuery UI 小部件(非常擅长维护状态)会更容易。

于 2011-08-29T22:10:09.220 回答
0

我在你的场景中玩了一段时间,试图看看是否可以使用 moduler 模式;并且看起来在绑定过程中出现了一个巨大的障碍。在 updateMainPic() 函数中确定“this”的范围变得非常困难。即使使用像underscore.js这样功能强大的库,以及它们的 _.bind() 函数允许对对象进行竞价,也无法轻松克服这种情况。

就像 Mike 提到的那样,插件或小部件会让这个特定的任务变得微不足道:

$('li.thumbnail').bind('click', function() {
    $(this).closest('div').find('.main-pic').attr('src', $(this).attr('data-src'));
    $(this).addClass('selected');
    $(this).siblings().removeClass('selected');
});
于 2011-08-30T04:55:21.443 回答
0

模块模式更适合单例使用。每次调用 init 方法时,都会将 $obj 变量重新指向传递的 $e。因此只需将 $obj 移至其他两个到 init 中并将三个参数传递给 updateMainPic。如果您需要基于实例的指针,那么让您的单例返回一个原型函数,您可以创建实例并直接绑定到您的 dom 单击事件。

于 2011-09-01T13:51:37.910 回答