【问题标题】:jquery - this.each isn't executingjquery - this.each 没有执行
【发布时间】:2012-04-03 03:23:35
【问题描述】:

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

我在 Ruby 1.9.3 和 Rails 3.2.2 上运行此脚本,并带有 coffee-rails (3.2.1) 和 jquery-rails (2.0.1) gem。

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);

【问题讨论】:

  • 那里的内部回报似乎是多余的。删除它们,再试一次,告诉我会发生什么。
  • 它们是由coffeescript自动生成的,我尝试删除返回并且代码没有运行。我在 return this.each 的任一侧放置了断点,第一个被触发,但第二个没有。
  • @elclanrs 你已经回答了你的问题:更少的代码。而且阅读起来并不难。使用 Python 或 Ruby 编写代码的人实际上发现它更自然。
  • 是的,我想它感觉更自然,我的意思是它是 Rails 中的默认设置......我只需要我的花括号!我受不了“用英语阅读”的代码。
  • 您可以通过插入显式return 作为函数的最后一行来阻止CoffeeScript 返回最后一个表达式的结果。如果您可以发布您正在使用的 HTML,它将更容易回答您的问题。

标签: javascript jquery jquery-plugins coffeescript


【解决方案1】:

你有各种各样的问题。

我们将从添加一些行号开始:

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 中引用 @ 时,请仔细检查您的代码是否在正确的上下文中运行,并三次检查是否涉及回调函数.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-15
    相关资源
    最近更新 更多