jquery - this.each没有执行

时间:2012-03-18 07:12:14

标签: 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 个答案:

答案 0 :(得分: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与第4行的this不一样,此thiswindow,因为滚动事件为被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控制台处于打开状态。

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