我正在尝试通过为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);
答案 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
不一样,此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控制台处于打开状态。
这里的主要教训是(咳咳):每次在JavaScript中引用this
或在CoffeeScript中引用@
时,请仔细检查您的代码是否在正确的上下文中运行,并检查是否存在是涉及的回调函数。