jquery - this.each не выполняется - PullRequest
2 голосов
/ 18 марта 2012

Я пытаюсь изучить CoffeeScript, создав небольшой плагин для jQuery, который будет перемещать тег div, чтобы он оставался на экране. По какой-то причине я не могу заставить 'return this.each' работать правильно. Я попробовал только базовую структуру со страницы авторизации плагина jQuery, но это все равно не сработало. Что-то особенное, что я должен сделать, чтобы заставить это работать?

Я запускаю этот скрипт на Ruby 1.9.3 и Rails 3.2.2 с гемами coffee-rails (3.2.1) и jquery-rails (2.0.1).

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 Ответ

2 голосов
/ 18 марта 2012

У вас есть различные проблемы здесь.

Мы начнем с добавления некоторых номеров строк:

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 не является объектом jQuery, который поддерживает offset метод, это просто старый объект DOM;вам нужно использовать $(this) (или, поскольку мы находимся на территории CoffeeScript, $(@)).

У вас есть другая проблема контекста в строке 8: this не совпадает с this, который у вас былв строке 4 это this равно window, потому что событие прокрутки запускается на window.Вы можете решить эту проблему, кэшируя ссылку на соответствующий объект:

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

или используя жирную стрелку для привязки обратного вызова $(window).scroll к нужному контексту:

$(window).scroll () =>

Вы также должны использовать @ вместо this в CoffeeScript.

Когда мы исправим эти проблемы, у нас будет следующее:

$.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/

Вы увидите, что у вас все еще есть ошибки, но теперь вы сможете исправить ихесть то, что на самом деле работает.Вы, вероятно, хотите оставить консоль JavaScript открытой при разработке и отладке скрипта (Java | Coffee).

Основной урок здесь (хм) таков: каждый раз, когда вы ссылаетесь на this в JavaScript или @ в CoffeeScript дважды проверьте, что ваш код работает в правильном контексте, и трижды проверьте, задействованы ли функции обратного вызова.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...