javascript - jquery - this.each 没有执行

标签 javascript jquery jquery-plugins coffeescript

我正在尝试通过为 jQuery 创建一个小插件来学习 CoffeeScript,该插件将移动 div 标签以将其保留在屏幕上。由于某种原因,我无法让“return this.each”正确运行。我已经尝试了 jQuery 插件创作页面的基本结构,但仍然不起作用。我需要做一些特别的事情才能让它发挥作用吗?

我正在 Ruby 1.9.3 和 Rails 3.2.2 上使用 Coffee-rails (3.2.1) 和 jquery-rails (2.0.1) gems 运行此脚本。

CoffeeScript

$ = jQuery

defaults =
  paddingTop: 10


$.fn.fixedTop = (options) ->
    settings = $.extend defaults, options
    this.each () ->
      beginPoint = this.offset().top - settings.paddingTop
      $(window).scroll () ->
        scrollTop = $(window).scrollTop()
        if beginPoint < scrollTop
          $(this).css 'marginTop', (scrollTop-beginPoint)+settings.paddingTop

生成的JS

(function() {
  var $, defaults;
  $ = jQuery;
  defaults = {
    paddingTop: 10
  };
  $.fn.fixedTop = function(options) {
    var settings;
    settings = $.extend(defaults, options);
    return this.each(function() {
      var beginPoint;
      beginPoint = this.offset().top - settings.paddingTop;
      return $(window).scroll(function() {
        var scrollTop;
        scrollTop = $(window).scrollTop();
        if (beginPoint < scrollTop) {
          return $(this).css('marginTop', (scrollTop - beginPoint) + settings.paddingTop);
        }
      });
    });
  };
}).call(this);

最佳答案

您在这里遇到了各种问题。

我们首先添加一些行号:

1  $.fn.fixedTop = (options) ->
2    settings = $.extend defaults, options
3    this.each () ->
4      beginPoint = this.offset().top - settings.paddingTop
5      $(window).scroll () ->
6        scrollTop = $(window).scrollTop()
7        if beginPoint < scrollTop
8          $(this).css 'marginTop', (scrollTop-beginPoint)+settings.paddingTop

在第 4 行,this 不是支持 offset 的 jQuery 对象。方法,它只是一个普通的旧 DOM 对象;您需要使用 $(this) (或者,因为我们在 CoffeeScript 领域,所以使用 $(@))。

您在第 8 行遇到了另一个上下文问题:this 与您在第 4 行遇到的 this 不同,这个 thiswindow 因为滚动事件是在 window 上触发的。您可以通过缓存对适当对象的引用来解决此问题:

$el = $(@)
#...
$(window).scroll () ->
    # Use $el rather than $(@) in here

或者使用fat arrow$(window).scroll 回调绑定(bind)到您想要的上下文:

$(window).scroll () =>

您还应该在 CoffeeScript 中使用 @ 而不是 this

当我们解决这些问题时,我们会得到:

$.fn.fixedTop = (options) ->
  settings = $.extend defaults, options
  @each () ->
    $el = $(@)
    beginPoint = $el.offset().top - settings.paddingTop 
    $(window).scroll () -> 
      scrollTop = $(window).scrollTop() 
      if beginPoint < scrollTop 
        $el.css 'marginTop', (scrollTop - beginPoint) + settings.paddingTop

演示:http://jsfiddle.net/ambiguous/cmBYD/

或者这个:

$.fn.fixedTop = (options) ->
  settings = $.extend defaults, options
  @each () ->
    beginPoint = $(@).offset().top - settings.paddingTop 
    $(window).scroll () => 
      scrollTop = $(window).scrollTop() 
      if beginPoint < scrollTop 
        $(@).css 'marginTop', (scrollTop - beginPoint) + settings.paddingTop

演示:http://jsfiddle.net/ambiguous/JCbJj/

您会发现仍然存在一些错误,但现在您已经有了实际运行的东西,您应该能够修复这些错误。您可能还希望在开发和调试 (Java|Coffee)Script 时保持 JavaScript 控制台打开。

这里的主要教训是(咳咳)这个:每次您在 JavaScript 中引用 this 或在 CoffeeScript 中引用 @ 时,请仔细检查您的代码是否在正确的位置运行上下文并三重检查是否涉及回调函数。

关于javascript - jquery - this.each 没有执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9756668/

相关文章:

javascript - 按下 javascript 后突出显示一个按钮

Javascript onclick 菜单更改背景颜色

jquery-ui - JavaScript 错误显示 "confirm is not a function"

jquery - 我如何使用 jquery 在 div 中传播图像

javascript - 如何让一个函数等待另一个函数停止执行(Simon Game) javascript

javascript - 防止 jquery 在表中追加重复值

Javascript 每次循环问题

jquery - 如何禁用 div 上的绑定(bind)

javascript - jQuery click() 多次输出错误按钮的信息

javascript - 使用 fn.extend 扩展 jQuery 的基础知识 - 访问成员