1

我需要一些指导来理解为什么这些功能正在做他们正在做的事情......

1.) 在我的网页上,我有三个使用 Slider 功能的不同面板,它使用下一个和上一个锚链接创建一个具有滑块功能的无序列表。请看下面的代码:

function Slider(id) {
    var _this = this;
    this.id = id;
    if (!id) return false;
    this.index = 0;
    this.slider = $(this.id);
    this.length = this.slider.children().length;
    this.width = $(this.id).outerWidth();
    this.totalWidth = this.length * this.width;
    $(id).addClass('slideWrapper').wrap('<div class="slideViewport">').after('<div class="sliderNav"><a href="#" class="prev">Previous</a><a href="#" class="next">Next</a></div>').css({
      'width': this.totalWidth
  }).children().addClass('slide').css({
      'width': this.width
  });

  $('.slideViewport a.next').click(function(e) {
    e.preventDefault();
    return _this.next();
  });

  $('.slideViewport a.prev').on(function(e) {
    e.preventDefault();
    return _this.prev();
  });
}

如果我尝试在一个页面上运行多个这样的 Slider 实例,单击 .next 锚点将导致单击的元素及其下方的任何元素在其幻灯片中更多到下一个列表元素。转到第二个面板将导致除第一个面板之外的所有面板运行,第三个面板导致除第一个和第二个面板之外的所有面板运行,依此类推。我希望处理程序仅针对我单击的事件而不是所有实例运行之后的课程,因为我this在我的活动中使用。任何关于这里发生的事情的解释都会非常有帮助。

2.) 现在,我一直在尝试让所有 Slider 事件在我单击页面上的任何 a.next 锚点时都运行 next(),而不是只为我的锚点运行一个事件已点击。我发现这段代码有效:

$('.slideshow').on("click", "a.next", function(e) {
   e.preventDefault();
   return _this.prev();
});

但我说实话,我不确定为什么这是有效的。我的理解是,JQuery 只是查看是否单击了 a.next 锚点,然后将处理函数传递给 $('.slideshow') 选择器,这让我假设它正在选择 $( 'slideshow') 并为所有这些运行 .next() 函数。这是正确的思考方式吗?

3.) 为什么下面的代码片段会导致所有幻灯片运行 next() 函数两次,而不是一次?我真的不喜欢这没有返回任何东西,所以我真的不想使用这段特殊的代码,但我只想更好地理解它......

$('.slideViewport a.next').on("click", function(e) {
   e.preventDefault();
   $('.slideshow').each(function() {
     _this.prev();
   }
});

帮助理解任何此代码将不胜感激。在这种情况下,我真的很想更好地了解 DOM 在传播方面发生的事情,但是我尝试阅读的所有内容都让我感到更加困惑。谢谢!

4

1 回答 1

2

这段代码将单击处理程序附加到文档中的所有.slideshow 元素。

$('.slideshow').click(function(e) {
    e.preventDefault();
    return _this.prev();
});

您可能想要的是将处理程序仅附加到作为滑块后代的 .slideshow 元素:

this.slider.find('.slideshow').click(function(e) {
    // ... handle event here ...
});

现在,关于你的on()陈述:

$('.slideshow a.next').on("click", function(e) {
   e.preventDefault();
   $('.slideshow').each(function() {
     _this.prev();
   }
});

您在这里所做的是将单击事件处理程序绑定到所有.slideshow a.next元素,并且处理程序所做的是_prev()在所有元素上运行。但是您已经有另一个处理程序绑定到.slideshow您调用时的元素$('.slideshow').click()。当“on”处理程序完成时,事件继续向上传播 DOM 树,在向上的过程中触发所有点击处理程序,包括您绑定到.slideshow元素的处理程序。当然,该处理程序也调用_prev().

如果你想停止事件传播,你有两个选择。

  1. 称呼e.stopPropagation()
  2. 从您的事件处理程序返回 false (这告诉 jQuery 停止传播并阻止默认操作)。

click()您可能会问自己,“和之间有什么区别on('click', ...)。该on()方法允许您使用事件委托。基本上,这意味着使用附加到一个 DOM 节点的单个事件处理程序来处理许多后代元素上的事件。

例如,假设您有一个 div,其中包含任意数量的图像,并且每当单击图像时您都需要执行一些操作。您可以 (a) 将单击事件处理程序绑定到每个图像或 (b) 将处理程序绑定到 div,该处理程序将处理所有图像的所有单击事件,因为这些事件在 DOM 树中冒泡。

$('#imageDiv').on('click', 'img', function(evt) {
    // ... "this" is the image that was clicked ...
});

委托具有额外的好处,您可以在容器中添加和删除图像,并且委托将继续工作。

于 2013-01-25T23:41:25.930 回答