javascript - 同一类的多个实例的事件处理——需要说明

标签 javascript jquery

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

1.) 在我的网页上,我有三个使用 slider 功能的不同面板,该功能使用下一个和上一个 anchor 链接创建一个具有 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 anchor 将导致被单击的元素及其下方的任何元素移动到其幻灯片中的下一个列表元素。转到第二个面板将导致除第一个面板之外的所有面板运行,第三个面板将导致除第一个和第二个面板之外的所有面板运行,等等。我希望处理程序只针对我单击的事件运行,而不是所有实例它之后的类(class),因为我在我的事件中使用了 this。任何关于这里发生的事情的解释都会非常有帮助。

2.) 现在,我一直在努力使所有 Slider 事件在我单击页面上的任何 a.next anchor 时都运行 next() ,而不是只为该 anchor 运行一个事件我点击了谁的 anchor 。我发现这段代码有效:

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

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

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

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

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

最佳答案

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

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

您可能想要的是仅将处理程序附加到作为 slider 后代的 .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();
   }
});

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

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

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

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

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

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

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

关于javascript - 同一类的多个实例的事件处理——需要说明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14531838/

相关文章:

javascript - 空变量和初始化变量的区别

javascript - Greasemonkey 无法找到/修改/删除内容? (在 Twitch.tv 上)

javascript - 在羽光形态内标记?

javascript - 显示多个区 block ,单选被选中

php - 在 jquery 数据表中加入查询问题

php - MVC php/ajax问题

javascript - Jquery/Js : Hide/Show Divs based on select box option values

javascript - math.floor 和 math.radom 相差一个索引

jQuery 循环插件

javascript - jquery ui datepicker 转到今天按钮