经过几个小时的压力,我刚刚让这段代码开始工作。我是 Javascript 新手,所以我不确定我是否以最有效的方式做到了这一点。我正在使用 IEX 提供的 API。这段代码的目标是当有消息时输出消息。正如你所知,这并不完全有效,但我确实让标题发挥了作用。因此,如果我做错了什么,请告诉我。
<html>
<head>
<style>
/* Outter Table <Tbody> Settings*/
.outtertable tbody {
vertical-align: top;
}
/* Innertable Table data settings */
.innertable tr > td {
vertical-align: top;
}
/* Div Article Holder Settings */
.divBorder {
margin-bottom: 10px;
border: solid;
border-color: #c4ef8b;
border-width: 4px 0px 0px 0px;
}
/* Article Image settings */
.articleImg {
height:50px;
width: 50px;
}
/* DivBorder Mouse Hover */
.divBorder:hover {
cursor: pointer;
background-color: #f3ffe5;
}
</style>
</head>
<body>
<table class="outterTable" id="newsContent"></table>
</body>
<script>
var request = new XMLHttpRequest();
request.open ('GET', 'https://api.iextrading.com/1.0/stock/spy/news')
//on request load
request.onload = function() {
//VARIABLES
var newsContainer = document.getElementById("newsContent");
var JSONData = JSON.parse(request.responseText);
var articleAmount = JSONData.length;
var rowAmount = articleAmount / 3;
var rowAmountRoundDown= Math.trunc(rowAmount);
var rowAmountRoundUp = (Math.trunc(rowAmount) + 1);
var remainder = (rowAmount - Math.floor(rowAmount)).toFixed(2); //.00, .67, or .33;
//=== TABLE CREATOR =============================================
//Create an "<tbody>" element
let tbodyHTML = document.createElement('tbody');
//"Assembler" inside is "createTable()"
tbodyHTML.innerHTML = createTable();
//FUNCTION Create Table
function createTable() {
var tData = '';
var index = 0;
//========= First Table Part Row Loop ===========================================================
for (var i = 1; i <= rowAmountRoundDown; i++) {
//Row Start
tData = tData + `
<tr>
`;
//Content: <td> <div> <table> <tr> <td>
for (var c = 1 + index; c < 4 + index; c++) {
tData = tData + `
<td style="width: 33.33%; padding: 0px 25px">
<div class="divBorder">
<table class="innerTable">
<tbody>
<tr>
<td>
<img class="articleImg" src="images/seeking-alpha-badge.png" id="image${c}">
</td>
<td style="padding-left: 5px">
<h3 id="headline${c}"></h3>
</td>
</tr>
</tbody>
</table>
</div>
</td>
`;
}
//Row End
tData = tData + `
</tr>
`;
index = index + 3;
}
//========= Second table part =====================================================================
//If remainder is .67 create 2 <td>
if (remainder == 0.67) {
//Row Start
tData = tData + `
<tr>
`;
//Content: <td> <div> <table> <tr> <td>
for (var c2 = (1 + index); c2 < (3 + index); c2++){
tData = tData + `
<td style="width: 33.33%; padding: 0px 25px">
<div class="divBorder">
<table class="innerTable">
<tbody>
<tr>
<td>
<img class="articleImg" src="images/seeking-alpha-badge.png" id="image${c2}">
</td>
<td style="padding-left: 5px">
<h3 id="headline${c2}"></h3>
</td>
</tr>
</tbody>
</table>
</div>
</td>
`;
}
//row End
tData = tData + `
</tr>
`;
//If remainder is .33 create 1 <Td>
} else if (remainder == 0.33) {
//Row Start
tData = tData + `
<tr>
`;
//Content: <td> <div> <table> <tr> <td>
for (var c = (1 + index); c < (2 + index); c++){
tData = tData + `
<td style="width: 33.33%; padding: 0px 25px">
<div class="divBorder">
<table class="innerTable">
<tbody>
<tr>
<td>
<img class="articleImg" src="images/seeking-alpha-badge.png" id="image${c}">
</td>
<td style="padding-left: 5px">
<h3 id="headline${c}"></h3>
</td>
</tr>
</tbody>
</table>
</div>
</td>
`;
}
//row End
tData = tData + `
</tr>
`;
//Anything else dont do anything
} else {
tData = tData;
}
return tData;
}
//Inject into the HTML
newsContainer.appendChild(tbodyHTML);
//===============================================================
var red = (JSONData.length + 1)
console.log(red);
//Output data to html
for (var l = 1; l < red; l++){
console.log("l: " + l);
spyOutputToHTML(JSONData, l);
}
};
function spyOutputToHTML(data, i) {
//get current variables in this HTML page x3
var offset = i - 1;
var headline = document.getElementById(`headline${i}`);
//Get Content From the JSON file ex: ".latestPrice"
var JSONHeadline = data[offset].headline;
//Inject data into HTML
headline.innerHTML = JSONHeadline;
}
request.send()
</script>
最佳答案
首先,干得好! 对于 javascript 新手来说,这是令人印象深刻的工作
确实没有什么可以改进的,但我不认为你做错了什么。也许,只有 remainder
的逻辑太困惑了。我打赌应该有一个更简单的方法
可读性
如果您将 View (模板)逻辑、请求逻辑和数据“按摩”逻辑分开,您的代码无疑会更容易阅读和理解
View 逻辑
通常,“手动”构建 HTML 结构( createElement
、 appendChild
)需要更多的努力,并且可以说,与使用模板函数渲染字符串(有点像您所做的那样)和注入(inject)相比,更令人困惑在您需要的地方得到结果。混合使用这些方法比“手工”完成所有事情更容易出错。因此,我建议您使用一个 View /模板函数来获取数据并返回一个字符串
function renderTable(data) {
var result = '<div>';
// build the result string...
result += '</div>';
return result;
}
// and then...
targetEl.innerHTML = renderTable(data);
您可能还想利用 micro-templating 。对于较大的应用程序来说,一种或另一种模板是必需的。让自己熟悉模板引擎。对于您的项目,使用 javascript 构建字符串就可以了。虽然,还有一个更advanced您可以考虑的技术
数据“按摩”逻辑
好吧,这归结为您的模板函数对其上下文(基本的关注点分离)并不“智能”,而仅消耗数据。不是“煮”它,只是吃它:)
所以,不要这样做
function renderTable(data) {
var result = '<div>';
var something = data.abc * data.xyz;
// do something with something here
result += '</div>';
return result;
}
targetEl.innerHTML = renderTable(data);
...你这样做
function adaptResponsePayloadData(data) {
var result = { ...data };
result.something = result.abc * result.xyz;
return result;
}
function renderTable(data) {
// ...
}
targetEl.innerHTML = renderTable(adaptResponsePayloadData(data));
这是所谓的适配器设计模式的一个示例。这是使用它的正确情况。还有很多其他design patterns我强烈建议您花时间熟悉它们
请求逻辑
这里还有一个值得关注的分离问题。您可以将请求逻辑放在单独的函数中,类似于我们从上面的 View 中分离“按摩”的方式
const API_ENDPOINT_URL = 'https://api.iextrading.com/1.0/stock/spy/news';
function fetchData(callback) {
var request = new XMLHttpRequest();
request.open('GET', API_ENDPOINT_URL);
request.onLoad(() => {
var data = JSON.parse(request.responseText);
callback(data);
});
request.send();
}
// ... and then
fetchData(data => {
// ...
targetEl.innerHTML = renderTable(adaptResponsePayloadData(data));
});
执行顺序注意事项
有一个经验法则可以让你的代码何时运行变得清晰。这完全是一个挑剔,但可以在代码级别将内容与时间分开
function goOn() { // there are many conventional names for this, like `main`
fetchData(data => {
document.body.innerHTML = renderTable(adaptResponsePayloadData(data));
});
}
window.onload = goOn;
HTML 和 CSS 注释
你并不真的需要
<tbody>
。除非你想用 CSS 突出显示某些内容,否则不需要它避免使用内联样式,例如
<td style="width: 33.33%; padding: 0px 25px">
。你可以用 CSS 来表达您不需要
divBorder
类(class)。向父级添加填充td
和 child 的边框table
其他小注释
按照惯例,第一个大写字母的名称是对象构造函数或类。简单地说,将常规变量名称设为小驼峰命名,例如 jsonHeadline
JSON 是我们所知道的表示法术语。当我们解析该符号的字符串时,它只是变成 data
或contextData
,你明白了...然后,数据里面的内容就变成了 headline
尽力命名变量,这样您就不必编写注释来理解您的含义。查找其他好提示here
确保您的生产代码没有 console.log
声明
let
关键字比 var
更安全。你永远不会用它污染全局范围
请注意有Code Review on StackExchange在这里您可以学习如何编写优秀代码的许多其他方面
你做得真棒。祝您旅途顺利! :)
关于javascript - 我如何简化这段代码?有更好的方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54564972/