【问题标题】:Within an if-statement inside of a loop, how can I get the children of an element and push them into an array?在循环内的 if 语句中,如何获取元素的子元素并将它们推送到数组中?
【发布时间】:2015-04-29 23:05:09
【问题描述】:

我正在使用 JavaScript 和 jQuery 制作膳食计划/杂货清单应用程序。基本上,它是这样工作的:

  1. 用户通过表单添加食谱。用户输入食谱的名称以及与该食谱相关的成分。
  2. 提交后,每个配方都存储在<dl id="recipeList"> 元素中。配方名称存储为<dt class="recipe">,每种成分存储为<dd class="ingredient">
  3. 对于一周中的每一天,用户可以单击“计划膳食”锚点。这将显示#recipeList 的副本。当用户点击<dt> 时,class="meal" 会应用到它,并删除列表的其余部分。
  4. 下一步是让用户单击“生成杂货清单”锚点。当用户这样做时,JavaScript 应该遍历每个.meal 并创建一个数组#mealsArray。然后 JavaScript 应该遍历每个 class="recipe" 并检查它的 .innerHTML 是否与 #mealsArray 中的项目匹配。它这样做很好,但是问题是在找到匹配项后,它应该获取class="recipe" 的孩子(即<dt class="ingredient">)并将它们推入#groceriesArray

JavaScript 不会找到 <dt class="recipe"> 的子代。我尝试了多种编码方式,例如:

  • this.children
  • this.childNodes
  • this.children()
  • this.children("dt")
  • this.children(".ingredient")
  • this.contents()
  • this.find(".ingredient")

它通常会发现像[Object HTMLElement] 这样的奇怪的东西,或者返回像Type Error: this.children() is not a function 这样的错误消息。

看起来就是这么简单,但我不知道该怎么做。我将在下面提供我的代码——为它的草率道歉。

这是 HTML:

<form id="addRecipeForm">
    <label>Name</label><input type="text" id="recipeName">
    <label>Ingredients</label><input type="text" class="recipeIngredients">
    <label>Ingredients</label><input type="text" class="recipeIngredients">
    <label>Ingredients</label><input type="text" class="recipeIngredients">
    <button id="recipeButton">Add Recipe</button>
</form>

<dl id="recipeList"></dl>

<div>
    <h3>Sunday</h3>
    <a href="#" class="planAnchor">Plan a Meal</a>
</div>
<div>
    <h3>Monday</h3>
    <a href="#" class="planAnchor">Plan a Meal</a>
</div>
<!-- And so on, until Saturday -->

<a href="#" id="groceryListAnchor">Generate Grocery List</a>
<ul id="groceryList"></ul>

这里是 JavaScript:

var recipeList = $("#recipeList");
var recipeIngredients = $(".recipeIngredients");
var planAnchor = $(".planAnchor");
var groceryListAnchor = $("#groceryListAnchor");
var groceryList = $("#groceryList");

////////// ADD A RECIPE //////////
$("#recipeButton").click(function(e) {
    e.preventDefault();
    var recipeName = $("#recipeName").val();
    var recipeIngredients = $(".recipeIngredients");

    recipeList.append("<dt class='recipe'></dt>");
    recipeList.children("dt").last().text(recipeName);

    for (i = 0; i < recipeIngredients.length ; i++) {
        $("<dd class='ingredient'></dd>").text(recipeIngredients[i].value).appendTo(recipeList);
    };
});

////////// PLAN A MEAL //////////
planAnchor.click(function(e) {
    e.preventDefault();
    var dayInPlanning = $(this).parent("div");
    var availableRecipes = recipeList.clone();

    availableRecipes.children("dd").remove();
    availableRecipes.attr("id", "availableRecipes");
    $(this).parent("div").append(availableRecipes);
    $(this).remove();

availableRecipes.children("dt").click(function(e) {
    e.preventDefault();
    var selectedRecipe = $(this);
    var para = $("<p class='meal'></p>");

    para.appendTo(dayInPlanning);
    para.text(selectedRecipe.text());

    availableRecipes.remove();
});

////////// GENERATE GROCERY LIST //////////
///////// THIS IS WHERE THE PROBLEM LIES //////////
groceryListAnchor.click(function(e) {
    e.preventDefault();
    var mealsArray = [];
    var groceriesArray = [];

    // Create an array of .meal elements
    $(".meal").each(function() {
        mealsArray.push(this.innerHTML);
    });

    console.log("mealsArray is " + mealsArray);

    $(".recipe").each(function() {
        console.log("Checking " + this.innerHTML);
        // Match the innerHTML of each .recipe to the items in the mealsArray
        if ($.inArray(this.innerHTML, mealsArray) > -1) {
            console.log("We found " + this.innerHTML + " in the array!");
            // Get the children of that recipe, and place them in groceriesArray
            // *** Not Working ***
            groceriesArray.push(this.children.innerHTML)

        } else {};

    });
    console.log("The grocery list is " + groceriesArray);
});

【问题讨论】:

    标签: javascript jquery arrays this children


    【解决方案1】:

    简单地解释一下。它们是两种类型的元素 jQuery ElementsJavaScript Elementsthis 是一个 JavaScript 元素。 jQuery 函数仅适用于 jQuery 元素。因此,要使其正常工作,请使用:

    $(this).myjQueryFunction();
    

    所以对你来说:

    $(this).children();
    


    深入

    当使用$() 创建 jQuery 元素时,它会做一些事情。 jQuery 使用 Sizzle 来选择元素。如果传入$() 的内容已经是一个元素。它什么也没做。它是,它将把它变成一个元素。取决于使用两个 jQuery 中的哪一个。它将返回一个元素。这是一个常规的 JavaScript 元素,但是是什么让它如此特别呢? jQuery 函数只能$ 之后运行。原因在于您如何使用原型创建链式 JavaScript 函数:

    //Kind of how it's created
    $.prototype.children = function () {
        //jQuery's code to get children
    }
    

    这使得children() 只能运行在$ 之外。

    【讨论】:

    • 感谢您的回复。我将其更改为 $(this).children() 并在 if 语句中添加了 console.logconsole.log($(this).children()) 返回[object Object]。因此,[object Object]s 被添加到数组中。你知道它为什么这样做吗?
    • @Michael 我修复了你的程序中的一个错误:jsfiddle.net/7hv7opjy 但是$(this).children().html() 将无法工作,因为你需要将$(this).children() 通过 each
    【解决方案2】:

    你可以尝试将这个 Dom 元素转换为 jQuery 元素吗:

     //so instead of this.children() use
     $(this).children()
    

    在这种情况下,如果您想要 HTML,它将是

     $(this).children().html()
    

    但它只会让您获得第一个子 HTML,您可以尝试以下方式来获取所有内容:

    html_contents = ""
    $.each($(this).children(), function(){
     html_contents+=$(this).html();
    });
    

    【讨论】:

    • 谢谢。我将其更改为$(this).children().html(),但它似乎仍然无法正常工作。我将console.log($(this).children().html()) 放在if 语句中,它返回undefined
    • 因为这个会返回给第一个孩子,如果你愿意的话,你需要遍历孩子并为每个孩子获取 .html()
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-10
    • 2019-02-24
    相关资源
    最近更新 更多