【问题标题】:How can I determine/use $(this) in js callback script如何在 js 回调脚本中确定/使用 $(this)
【发布时间】:2010-02-04 06:09:41
【问题描述】:

我正在使用 Rails 和 jQuery,通过单击链接发起 ajax 调用。我将我的 application.js 文件设置为看起来像建议的here 并且效果很好。我遇到的问题是如何在我的 say..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");

【问题讨论】:

    标签: javascript ruby-on-rails jquery callback


    【解决方案1】:

    jQuery 已经通过事件属性为您处理了this 问题:

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

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

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

    【讨论】:

    • 这很棒,并且可以在脚本之外工作 - 所以它更接近!这是被称为 pastie.org/832155 的 javascript,因此您可以看到单击事件提供了“e”,但您也看到了“脚本”,该脚本显然不知道 e.. 并且该脚本是我试图获取的地方在您的情况下访问 $(this) 或 e,您是否看到提供它的方法?
    • 我不熟悉$.put()"script" 是代表要调用的函数的字符串吗?如果是这样,您不能将e 作为参数传递给该函数吗?
    • 脚本实际上是 put 方法的“类型”参数,这是我从教程中得到的。这个网站homework.nwsnet.de/news/9132_put-and-delete-with-jquery 有类似的东西。对不起,我对此也不太了解..
    • 你用这个方法做什么?你能举个例子吗?
    【解决方案2】:

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

    基本上,我需要操作的每个 DOM 元素都有一个 id,并在我的脚本中引用它们。它有时很丑陋,但替代品更糟。

    【讨论】:

    • 我不会投反对票,但这根本不是真的。我以前也这么想,但是看我上面的帖子。
    【解决方案3】:

    如果你的 JS 来自服务器, 真的没有办法 $(this) 可以在相同的上下文中运行。这 你能得到的最接近的是加载 来自服务器的一些脚本和 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;
    }
    

    你可以让它做你真正想让它做的任何事情,哈哈。

    有关更改“this”值的 JavaScript 函数的更多信息,请查看 MDC 的 .apply.call

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

    【讨论】:

    • 似乎是一个很好的解决方案。我正在寻找的是一种方法来提供我的回调对象,以便我可以引用它。因此,使用我发布的示例使用 {pastie.org/809431} 和回调“脚本”(我认为)的方法 - 我可以修改它以使脚本成为您建议我调用的方法的主体吗? callbackMethod.call(_partial, theLink, data) 其中 partial 是脚本
    • 你不能让它执行一个文件,但是你可以添加一个脚本标签到 DOM ($( 'body' ).append( '&lt;script src="whatevs.js"&gt;&lt;/script&gt;' );) 或者在你执行 AJAX 调用之前简单地包含脚本并将脚本的内容包装在一个函数myExtraJavaScript(){ /* put the code here */ } 然后在回调中调用myExtraJavaScript
    • 猜猜我只需要分配 ID,这似乎太复杂且实施起来存在太多安全风险。
    【解决方案4】:

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

    【讨论】:

    • 好吧,举一个类似于我正在尝试做的事情的简单示例(并且更容易解释):如果用户单击链接,则会从列表中删除该元素,控制器会处理回调,回调(这里有问题)会删除我点击的元素,所以在回调中 delete.js.erb 只会说 $(this).fadeOut();这就是为什么我想使用 $(this) 这样我就不必为每个元素分配一个 ID(这将是世界末日,只是更详细的标记)
    • 我不确定您所说的“控制器将处理回调”是什么意思。您的前端 javascript“回调”将是我上面写的成功处理程序。 rails 控制器会响应一些状态或一些新的 html 或其他什么。如果调用成功,这里的前端知道它需要的一切,点击了什么,上下文,任何闭包变量等。或者我仍然不明白你在你的rails 控制器以及为什么它不能在客户端完成。
    【解决方案5】:

    这是无法实现的,我尝试执行此操作的方法使其不可能,我无法通过视图传递对 javascript 对象的引用。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-18
      • 1970-01-01
      • 2013-03-13
      • 2021-12-30
      相关资源
      最近更新 更多