简体   繁体   中英

Ajax request called multiple times though I need only once?

I have been working on a e-commerce web application. There is a wishlist module which I'm trying to implement. I'm adding the products into wishlist using ajax calls and also removing it with ajax. The adding part works fine but I have a problem in removing part . What I'm trying to do is, making an ajax call to fetch the wishlist items from the database and adding a remove button dynamically using jquery. Although I know that I have to use a .live function to attach an event to it which I did but when i click on the button all the items which are present in the wishlist are removed . I see multiple ajax request was made in console under network tab and I don't get it why , although I clicked it only once. The following is a snippet of my code

$.ajax({
  type: "POST",
  url: "fetchdata1",
  data: "cat=" + cat,
  success: function(data) {
    productContainer.innerHTML = "";
    var $productContainer = $('#productContainer');

    $.each(data, function(key, value) {
      if (value['newVar'] === 1) {
        $productContainer.append("<div id='productBox' class='grid_3'>\n\
          <a href='product.jsp?id=" + value['id'] + "'><img src='" + value["image"] + "'/></a><br/>\n\
          <a href='product.jsp?id=" + value['id'] + "'><span class='black'>" + value['name'] + "</span></a><br/>\n\
          <span class='black'>By " + value['company'] + "</span><br/><span class='red'>RS." + value['price'] + "</span>\n\
          <br/><br/><a id='remove' href='#'>REMOVE</a></div>");
        foo(value['id']);
      } else {
        $productContainer.append("<div id='productBox' class='grid_3'>\n\
          <a href='product.jsp?id=" + value['id'] + "'><img src='" + value["image"] + "'/></a><br/>\n\
          <a href='product.jsp?id=" + value['id'] + "'><span class='black'>" + value['name'] + "</span></a><br/>\n\
          <span class='black'>By " + value['company'] + "</span><br/><span class='red'>RS." + value['price'] + "</span></div>");
      }
    });
  }
});

function foo(value) {
  var pid = value;
  $('#remove').live("click", function() {
    $.ajax({
      type: "POST",
      url: "removeFromWishlist",
      data: "pid=" + pid,
      success: function(response) {
      }
    });
  });

In the first ajax request I'm fetching products from the database then adding remove button to it dynamically then calling function foo which attach the click event using .live function and then make call to database to remove it. Hey guys I'm not pro at web, so go easy on me if I made some silly mistake.
Thanks!

The issue happened because you register listener multiple times in each loop. So to resolve, you need to register once after all button has been populated. I also change selector to class ".remove" because you going to have multiple remove button so using id is will be duplicated, and using jquery .on() instead of .live() (deprecated)

 $.ajax({ type: "POST", url: "fetchdata1", data: "cat=" + cat, success: function(data) { productContainer.innerHTML = ""; var $productContainer = $('#productContainer'); $.each(data, function(key, value) { if (value['newVar'] === 1) { $productContainer.append("<div id='productBox' class='grid_3'>\\n\\ <a href='product.jsp?id=" + value['id'] + "'><img src='" + value["image"] + "'/></a><br/>\\n\\ <a href='product.jsp?id=" + value['id'] + "'><span class='black'>" + value['name'] + "</span></a><br/>\\n\\ <span class='black'>By " + value['company'] + "</span><br/><span class='red'>RS." + value['price'] + "</span>\\n\\ <br/><br/><a class='remove' id='remove' data-pid='" + value['id'] + "' href='#'>REMOVE</a></div>"); } else { $productContainer.append("<div id='productBox' class='grid_3'>\\n\\ <a href='product.jsp?id=" + value['id'] + "'><img src='" + value["image"] + "'/></a><br/>\\n\\ <a href='product.jsp?id=" + value['id'] + "'><span class='black'>" + value['name'] + "</span></a><br/>\\n\\ <span class='black'>By " + value['company'] + "</span><br/><span class='red'>RS." + value['price'] + "</span></div>"); } }); foo(); } }); function foo() { $('.remove').on("click", function() { var pid = $(this).data("pid"); $.ajax({ type: "POST", url: "removeFromWishlist", data: "pid=" + pid, success: function(response) { } }); }); 

Problem: You have same id for multiple hyperlink and you are using .live function on "id based" selector. It is applying click function again & again on first element.

Solution: Update your hyperlink

<a href='#' onclick="foo(this)" pid=value['id']>REMOVE</a>

Then in foo() function

function foo(obj) {
  var pid = $(obj).attr("pid");
  $(obj).bind("click", function() {
    $.ajax({
      type: "POST",
      url: "removeFromWishlist",
      data: "pid=" + pid,
      success: function(response) {
      }
    });
  });

i don't get why you using same id multiple times.

and afaik, jQuery.live already deprecated. you can use this if you want to get live behavior:

$(document).on('click', 'element-selector', function(){
   ...
});

with your code, it can rewriten to:

$(document).on('click', '[id=remove]', function(){
   ...ajax call...
});

now the problem with your fetch data function is this:

$.each(data, function(key, value) {
      if (value['newVar'] === 1) {
        ...append element...
        **foo(value['id']);**
      } else {
         ...append element...
      }
});

as we know foo() are your function that bind remove behavior. based on your code, whenever that fetch data has newVar = 1, it will directly call foo. which mean binding remove behavior multiple times, as many as newVar = 1 was.

solution: you can put pid as a attribute on your a element maybe something like <a href="x" pid="123">remove</a> and within remove click function, you can use $(this).attr('pid') to get that value. and remove that foo() content to outside the function, since $(element).live(...) or $(document).on(event, element, ...) will listen the element, even the element dynamicly added to the page.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM