2012-03-18 36 views
2

我想通过为jQuery创建一个小插件来学习CoffeeScript,该插件将移动div标记以将其保留在屏幕上。出于某种原因,我无法使'return this.each'正常运行。我已经尝试了jQuery插件创作页面的基本结构,但仍然无法工作。有什么特别的,我必须做的才能使这个工作?jquery - this.each不执行

我在Ruby 1.9.3和Rails 3.2.2上使用了咖啡栏(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

内部回报似乎是多余的。擦除它们,再试一次并告诉我会发生什么。 – 2012-03-18 07:15:46

+0

@elclanrs +1为那个家伙。 – Nemoy 2012-03-18 07:16:32

+0

他们是由coffeescript自动生成的,我试图删除返回和代码没有运行。我在回报的这一边放置了断点,第一个被触发,但第二个不是。 – Nick 2012-03-18 07:21:50

回答

2

您在这里有各种各样的问题。

我们会加入一些行号开始:

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是不一样的this你在4号线过了,这是this因为window滚动事件被上window触发。您可以通过缓存到相应的对象的引用解决这个问题:

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

或使用fat arrow$(window).scroll回调到你想要的背景下结合:

$(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)脚本时保持JavaScript控制台处于打开状态。这里的主要教训是:(ahem):每当您在JavaScript中引用this或在CoffeeScript中引用@时,请仔细检查您的代码是否在正确的上下文中运行,并三重检查是否存在回调函数。