当通过 ajax 加载表单时,jQuery 的 live 和 livequery 对我不起作用

Posted

技术标签:

【中文标题】当通过 ajax 加载表单时,jQuery 的 live 和 livequery 对我不起作用【英文标题】:jQuery's live and livequery not working for me when the form is loaded through ajax 【发布时间】:2010-12-19 16:56:11 【问题描述】:

我之前问过类似的问题How can I have jquery attach behavior to an element after inserting it,但仍然没有找到答案。为了清楚起见,我用不同的例子提出了一个新问题。

这是我的代码不起作用。

$(document).ready(function()   
 $('form.edit_color').live('submit',  function()
    var form = $(this).closest('form');
    var colorRow = $(this).closest('tr');
    var action = $(form).attr('action');
    var formData = $(form).serialize();
    $(colorRow).fadeOut();
   $.post(action, formData,
    function(data) 
        $(form).replaceWith(data);
        $(colorRow).fadeIn();           
    );
    return false;
  );
);

会发生什么,对于我的每个表单,我都可以通过 ajax 提交它们并用更新的表单替换它。但是,当我点击新的提交按钮时,什么也没有发生。

【问题讨论】:

【参考方案1】:

要添加到 bobince,live 使用 event delegation 技术来“附加”事件。它的工作原理是所有事件最终都会传播到 DOM 中的最高父级 (window.document),因此如果您仅将单个事件处理程序附加到文档,然后根据事件的原始目标运行不同的事件处理程序。

但是,有些事件不会传播。 submit 就是其中之一。所以你不能在那里使用事件委托。

【讨论】:

【参考方案2】:

正如您在原始问题中的回答,live 根本不适用于 submit 事件。

还要注意,您的回调函数中的 $(colorRow).fadeIn(); 不可能工作,因为它指的是在 submit 发生时表单中存在的 colorRow。但是您已经在前面的replaceWith 调用中完全删除并用新的colorRow 替换了该colorRow。替换后,formcolorRow 变量没有指向任何有用的东西。

live 有点像 hack,它与 html 中事件的实际工作方式不太吻合。尽量避免使用它。用新标记替换页面的大部分内容通常是一个糟糕的举动。如果您可以从 JSON 返回值更新表单中现有元素的内容,而不是传回 HTML 的 katamari:那么您将无需担心重新绑定事件或保留对现已失效的 DOM 对象的引用。

(如果一定要传回HTML,至少只返回表单的内容,而不是表单标签本身。那么你可以使用html()来设置表单内容;通过不替换表单标签本身,你不必担心重新绑定submit 事件就可以了。)

【讨论】:

但是我不是替换colorRow,只是替换里面的Form,而且是个小表单 另外,我只是在其他地方实现了相同的代码并且它工作了......我认为不同之处在于,在这种情况下,我的表单不正确地包含了一些表格元素。 啊,好的,很酷。是的,这会发生:你不能在 IE 的表上设置 innerHTML,所以 jQuery 有一个解决方法,但是因为它只在你创建的元素是像 trtbody 这样的表子元素时触发. jQuery 假设您只会以 HTML 有效的方式进行嵌套,这可能很公平。【参考方案3】:

我在想 livequery 确实处理了提交事件,但是当我也遇到问题时,我想我也会 live() 。

当我尝试绑定到提交按钮的单击事件时,我也遇到了查找表单的问题。

当我在 firebug 中检查我的提交按钮时,我意识到它没有显示为我的表单的子项。这让我想到,如果 firebug 无法确定我的提交按钮是我表单的子元素,那么 jQuery 会遇到什么样的麻烦(也许 W3C 验证器抱怨是有原因的)。

所以我在一个 div 标签内的不同表单上尝试了与上面相同的代码,它工作了,所以我迅速从这个问题的表单中删除了表格标签,令人惊讶的是它也工作了。

我的解决方案是花费额外的时间来使我的 html 有效,并使用在 jQuery 1.3.3 之前无法使用的东西,http://docs.jquery.com/Release:jQuery_1.3.2。

以下是我当前的代码,我需要弄清楚如何正确标记表单。

$('form.edit_color').live('submit', function() var 形式 = $(this); var colorRow = $(this).closest('div.color_form'); var action = $(form).attr('action'); var formData = $(form).serialize(); $(colorRow).fadeOut(); $.post(动作,formData, 功能(数据) $(form).replaceWith(data); $(colorRow).fadeIn(); ); 返回假; );

<div class="color_form">
<% form_for color, :url => admin_color_path(color) do |f| -%>
 <div style="background: #<%= color.value %>"></div>
  <div><%= f.text_field :title %></div>
   <div><input type="text" size="30" name="color[value]" class="colorpickerfield" value="<%= color.value %>" /></div>
    <div style="text-align:left">
     <% Color.types.each do |type, name| %>
      <div>
       <%= color_types_checkbox(color, type) %>
       <%= name %>
      </div> 
     <% end %>
    </div>
   <div>
  <%= f.submit "Update", :class => 'submit' %>
 </div>
<% end %>
</div>

【讨论】:

【参考方案4】:
$('form.edit_color').live("submit",
function( event )
event.preventDefault();

);

试试这个。 更多:http://api.jquery.com/event.preventDefault/

干杯, http://hiteshjoshi.com

【讨论】:

【参考方案5】:
$('form').live('submit', function(e) 
    alert(e.type);
    e.preventDefault();
);

$('form :submit').live('click', function(e) 
    $(this.form).submit();
    e.preventDefault();
);

【讨论】:

以上是关于当通过 ajax 加载表单时,jQuery 的 live 和 livequery 对我不起作用的主要内容,如果未能解决你的问题,请参考以下文章

通过 AJAX 加载时 JQuery 脚本不运行

jquery ajax 加载结果列表,即使没有任何查询

提交时 ASP.NET jQuery 重新加载元素(Ajax POST/GET)

Django + Jquery,扩展AJAX div

通过 AJAX 加载 div 时 jQuery 拖放中断

通过 Jquery-Ajax 提交复选框表单 [关闭]