【问题标题】:jQuery Plugin init binding event to window scroll - how to pass $this?jQuery 插件初始化绑定事件到窗口滚动 - 如何传递 $this?
【发布时间】:2011-08-11 06:16:47
【问题描述】:

我的第一个插件使用适当的架构完成,但我一直坚持如何将事件侦听器应用于 $(window).scroll 以将 globalMessage 固定到窗口顶部。可以在此处查看完整的插件:https://gist.github.com/937792,但相关位是下面的 init。

设置修改目标元素的 css 属性的窗口事件侦听器的最佳方法是什么?

(function($){

    var methods = {
        init: function(options) {

            var $this = this;
            var opts = $.extend({}, $.fn.globalMessage.defaults, options);
            var data = $this.data('globalMessage');

            // init global data
            if ( ! data ) {
                $this.data('globalMessage', {
                    settings : opts
                });

                $(window).bind("scroll.globalMessage", function() {

                    // ----------
                    // HOW TO ACCESS both $this (defined outside this context)
                    // and the scrollTop value to change top css val?
                    //-----------
                    $this.css("top", $(window).scrollTop());

                });

                $this.bind('click.globalMessage', methods.hide);

            }

            return $this;
        },
        ...[other funcs]...
    }

    ...[main entry point etc]...

})(jQuery);

【问题讨论】:

  • 我根本不清楚你的问题到底是什么。
  • 也许我不明白你在用窗口滚动事件做什么,但是如果你想让 globalMessage 保持在窗口的顶部,你不能只使用 position:fixed css 吗?跨度>
  • @nicky - 假设您已将页面滚动到一半,并且您想要显示固定在窗口顶部的消息。在这种情况下,将不会看到带有 top:0 的固定元素。
  • @notbrain 也许你是对的,这里有点晚了 - jsfiddle.net/wUpgP
  • @nicky 你很清醒,看来我是缺少 css foo 的人;位置:固定是更好的方法。谢谢

标签: jquery plugins scope scrolltop


【解决方案1】:

以正确的方式将变量传递给事件:

$(window).bind("scroll.globalMessage", {foo:'bar'}, function(e) {
   alert(e.data.foo); // alert 'bar'
});

【讨论】:

    【解决方案2】:

    如果您考虑一下,您的 methods 对象的上下文中没有 this。所以你需要通过init()调用传入:

    (function($){
    
        var methods = {
            init: function(sel, options) {
    
                var $this = $(sel);
    

    然后,当您调用插件时,将 this 传递给您的 init() 方法:

    $.fn.yourPlugin = function(method) {
        if (!this.length) {
            return this;
        }
        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || !method) {
            return methods.init(this, arguments);
        } else {
            $.error('Method ' +  method + ' does not exist on jQuery.yourPlugin');
        }
    };
    

    我唯一要注意的是,在设置 $this 变量时,它实际上是一个 jQuery 对象,而不是特定元素。所以我用过:

    (function($){
    
        var methods = {
            init: function(sel, options) {
    
                var $sel = $(sel);
    

    而且,就在事件处理程序中使用 $this 而言,您需要重新定义它:

    $(window).bind("scroll.globalMessage", function() {
        $this = $('#the_selector_for_your_element'); // Maybe $(this)?
        $this.css("top", $(window).scrollTop());
    });
    

    【讨论】:

    • Re: 从 $.fn.plugin 传递这个: 我想我已经这样做了——因为如果我调用 console.log(this.attr("id")) 作为 init 的第一行,我得到了我期望的 id(插件所附加的那个)。初始化上下文中的“this”不是已经是 jQuery 对象了吗?
    • 嗯,我正在使用的插件遇到了同样的问题,并用上面的代码 (you can see it here) 解决了它。至于事件处理程序,您需要为事件处理程序上下文重新定义 $this,因为当它被调用时,它将在被调用时脱离上下文。
    • @jared,看看这个:jsfiddle.net/7CxuC/7 我是疯了还是这不等同于你所拥有的而不需要从 $.fn.globalMessage 显式传递?顺便说一句,感谢您的帮助...
    • 是的...用于调用方法数组中的函数的 .apply 函数负责在 init 函数中设置“this”。见developer.mozilla.org/en/JavaScript/Reference/Global_Objects/…
    猜你喜欢
    • 2013-09-02
    • 1970-01-01
    • 2013-11-17
    • 1970-01-01
    • 2020-10-16
    • 1970-01-01
    • 1970-01-01
    • 2011-10-13
    • 2011-08-06
    相关资源
    最近更新 更多