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

时间:2010-02-04 06:09:42

标签: javascript ruby-on-rails jquery callback

我正在使用Rails和jQuery,通过单击链接发起ajax调用。我将我的application.js文件设置为与here提议的文件类似,并且效果很好。我遇到的问题是如何在我的说.. update.js.erb文件中使用$(this)来表示我点击的链接?我不想为每个人分配一个ID,然后在回调脚本中重新编译该id ..

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

  

的application.js

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

show.html.erb

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

两个东西的组合将在rails中调用 update.js.erb ,该文件中的代码用作ajax的回调(在这种情况下为$ .put)

  

update.js.erb

// user feedback
$("#notice").html('<%= flash[:notice] %>');

// update the background color
$(this OR e.target).attr("color", "red");

5 个答案:

答案 0 :(得分:1)

jQuery已经使用事件属性处理this问题:

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

请注意我如何通过其event返回主链接。对于在其中处理的任何事件也是如此。只需为它们指定唯一的名称,例如e2e3等。不再需要不断编写另一条var item = $(this)行来跟踪this三个事件。< / p>

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

答案 1 :(得分:0)

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

我基本上为每个需要操作的DOM元素都有一个id,并在我的脚本中引用它们。它偶尔会很难看,但替代品更糟糕。

答案 2 :(得分:0)

  

如果您的JS来自服务器,   真的没有办法$(这个)   可以在相同的环境中运作。该   最接近你可能会加载   来自服务器和eval的一些脚本   它在您的客户端的背景下   功能

不正确

  

我基本上每个都有一个id   我需要操纵的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;
}

你可以做任何你想要它做的事,哈哈。

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

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

答案 3 :(得分:0)

你在发回的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);
    }
  });
});

答案 4 :(得分:0)

这是无法实现的,我尝试这样做的方法使其无法实现,我无法通过视图传递对javascript对象的引用。

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