代码之家  ›  专栏  ›  技术社区  ›  Rabbott

如何在JS回调脚本中确定/使用$(this)

  •  0
  • Rabbott  · 技术社区  · 15 年前

    我正在使用Rails和jQuery,通过单击一个链接进行一个Ajax调用。我将application.js文件设置为类似于建议的文件 here 而且效果很好。我现在的问题是,我怎样才能在我的发言中使用美元。是否更新.js.erb文件以表示我单击的链接?我不想给每个人都分配一个ID,然后在回调脚本中重新编译该ID。

    编辑 举一个简单的例子,类似于我正在尝试做的事情(更容易解释):如果用户单击一个链接,从列表中删除该元素,控制器将处理回调,回调(这里有问题)将删除我单击的元素,因此在回调中,delete.js.erb只会说$(这个)。.fadeout();这就是为什么我要使用$(this)以便不必为每个元素分配ID(这将是世界末日,只是更详细的标记)

    应用程序

    jQuery.ajaxSetup({ 'beforeSend': function(xhr) {xhr.setRequestHeader("Accept", "text/javascript,application/javascript,text/html")} })
    
    function _ajax_request(url, data, callback, type, method) {
        if (jQuery.isFunction(data)) {
            callback = data;
            data = {};
        }
        return jQuery.ajax({
            type: method,
            url: url,
            data: data,
            success: callback,
            dataType: type
        });
    }
    
    jQuery.extend({
        put: function(url, data, callback, type) {
            return _ajax_request(url, data, callback, type, 'PUT');
        },
        delete_: function(url, data, callback, type) {
            return _ajax_request(url, data, callback, type, 'DELETE');
        }
    });
    
    jQuery.fn.submitWithAjax = function() {
        this.unbind('submit', false);
        this.submit(function() {
            $.post(this.action, $(this).serialize(), null, "script");
            return false;
        })
        return this;
    };
    
    // Send data via get if <acronym title="JavaScript">JS</acronym> enabled
    jQuery.fn.getWithAjax = function() {
        this.unbind('click', false);
        this.click(function() {
            $.get($(this).attr("href"), $(this).serialize(), null, "script");
            return false;
        })
        return this;
    };
    
    // Send data via Post if <acronym title="JavaScript">JS</acronym> enabled
    jQuery.fn.postWithAjax = function() {
        this.unbind('click', false);
        this.click(function() {
            $.post($(this).attr("href"), $(this).serialize(), null, "script");
            return false;
        })
        return this;
    };
    
    jQuery.fn.putWithAjax = function() {
        this.unbind('click', false);
        this.click(function() {
            $.put($(this).attr("href"), $(this).serialize(), null, "script");
            return false;
        })
        return this;
    };
    
    jQuery.fn.deleteWithAjax = function() {
        this.removeAttr('onclick');
        this.unbind('click', false);
        this.click(function() {
            $.delete_($(this).attr("href"), $(this).serialize(), null, "script");
            return false;
        })
        return this;
    };
    
    // This will "ajaxify" the links
    function ajaxLinks(){
        $('.ajaxForm').submitWithAjax();
        $('a.get').getWithAjax();
        $('a.post').postWithAjax();
        $('a.put').putWithAjax();
        $('a.delete').deleteWithAjax();
    }
    

    E.B

    <%= link_to 'Link Title', article_path(a, :sentiment => Article::Sentiment['Neutral']), :class => 'put' %>
    

    这两件事的结合 J.S.Erb 在Rails中,该文件中的代码用作Ajax的回调(在本例中为$.Put)。

    J.S.Erb

    // user feedback
    $("#notice").html('<%= flash[:notice] %>');
    
    // update the background color
    $(this OR e.target).attr("color", "red");
    
    5 回复  |  直到 15 年前
        1
  •  1
  •   Sampson    15 年前

    jquery已经处理 this 事件属性问题:

    $("a").click(function(e){
      e.preventDefault();
      $("#foo").fadeIn(3000, function(){
        $(e.target).text("Foo loaded");
      });
    });​​​
    

    注意如何通过 event . 在这种情况下,任何事件都在内部处理。只需给他们起唯一的名字,比如 e2 , e3 等等,不再需要不断地写另一篇 var item = $(this) 跟踪的行 三个事件。

    在线演示: http://jsbin.com/egelu3/edit

        2
  •  0
  •   Toby Hede    15 年前

    如果您的JS来自服务器,那么$(this)实际上无法在同一上下文中操作。最接近的方法是从服务器加载一些脚本,并在客户端函数的上下文中对其进行评估。

    我基本上有一个需要操作的每个DOM元素的ID,并在脚本中引用它们。它有时也很难看,但替代方案更糟。

        3
  •  0
  •   Dan Beam    15 年前

    如果您的JS来自服务器, 真的没有办法(这个) 不能在同一上下文中操作。这个 你能得到的最接近的是装载 服务器和eval的一些脚本 在您的客户端上下文中 功能。

    不是真的

    我基本上有一个身份证 我需要操作的DOM元素,以及 在我的脚本中引用它们。它是 偶尔丑陋,但 替代方案更糟。

    我觉得这不难看。

    这个问题的关键是功能范围。让我告诉你我的意思。在发送XHR调用之前,需要创建一个被调用的函数。在您的案例中,您使用的是一个单击事件,因此让我向您展示一个为您量身定制的示例:

    $( '#somelink' ).click( function( )
    {
        // this stores the location of the current "this" value
        // into this function, and will available even after we
        // end this function (and will still live while the XHR's
        // callback is being executed
    
        var theLink = this;
    
        // fire the AJAX call
    
        $.post
        (
            'some/url',
    
            { 'some':'data' }, // optional
    
            function( )
            {
                // use theLink however you want
                // it'll still be there
    
                // also, if you're sending in callbacks
                // as variables, you can safely say
    
                hideAndStore.call( theLink, data );
    
                // which executes callback( ), overriding
                // "this" with theLink (your DOM node)
                // and sending in the responseText as the
                // first argument
            }
        );
    } );
    

    然后你可以让你的回拨功能如下:

    function hideAndStore( response )
    {
        // you can safely use "this" as the DOM node
        $( this ).css( { 'display':'none' } );
    
        // and you can do whatever you wish with the response
        window.globalData = response;
    }
    

    你想让它做什么就做什么,哈哈。

    有关更改“this”值的javascript函数的详细信息,请查看 .apply .call 在MDC

    https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/Function/Apply https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/Function/Call

        4
  •  0
  •   aceofspades    15 年前

    你在发送回的javascript中做什么?也许您可以发送一些HTML或JSON并在回调中对其进行操作。

    $('a:clickable').bind('click', function() {
      var elem = $(this);
      $.ajax({
        url: ...,
        dataType: 'json',
        success: function(data) {
          // elem is still in scope
          elem.addClass(data.class_to_add_to_link);
        }
      });
    });
    
        5
  •  0
  •   Rabbott    15 年前

    这是不可能完成的,我尝试的方法使得它不可能实现,我不能通过视图传递对javascript对象的引用。

    解决方案是为每个项目分配ID,并通过它引用它们。