我想使用javascript循环来创建多个HTML包装器元素,并将JSON响应API数据插入到一些元素(图像,标题,网址等)中。
这是我需要逐行进行的吗?
<a class="scoreboard-video-outer-link" href="">
<div class="scoreboard-video--wrapper">
<div class="scoreboard-video--thumbnail">
<img src="http://via.placeholder.com/350x150">
</div>
<div class="scoreboard-video--info">
<div class="scoreboard-video--title">Pelicans @ Bulls Postgame: E'Twaun Moore 10-8-17</div>
</div>
</div>
</a>
我在尝试什么:
var link = document.createElement('a');
document.getElementsByTagName("a")[0].setAttribute("class", "scoreboard-video-outer-link");
document.getElementsByTagName("a")[0].setAttribute("url", "google.com");
mainWrapper.appendChild(link);
var videoWrapper= document.createElement('div');
document.getElementsByTagName("div")[0].setAttribute("class", "scoreboard-video-outer-link");
link.appendChild(videoWrapper);
var videoThumbnailWrapper = document.createElement('div');
document.getElementsByTagName("div")[0].setAttribute("class", "scoreboard-video--thumbnail");
videoWrapper.appendChild(videoThumbnailWrapper);
var videoImage = document.createElement('img');
document.getElementsByTagName("img")[0].setAttribute("src", "url-of-image-from-api");
videoThumbnailWrapper.appendChild(videoImage);
然后我基本上为所有嵌套的HTML元素重复该过程。
将A-tag附加到主包装
创建DIV
如果你能告诉我最好的方法去做我想在这里解释的事情,我会非常感激吗?好像它会变得非常混乱。
答案 0 :(得分:2)
您会找到许多解决此问题的工作的解决方案。但这可能不是重点。关键是:是不是?你可能会使用错误的工具解决问题。
我使用过做过类似事情的代码。我没有写它,但我必须使用它。您会发现像这样的代码很快就变得非常难以管理。你可能会想:“哦,但我知道它应该做什么。一旦完成,我就不会改变它。”
代码分为两类:
所以,“它有效吗?”这不是正确的问题。有很多问题,但其中一些问题是:“我能保持这个吗?它是否易于阅读?如果我改变一个部分,它是否只改变了我需要改变的部分,还是改变了别的东西我不是故意改变?“
我在这里得到的是你应该使用模板库。有许多JavaScript。
通常,您应该使用整个JavaScript应用程序框架。现在有三个主要的:
为了诚实,请注意我不遵循自己的建议,仍然使用Angular。 (原来的,不是Angular 2.)但这是一个陡峭的学习曲线。有很多库也包含模板能力。
但是您显然已经设置了整个项目,并且您只想将模板插入现有的 JavaScript代码中。您可能想要一种模板语言,它可以完成它的工作并且不会受到影响。当我开始时,我也想要那样。我用了Markup.js。它很小,很简单,它可以在这篇文章中做到你想要的。
https://github.com/adammark/Markup.js/
这是第一步。我认为它loops feature正是你所需要的。从那开始,及时完成一个完整的框架。
答案 1 :(得分:2)
这是我的答案。它的标记。为了查看代码段中的效果,您必须进入开发人员控制台,以检查包装器元素或查看开发人员控制台日志。
我们基本上创建了一些辅助方法来轻松创建元素并将它们附加到DOM - 它实际上并不像看起来那么难。这也应该让您可以轻松地将JSON检索到的对象作为属性附加到元素中!
这是一个基本版本,为您提供有关发生的事情以及如何使用它的要点
//create element function
function create(tagName, props) {
return Object.assign(document.createElement(tagName), (props || {}));
}
//append child function
function ac(p, c) {
if (c) p.appendChild(c);
return p;
}
//example:
//get wrapper div
let mainWrapper = document.getElementById("mainWrapper");
//create link and div
let link = create("a", { href:"google.com" });
let div = create("div", { id: "myDiv" });
//add link as a child to div, add the result to mainWrapper
ac(mainWrapper, ac(div, link));
//create element function
function create(tagName, props) {
return Object.assign(document.createElement(tagName), (props || {}));
}
//append child function
function ac(p, c) {
if (c) p.appendChild(c);
return p;
}
//example:
//get wrapper div
let mainWrapper = document.getElementById("mainWrapper");
//create link and div
let link = create("a", { href:"google.com", textContent: "this text is a Link in the div" });
let div = create("div", { id: "myDiv", textContent: "this text is in the div! " });
//add link as a child to div, add the result to mainWrapper
ac(mainWrapper, ac(div, link));
&#13;
div {
border: 3px solid black;
padding: 5px;
}
&#13;
<div id="mainWrapper"></div>
&#13;
以下是如何使用更详尽的注释代码专门执行您所要求的内容。
//get main wrapper
let mainWrapper = document.getElementById("mainWrapper");
//make a function to easily create elements
//function takes a tagName and an optional object for property values
//using Object.assign we can make tailored elements quickly.
function create(tagName, props) {
return Object.assign(document.createElement(tagName), (props || {}));
}
//document.appendChild is great except
//it doesn't offer easy stackability
//The reason for this is that it always returns the appended child element
//we create a function that appends from Parent to Child
//and returns the compiled element(The Parent).
//Since we are ALWAYS returning the parent(regardles of if the child is specified)
//we can recursively call this function to great effect
//(you'll see this further down)
function ac(p, c) {
if (c) p.appendChild(c);
return p;
}
//these are the elements you wanted to append
//notice how easy it is to make them!
//FYI when adding classes directly to an HTMLElement
//the property to assign a value to is className -- NOT class
//this is a common mistake, so no big deal!
var link = create("a", {
className: "scoreboard-video-outer-link",
url: "google.com"
});
var videoWrapper = create("div", {
className: "scoreboard-video-outer-link"
});
var videoThumbnailWrapper = create("div", {
className: "scoreboard-video--thumbnail"
});
var videoImage = create("img", {
src: "url-of-image-from-api"
});
//here's where the recursion comes in:
ac(mainWrapper, ac(link, ac(videoWrapper, ac(videoThumbnailWrapper, videoImage))));
//keep in mind that it might be easiest to read the ac functions backwards
//the logic is this:
//Append videoImage to videoThumbnailWrapper
//Append (videoImage+videoThumbnailWrapper) to videoWrapper
//Append (videoWrapper+videoImage+videoThumbnailWrapper) to link
//Append (link+videoWrapper+videoImage+videoThumbnailWrapper) to mainWrapper
let mainWrapper = document.getElementById('mainWrapper');
function create(tagName, props) {
return Object.assign(document.createElement(tagName), (props || {}));
}
function ac(p, c) {
if (c) p.appendChild(c);
return p;
}
var link = create("a", {
className: "scoreboard-video-outer-link",
url: "google.com"
});
var videoWrapper = create("div", {
className: "scoreboard-video-outer-link"
});
var videoThumbnailWrapper = create("div", {
className: "scoreboard-video--thumbnail"
});
var videoImage = create("img", {
src: "url-of-image-from-api"
});
ac(mainWrapper, ac(link, ac(videoWrapper, ac(videoThumbnailWrapper, videoImage))));
//pretty fancy.
//This is just to show the output in the log,
//feel free to just open up the developer console and look at the mainWrapper element.
console.dir(mainWrapper);
&#13;
<div id="mainWrapper"></div>
&#13;
答案 2 :(得分:1)
看看这个 - [underscore._template] 它非常小,在这种情况下很有用。 (https://www.npmjs.com/package/underscore.template)。
const targetElement = document.querySelector('#target')
// Define your template
const template = UnderscoreTemplate(
'<a class="<%- link.className %>" href="<%- link.url %>">\
<div class="<%- wrapper.className %>">\
<div class="<%- thumbnail.className %>">\
<img src="<%- thumbnail.image %>">\
</div>\
<div class="<%- info.className %>">\
<div class="<%- info.title.className %>"><%- info.title.text %></div>\
</div>\
</div>\
</a>');
// Define values for template
const obj = {
link: {
className: 'scoreboard-video-outer-link',
url: '#someurl'
},
wrapper: {
className: 'scoreboard-video--wrapper'
},
thumbnail: {
className: 'scoreboard-video--thumbnail',
image: 'http://via.placeholder.com/350x150'
},
info: {
className: 'scoreboard-video--info',
title: {
className: 'scoreboard-video--title',
text: 'Pelicans @ Bulls Postgame: E`Twaun Moore 10-8-17'
}
}
};
// Build template, and set innerHTML to output element.
targetElement.innerHTML = template(obj)
// And of course you can go into forEach loop here like
const arr = [obj, obj, obj]; // Create array from our object
arr.forEach(item => targetElement.innerHTML += template(item))
<script src="https://unpkg.com/underscore.template@0.1.7/dist/underscore.template.js"></script>
<div id="target">qq</div>