在html模板上追加/前置div的javascript逻辑

在html模板上追加/前置div的javascript逻辑,javascript,jquery,html,css,Javascript,Jquery,Html,Css,我编写了一个非常基本的web应用程序,可以从API中提取配方数据。通过将数据推送到javascript文件中定义的html模板来呈现数据。布局通过CSS中的浮动网格进行控制 呈现结果并推送到模板的代码部分: function displayRecipeSearchData(data) { var results = ' '; if (data.hits.length) { data.hits.forEach(function(item) { results += te

我编写了一个非常基本的web应用程序,可以从API中提取配方数据。通过将数据推送到javascript文件中定义的html模板来呈现数据。布局通过CSS中的浮动网格进行控制

呈现结果并推送到模板的代码部分:

function displayRecipeSearchData(data) {
  var results = ' ';
  if (data.hits.length) {
    data.hits.forEach(function(item) {
      results += template.item(item);
    });
  }
  else {
    results += '<p> No results </p>';
  }
  $('#js-search-results').html(results);
}
函数显示RecipeSearchdata(数据){
var结果=“”;
if(数据点击数长度){
data.hits.forEach(函数(项){
结果+=模板项(项);
});
}
否则{
结果+='无结果

; } $(“#js搜索结果”).html(结果); }
显示响应的html模板:

const template = {
  item: function(item) {
    return '<div class ="col-4">' +
             '<div class ="result">' +
               '<div class="recipelabel">' +
                 '<div class="reclist">' + item.recipe.ingredientLines + '</div><!-- end reclist -->' +
                  '<p class="label">' + item.recipe.label + '</p>' +
                  '<div class="thumbnail">' + 
                    '<a href="'+ httpsTransform(item.recipe.url) + '" target="_blank">' +
                      '<img src="' + item.recipe.image + '"alt="' + item.recipe.label + '">' +
                    '</a>' +
                    '<div class="recipesource">' +
                      '<p class="source">' + item.recipe.source + '</p>' +
                    '</div><!-- end recipesource -->' +
                  '</div><!-- end thumbnail -->' +
                '</div><!-- end recipelabel -->' +
              '</div><!-- end result -->' + 
            '</div><!-- end col-4 -->';
  }
};
const模板={
项目:功能(项目){
返回“”+
'' +
'' +
''+item.recipe.ingredientLines+''中+
“

”+item.recipe.label+”

'+ '' + '' + '' + “

”+item.recipe.source+”

'+ '' + '' + '' + '' + ''; } };
我试图更改displayRecipeSearchData函数中的逻辑,以便对于每组三个结果,一个
包围三个结果块。这使得行/列始终在flex网格中工作。我已经尝试了几种方法,但尚未获得正确的语法/逻辑。嵌套在现有语句中的if语句是否有效

if(i % 3 === 0 ){ results. += '<div class="row">''</div>'}
if(i%3===0){results.+=''''''}

任何建议都将不胜感激。

您可以使用另一个变量来存储一行HTML:

function displayRecipeSearchData(data) {
  var results = ' ', row = '';
  if (data.hits.length) {
    data.hits.forEach(function(item, i) {
      row += template.item(item);
      if (i % 3 == 2) { // wrap row and add to result
        results += '<div class="row">' + row + '</div>';
        row = '';
      }
    });
    if (row.length) { // flush remainder into a row
      results += '<div class="row">' + row + '</div>';
    }
  }
  else {
    results += '<p> No results </p>';
  }
  $('#js-search-results').html(results);
}
函数显示RecipeSearchdata(数据){
var结果=“”,行=“”;
if(数据点击数长度){
data.hits.forEach(函数(第i项){
行+=模板项(项);
如果(i%3==2){//换行并添加到结果
结果+=''+行+'';
行=“”;
}
});
if(row.length){//将余数刷新到一行中
结果+=''+行+'';
}
}
否则{
结果+='无结果

; } $(“#js搜索结果”).html(结果); }
在我看来,你做这件事肯定很难

您应该使用javascripts内置的元素创建,而不是手动将模板编写为字符串并尝试在正确的位置注入字符串(可能会创建无效的html)。此外,它将更加模块化,以在自己的函数中创建子函数。使用函数而不是对象来保存对象创建者也会容易得多。我的版本可能有更多的代码,但从长远来看,修改会容易得多

const Itemizer = function(){
  this.items = [];
  const createEl = function(elType, classes, attributes, text, html){
    let el = document.createElement(elType)
    for(let i = 0; i < classes.length; i++){
      el.classList.add(classes[i]
    }
    for(let attr in attributes){
      el.setAttribute(attr, attributes[attr])
    }
    if(text){
      el.innerText = text
    }
    if(html){
      el.innerHTML = html
    }
    return el
  };

  const createThumbnail = function(url, image, alt, source){
    let thumbnail = createEl("DIV", ["thumbnail"]),
        link = createEl("A", [], {href: httpsTransform(url)}),
        img = createEl("IMG", [], {src: image, alt: label});
        rSource = createRecipeSource(source)
    link.appendChild(img);
    thumbnail.appendChild(link);
    thumbnail.appendChild(rSource)
    return thumbnail
  };

  const createRecipeSource = function(source){
    let wrapper = createEl("DIV", ["recipe-source"]);
    wrapper.appendChild(createEl("P", ["source"], {}, source))
    return wrapper
  }

  const createRecipeLabel = function({
    recipe: {
      ingredientLines,
      label,
      url,
      source
    }
  }){
    let labelWrapper = createEl("DIV", ["recipe-label"),
        ingredients = createEl("DIV", ["rec-list"], {}, false, ingredientLines),
        recipeLabel = createEl("P", ["label"], {}, label),
        thumbnail = createThumbnail(url, image, label, source)
    labelWrapper.appendChild(ingredients)
    labelWrapper.appendChild(recipeLabel)
    labelWrapper.appendChild(thumbnail)
    return labelWrapper
  }

  const createNewItem = function(data){
    let columnWrapper = createEl("DIV", ["col-4"]),
        result = createEl("DIV", ["result"]),
        label = createRecipeLabel(data)

    columnWrapper.appendChild(result)
    result.appendChild(label)
    this.items.push(columnWrapper)
    return columnWrapper
  }.bind(this)

  const getItems = function(){
   return this.items
  }.bind(this)

  const getRows = function(){
    const rows = []
    let row;
    for(let i = 0; i < this.items.length; i++){
      const item = this.items[i]
      if(i % 3 === 0){
        row = createEl("DIV", ["row"])
        rows.push(row)
      }
      row.appendChild(item)
    }
    return rows;
  }.bind(this)

  return {
    add: createNewItem,
    get: getItems,
    rows: getRows
  }
}
const Itemizer=function(){
此参数为.items=[];
const createEl=函数(elType、类、属性、文本、html){
设el=document.createElement(elType)
for(设i=0;i
然后,您可以使用如下功能:

const template = new Itemizer()
function displayRecipeSearchData(data) {
  let rows
  if (data.hits.length) {
    for(let i = 0; i < data.hits.length; i++){
      template.add(data.hits[i])
    }
    rows = template.rows()
  } else {
    const p = document.createElement("P")
    p.innerText = "No Results")
    rows = [p]
  }
  const resultsWrapper = document.getElementById("js-search-results");
  for(let i = 0; i < rows.length; i++){
    resultsWrapper.appendChild(rows[i])
  }
}
const template=new Itemizer()
函数显示RecipeSearchData(数据){
让争吵
if(数据点击数长度){
for(设i=0;i
用连字符分隔css类也是一种很好的形式,因此我替换了一些类名以反映这一点

还需要注意的是,您实际上不需要超过一行。如果您将所有项目包装在一行中,当它们达到网格限制时,节列将自动溢出到下一行

M