函数在我的js文件中以指数方式重复

时间:2016-09-14 21:48:12

标签: javascript jquery ajax

我正在使用Node,Express和MongoDB运行网站。我在ajax调用之后生成容器以获取数据以填充它们,并且每个容器都有一个按钮,该按钮使得另一个ajax调用特定于其获取详细信息的配方。第一次我这样做它完美地工作,但如果我得到第二个的细节它执行功能3次而不是一个,如果我为第三个容器执行它运行它9次,依此类推。我对Jquery很新,也许这是对事件如何运作的误解。 saveRecipe函数也会出现问题。

global.js

$(document).ajaxComplete(function(){
  $('.details').popover({"trigger": "manual", "html":"true"});
  $('.details').click(get_data_for_popover_and_display);
  $('.save-favorite').on('click', saveRecipe );
});

(function ($) {
    $('#search').on('click', function (e) {
      // remove resultset if this has already been run
      $('.recipes').empty();

      var recipeName = document.getElementById('recipeName').value;
      var recipeNameString = '&q=' + recipeName;

      var ingredientHtml = '&allowedIngredient[]=';
      var ingredientsArray = document.getElementById('ingredients').value.split(",");
      var ingredientsString = '';
      if (ingredientsArray[0] !== ""){
        for (i = 0; i < ingredientsArray.length; i++){
          ingredientsArray[i] = ingredientHtml + ingredientsArray[i].trim();
        }
        for (i = 0; i < ingredientsArray.length; i++){
          ingredientsString += ingredientsArray[i];
        }
      }

      var excludedIngredientHtml = '&excludedIngredient[]=';
      var excludedIngredientsArray = document.getElementById('ingredientsExclude').value.split(",");
      var excludedIngredientsString = '';
      if (excludedIngredientsArray[0] !== ""){
        for (i = 0; i < excludedIngredientsArray.length; i++){
          excludedIngredientsArray[i] = excludedIngredientHtml + excludedIngredientsArray[i].trim();
        }
        for (i = 0; i < excludedIngredientsArray.length; i++){
          excludedIngredientsString += excludedIngredientsArray[i];
        }
      }

      var dietHtml = '';
      if(document.getElementById('lacto-veg').checked){
        dietHtml += '&allowedDiet[]=388^Lacto vegetarian';
      }
      if(document.getElementById('ovo-veg').checked){
        dietHtml += '&allowedDiet[]=389^Ovo vegetarian';
      }
      if(document.getElementById('paleo').checked){
        dietHtml += '&allowedDiet[]=403^Paleo';
      }
      if(document.getElementById('pescetarian').checked){
        dietHtml += '&allowedDiet[]=390^Pescetarian';
      }
      if(document.getElementById('vegan').checked){
        dietHtml += '&allowedDiet[]=386^vegan';
      }
      if(document.getElementById('vegetarian').checked){
        dietHtml += '&allowedDiet[]=387^Lacto-ovo vegetarian';
      }

      var allergyHtml = '';
      if(document.getElementById('dairy-free').checked){
        allergyHtml += '&allowedAllergy[]=396^Dairy-Free';
      }
      if(document.getElementById('egg-free').checked){
        allergyHtml += '&allowedAllergy[]=397^Egg-Free';
      }
      if(document.getElementById('gluten-free').checked){
        allergyHtml += '&allowedAllergy[]=393^gluten-Free';
      }
      if(document.getElementById('peanut-free').checked){
        allergyHtml += '&allowedAllergy[]=394^Peanut-Free';
      }
      if(document.getElementById('seafood-free').checked){
        allergyHtml += '&allowedAllergy[]=398^Seafood-Free';
      }
      if(document.getElementById('seseme-free').checked){
        allergyHtml += '&allowedAllergy[]=399^Seseme-Free';
      }
      if(document.getElementById('sulfite-free').checked){
        allergyHtml += '&allowedAllergy[]=401^Sulfite-Free';
      }
      if(document.getElementById('tree-nut-free').checked){
        allergyHtml += '&allowedAllergy[]=395^Tree Nut-Free';
      }
      if(document.getElementById('wheat-free').checked){
        allergyHtml += '&allowedAllergy[]=392^Wheat-Free';
      }

      var apiHtml = 'http://api.yummly.com/v1/api/recipes?_app_id=&_app_key=' +recipeNameString;
      if (ingredientsString){
        apiHtml += ingredientsString;
      }
      if (excludedIngredientsString){
        apiHtml += excludedIngredientsString;
      }
      if (dietHtml){
        apiHtml += dietHtml;
      }
      if (allergyHtml){
        apiHtml += allergyHtml;
      }
      apiHtml += '&requirePictures=true';
      apiHtml = apiHtml.replace(' ', '%20');

      $.getJSON(apiHtml, function (json) {
        var recipes = [],
            $recipes;

        $.each(json, function (key, val) {
          if (key === "matches"){
            for (i = 0; i < val.length ; i++) {
              if (i%3 === 0){
                recipes.push('<div class="row">');
              }
              recipes.push('<div class="col-sm-6 col-md-4">');
              recipes.push('<div class="thumbnail">' + '<img src="'+ val[i].imageUrlsBySize[90] + '" alt="' + val[i].recipeName + '" data-holder-rendered="true" style="height: 300px; width: 100%; display: block;"/>');
              recipes.push('<div class="caption">' + '<h3 class="caption-text">' + val[i].recipeName + '</h3>');
              recipes.push('<p class="caption-text">' + val[i].sourceDisplayName + '</p>');
              recipes.push('<p><button type="button" class="btn btn-primary details" data-toggle="popover" title="' + val[i].recipeName + '" value="' + val[i].id + '"> Details </button> ');
              recipes.push('<button type="button" class="btn btn-primary save-favorite" method="post" action="saveFavorite" value="' + val[i].id + '"> Favorite </button></p>');
              recipes.push('</div></div></div>');
              if ((i+1)%3 === 0){
                recipes.push('</div>');
              }
            }
          }
        });
      if (recipes.length < 1) {
      recipes.push('<p>No results for parameters, try again!</p>');
      }
      $recipes = $('<div />').appendTo('.recipes');
      $recipes.append(recipes.join(''));
    });
    e.preventDefault();
  });
}(jQuery));


