【问题标题】:Multiple event listener are added to each element resulting in multiple ajax call向每个元素添加多个事件侦听器,从而导致多个 ajax 调用
【发布时间】:2020-11-20 12:30:06
【问题描述】:

我有一个购物车清单。 每个购物车都包含一个产品列表。

{# templates\Cart\list.twig #}
{% use 'Cart/details.twig' %}
{% extends '@templates/_base.twig' %}
   {% block body %}
      <div class="list-group" id="cart-list" role="tablist">
         {% for cart in cart_list %}
            <a class="products-list-cart list-group-item list-group-item-action {% if userCart.current %}active{% endif %}"
                               id="item-details-cart-{{ cart.id }}"
                               href="#products-list-cart-{{ cart.id }}"
                               data-href="{{ path('cart_product_list', {'cart_id':cart.id}) }}"
                               data-toggle="list" role="tab" aria-controls="products-list-cart-{{ cart.id }}"
                               {% if not first_cart %}data-product-list-loaded="true" {% set first_cart = true %}{% endif %}>
               See cart details for cart {{ cart.id }}
               {# 
                  On click, make an ajax call to filled
                  in product list '#products-list-cart-{{ cart.id }}'
               #}
            </a>
         {% endfor %}
      </div>
      <div class="tab-content" id="carts-content">
         {% for cart in cart_list %}
            {% set userCart = cart.userCart %}
            <div class="tab-pane fade {% if userCart.current %}show active{% endif %}"
                                 id="products-list-cart-{{ cart.id }}"
                                 role="tabpanel"
                                 aria-labelledby="cart-{{ cart.id }}">
               {% if not first_cart_product_list %}
                  {% block cart_details %}
                     {{ parent() }} 
                  {% endblock %}
               {% else %}
                  <i class="fa fa-cog fa-spin fa-1x fa-fw">&nbsp;</i> {{ "loading_product"|trans }}
                  ... {# 
                        Filled in on click on '.products-list-cart'.
                        Proceed to ajax call.
                      #}
               {% endif %}
            </div>
         {% endfor %}
      </div>
   {% endblock %}
{% endblock %}
{% block javascripts %}
    {{ parent() }}
    {{ encore_entry_script_tags('cart') }}
    {{ encore_entry_script_tags('product') }}
{% endblock %}

我尽量保持简单,我使用list tab bootstrap component

当我必须包含入口点时,问题就来了。

因为我的 javascript 将事件侦听器添加到产品详细信息。 因此,第一个购物车的所有产品详细信息都可以正常工作,因为它们是在页面加载时加载的。 此行为由first_cart_product_list 变量管理。

当用户单击购物车查看其详细信息时,将显示所有其他产品列表。 问题是包含 javascript 的入口点仅将事件添加到使用 dom 加载的元素。

我尝试将入口点添加到我的Cart/details.twig 模板,但它会在每次 ajax 调用时加载。 所以这里的问题是所有 ajax 调用都将事件侦听器添加到所有现有的 $('a.products-list-cart') 元素。所以页面上的很多元素都有越来越多的事件监听器而不是一个。

我举个例子: 如果我将encore_entry_script_tags 添加到购物车详细信息模板:

{# Cart/details.twig #}
{{ encore_entry_script_tags('product') }}

它被添加到每个产品列表中,因此: 如果我有 4 辆购物车:

然后我单击每个以加载产品列表,该列表在页面上的每个产品上添加一个事件侦听器。 所以对于第一个购物车,我将在每个产品元素上设置 4 个事件监听器。

结果是当我点击第一个购物车的“添加到购物车”按钮时:

有 4 次调用 ajax 函数将产品数量更新到购物车中。

// product.js entry point...
$(document).ready(
    function () {
        $('.btn-add-product-to-cart').on( // This event listener is added to every button on product list
            'click',
            function (e) {
                e.preventDefault();
                $.ajax({
                    method: 'POST',
                    url: $(this).data('href'),# Call controller route to modify product quantity in DB
                ...    

我尝试使用.one() 函数,因为我希望在每个元素上只添加一个事件侦听器。但不幸的是它不起作用。

任何帮助将不胜感激。

【问题讨论】:

  • “问题在于,包含 javascript 的入口点仅向使用 dom 加载的元素添加事件。” - 以及解决这个众所周知的问题的正确方法问题,称为事件委托
  • 我不知道事件委托,我来看看。感谢您为我指明正确的方向

标签: javascript jquery webpack


【解决方案1】:

我认为您可以在添加事件之前轻松完成 .off 事件。点击事件是这样的:

$('a.products-list-cart').off('click').click(function () { ... })

【讨论】:

  • 是的,我同意这是可能的,但是 JavaScript 将有额外的工作要做。如果我只是启动它,则退出所有先前添加的侦听器。然后它将新添加所有事件侦听器。如果我有 5 件物品没关系,但当我有 500 件时就不合适了:|
猜你喜欢
  • 2012-12-04
  • 2012-08-04
  • 2015-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-09
  • 1970-01-01
  • 2014-05-18
相关资源
最近更新 更多