Javascript 事件在 rails 应用中多次触发?

Javascript events firing multiple times in rails app?

我正在尝试设置一个表单,以便在我点击 enter 时通过 ajax 提交。为此,我想在输入字段上按下回车键时触发表单提交。但是,如果按住该键的时间超过一秒钟,则回车键的 keyup 事件会多次触发,这又会发送大量 ajax 请求,导致浏览器崩溃。

我不明白为什么事件会多次触发。这是页面的视图:

<div class="page-content">
  <div class="l-edit-header">
    <h1>Edit</h1>
    <div class="piece-header">
      <%= image_tag @piece.user.avatar_url(:small), class: "avatar-small" %>
      <div class="piece-header-info">
        <h1><a href="<%= piece_path @piece %>"><%= @piece.title %></a></h1>
        <em>
          By <%= link_to @piece.user.username, user_path(@piece.user) %>
          <%= @piece.created_at.strftime("%B %d, %Y") %>
        </em>
      </div>
    </div>
  </div>

  <div class="l-edit-main">

    <div class="piece-main">
      <%= image_tag @piece.image_url %>
      <p id="piece-description" class="piece-main-description"><%= @piece.description %></p>
      <div class="piece-main-links">
        <%= link_to "Delete", piece_path(@piece), method: :delete if current_user == @piece.user %>
      </div>
    </div>
  </div>

  <div class="l-edit-side">
    <div class="form-container">
      <%= form_tag piece_tags_path(@piece), id: "new_tag", remote: true do  %>
        <%= label_tag :new_tag, "New Tag"%>
        <%= text_field_tag :tag, "", data: {autocomplete_source: tags_url}, placeholder: "Add a tag and press Enter" %>
        <div id="tags" class="piece-tags">
          <%= render partial: "tags/delete_tag_list", locals: {piece: @piece, method: :delete} %>
        </div>
      <% end %>
    </div>

    <div class="form-container">
      <%= simple_form_for @piece do |f| %>
        <%= f.association :category, include_blank: false %>
        <%= f.input :published, as: :hidden, input_html: {value: true} %>
        <%= f.input :title %>
        <%= f.input :description %>

        <div class="form-submit">
          <%= f.button :submit, "Publish" %>
        </div>
      <% end %>
    </div>
  </div>
</div>

这是我尝试使用的标签形式的 Javascript:

var tagReplace = {
    init: function(){
        //Replace "#tags" with new updated tags html on tag create
        $("#new_tag").on("ajax:success", function(e, data, status, xhr){
            $("#tags").html(data);
            tagReplace.init();
            $("#tag").val("");
        });

        //Replace "#tags" with new updated tags html on teg delete
        $("#tags a[data-remote]").on("ajax:success", function(e, data, status, xhr){
            $("#tags").html(data);
            tagReplace.init();
        });


        $("#new_tag").on("keydown", function(e){
            if (e.which == 13){
                event.preventDefault();
            }
        });

        $("#tag").on("keyup", function(e){
            if (e.which == 13){
                $("#new_tag").submit();
                console.log("pressed enter on new tag");
            }
        });

    },
    getTags: function(){
        $.get( $("#tag").data("autocomplete-source"), tagReplace.initAutocomplete);
    },
    initAutocomplete: function(tagsArray){
        $("#tag").autocomplete({
            source: tagsArray
        });
    }
};

//Initalize
$(document).on('ready page:load', function () {
    tagReplace.init();
});

如您所见,我已经阻止了在表单上按下 return 键的默认行为,并添加了一个 console.log 来计算事件被触发的次数。

我认为这可能与我正在使用 turbolinks 有关,但我似乎无法弄清楚原因。

如何保证每次按下回车键只触发一次事件?目前,当我点击 enter 时,Javascript 使浏览器崩溃。

您正在调用 tagReplace.init();本身有 2 次,正如@Dezl 在他的 answer related to this topic、"If you have delegated events bound to the document, make sure you attach them outside of the ready function, otherwise they will get rebound on every page:load event (causing the same functions to be run multiple times)."

中解释的那样