get_data_for_popover_and_display = function() {
  var el = $(this);
  if(el.hasClass('recipe-loaded')){
  }
  else {
    var _data = $(this).attr('alt');
    var recipeUrl = 'http://api.yummly.com/v1/api/recipe/' + this.value + '?_app_id=&_app_key=';
    var recipeHtml = '';
    var ingredientsHtml = '';
    var nutritionHtml = '';
    var ratingHtml = '';
    var servingsHtml = '';
    var sourceHtml = '';

    $.getJSON(recipeUrl, function (json) {
         $.each(json, function (key, val) {
           if (key === "ingredientLines"){
             ingredientsHtml = '<h4>Ingredients:</h4><ul>';
             for (i = 0; i < val.length ; i++){
               ingredientsHtml += ('<li>' + val[i] + '</li>');
             }
             ingredientsHtml += '</ul>';
           }
           if (key === "nutritionEstimates"){
             if(val.length > 0){
             nutritionHtml = 'Cal. per Serving: ' + val[0].value + '<br>';
             }
           }
           if (key === "rating"){
             ratingHtml += 'Rating: ' + val + '</p>';
           }
           if (key === "numberOfServings"){
             servingsHtml += '<p>Servings: ' + val + '<br>';
           }
           if (key === "source"){
             sourceHtml += '<p><a type="button" class="btn btn-primary details" href="'+ val.sourceRecipeUrl +'" >Source</a>';
           }
         })
       recipeHtml += ingredientsHtml;
       recipeHtml += servingsHtml;
       recipeHtml += nutritionHtml;
       recipeHtml += ratingHtml;
       recipeHtml += sourceHtml;
       el.attr('data-content', recipeHtml).success(el.popover('toggle'));
       el.addClass('recipe-loaded');
     });
  }
};

function saveRecipe(){
  var recipeUrl = 'http://api.yummly.com/v1/api/recipe/' + this.value + '?_app_id=3e5b7dbe&_app_key=1d681685a57dac07e6df0b1c0df38de6';
  var json = $.getJSON(recipeUrl, function (data){
  console.log(JSON.stringify(data));
   $.ajax({
       type: 'POST',
       data: data,
       url: '/saverecipe',
       dataType: 'JSON'
   });
 });
};

1 个答案:

答案 0 :(得分:0)

这一行:

$('.details').click(get_data_for_popover_and_display);

在将调用.detail的所有get_data_for_popover_and_display元素上连接一个事件处理程序,即使该元素已经有一个事件处理程序调用get_data_for_popover_and_display。与:相同:

$('.save-favorite').on('click', saveRecipe );

因为get_data_for_popover_and_display(至少)执行另一个ajax调用,它会添加另一个处理程序,随着时间的推移,你会得到越来越多的处理程序。

它完全是这样的:

&#13;
&#13;
function clickHandler() {
  console.log(+new Date(), "Clicked");
  clickComplete();
}
function clickComplete() {
  $("#btn").on("click", clickHandler);
}
clickComplete();
&#13;
<input type="button" id="btn" value="Click Me">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
&#13;
&#13;
&#13;

所以:如果你还没有这样做,只能添加一个处理程序。也许在jQuery&#39; data商店中跟踪:

&#13;
&#13;
function clickHandler() {
  console.log(+new Date(), "Clicked");
  clickComplete();
}
function clickComplete() {
  $("#btn").filter(function() {
    return !$(this).data("hasClick");
  })
  .on("click", clickHandler)
  .data("hasClick", true);
}
clickComplete();
&#13;
<input type="button" id="btn" value="Click Me">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
&#13;
&#13;
&#13;