有没有办法重构这个 Javascript for 循环?
Is there a way to refactor this Javascript for loop?
这是我用来学习 Javascript 的测试项目。我有一个带有 if 语句的 for 循环,然后进入 innerHTML。下面是一个for循环。我想知道如何用 say map() 做到这一点?我在网上查看了如何使用 maps() 但没有显示比初学者理解更复杂的东西......我是初学者。
for (let i = 0; i < data.length; i++) {
let dataTitle = data[i].title;
let dataTimeFrames = data[i].timeframes.daily;
if (dataTitle === 'Work') {
hours_work.innerHTML = `<p>${dataTimeFrames.current}hrs</p>`;
past_work.innerHTML = `<p>Yesterday - ${dataTimeFrames.previous}hrs</p>`;
}
if (dataTitle === 'Study') {
hours_play.innerHTML = `<p>${dataTimeFrames.current}hrs</p>`;
past_play.innerHTML = `<p>Yesterday - ${dataTimeFrames.previous}hrs</p>`;
}
if (dataTitle === 'Play') {
hours_study.innerHTML = `<p>${dataTimeFrames.current}hrs</p>`;
past_study.innerHTML = `<p>Yesterday - ${dataTimeFrames.previous}hrs</p>`;
}
if (dataTitle === 'Exercise') {
hours_exercise.innerHTML = `<p>${dataTimeFrames.current}hrs</p>`;
past_exercise.innerHTML = `<p>Yesterday - ${dataTimeFrames.previous}hrs</p>`;
}
if (dataTitle === 'Social') {
hours_social.innerHTML = `<p>${dataTimeFrames.current}hrs</p>`;
past_social.innerHTML = `<p>Yesterday - ${dataTimeFrames.previous}hrs</p>`;
}
if (dataTitle === 'Self Care') {
hours_care.innerHTML = `<p>${dataTimeFrames.current}hrs</p>`;
past_care.innerHTML = `<p>Yesterday - ${dataTimeFrames.previous}hrs</p>`;
}
}
这段代码工作得很好,我只是想学习如何重构这样的东西。
如果需要,这里是进一步了解的回购协议:https://github.com/tmerrick17/time-tracking-dashboard
所以,我要做的第一件事不是让你的元素已经确定,然后设置它们的 html,你可以有一个根据标题获取正确元素的函数,所以我想你有这样的东西:
var hours_care = document.getElementById("hours_care")
取而代之的是,拥有一个根据标题获取正确元素的功能。这样的东西会很好:
function getHoursAndPast (title) {
var lowerTitle = title.toLowerCase();
var hours = document.getElementById("hours_" + lowerTitle)
var past = document.getElementById("past_" + lowerTitle)
return [hours, past]
}
此函数returns您要获取的元素数组。然后,您可以在循环中使用它和 DE-structure 这个数组。我不会使用地图,因为您对从中获取数组不感兴趣。相反,使用 forEach
data.forEach(datum => {
let dataTitle = datum.title;
let dataTimeFrames = datum.timeframes.daily;
const [hours, past] = getHoursAndPast(dataTitle);
hours.innerHTML = `<p>${dataTimeFrames.current}hrs</p>`;
past.innerHTML = `<p>Yesterday - ${dataTimeFrames.previous}hrs</p>`;
})
一种方法是创建一个包含对 HTML 元素的引用的对象。这打破了循环中的数据特定信息,使其更易于管理。当然,您仍然需要处理有点冗长的 dataObj,这并不理想。
const dataObj = {
Work: {
hoursElement: document.getElementById('hours_work'),
pastElement: document.getElementById('past_work'),
},
Study: {
hoursElement: document.getElementById('hours_study'),
pastElement: document.getElementById('past_study'),
}
// Etc....
}
for (let i = 0; i < data.length; i++) {
let dataTitle = data[i].title;
let dataTimeFrames = data[i].timeframes.daily;
dataObj[dataTitle].hoursElement.innerHTML = `<p>${dataTimeFrames.current}hrs</p>`;
dataObj[dataTitle].pastElement.innerHTML = `<p>Yesterday - ${dataTimeFrames.previous}hrs</p>`;
}
使用一些 data-* 而不是 ID 会大大简化您的任务。
鉴于此 HTML 示例(在您的 GitHub 上找到):
<!-- Social Card -->
<div class="card-social">
<div class="card-top card-img">
<img src="public/images/icon-social.svg" alt="book icon">
</div>
<a class="card-bot-anchor" href="#">
<div class="card-bot card__info">
<h2>Social</h2>
<img src="public/images/icon-ellipsis.svg" alt="3 dots icon">
<p id="hours-social" data-title="Self Care" data-timeframe="current" class="hours-current margin-top1">hrs</p>
<p id="past-social" data-title="Self Care" data-timeframe="previous" class="past-toggle">Category Toggle</p>
</div>
</a>
</div>
注意插件
data-title="Self Care" data-timeframe="current"
你的循环将是
data.forEach(activity => {
let r = activity.title,
t = activity.timeframes.daily;
document.querySelector(`[data-title='${r}'][data-timeframe='current']`).innerHTML = `<p class="hours-current">${t.current}hrs</p>`);
document.querySelector(`[data-title='${r}'][data-timeframe='previous']`).innerHTML = `<p>Yesterday - ${t.previous}hrs</p>`;
}
而且很可能您可以丢弃 ID 和为它们创建的一堆变量。
这是我用来学习 Javascript 的测试项目。我有一个带有 if 语句的 for 循环,然后进入 innerHTML。下面是一个for循环。我想知道如何用 say map() 做到这一点?我在网上查看了如何使用 maps() 但没有显示比初学者理解更复杂的东西......我是初学者。
for (let i = 0; i < data.length; i++) {
let dataTitle = data[i].title;
let dataTimeFrames = data[i].timeframes.daily;
if (dataTitle === 'Work') {
hours_work.innerHTML = `<p>${dataTimeFrames.current}hrs</p>`;
past_work.innerHTML = `<p>Yesterday - ${dataTimeFrames.previous}hrs</p>`;
}
if (dataTitle === 'Study') {
hours_play.innerHTML = `<p>${dataTimeFrames.current}hrs</p>`;
past_play.innerHTML = `<p>Yesterday - ${dataTimeFrames.previous}hrs</p>`;
}
if (dataTitle === 'Play') {
hours_study.innerHTML = `<p>${dataTimeFrames.current}hrs</p>`;
past_study.innerHTML = `<p>Yesterday - ${dataTimeFrames.previous}hrs</p>`;
}
if (dataTitle === 'Exercise') {
hours_exercise.innerHTML = `<p>${dataTimeFrames.current}hrs</p>`;
past_exercise.innerHTML = `<p>Yesterday - ${dataTimeFrames.previous}hrs</p>`;
}
if (dataTitle === 'Social') {
hours_social.innerHTML = `<p>${dataTimeFrames.current}hrs</p>`;
past_social.innerHTML = `<p>Yesterday - ${dataTimeFrames.previous}hrs</p>`;
}
if (dataTitle === 'Self Care') {
hours_care.innerHTML = `<p>${dataTimeFrames.current}hrs</p>`;
past_care.innerHTML = `<p>Yesterday - ${dataTimeFrames.previous}hrs</p>`;
}
}
这段代码工作得很好,我只是想学习如何重构这样的东西。
如果需要,这里是进一步了解的回购协议:https://github.com/tmerrick17/time-tracking-dashboard
所以,我要做的第一件事不是让你的元素已经确定,然后设置它们的 html,你可以有一个根据标题获取正确元素的函数,所以我想你有这样的东西:
var hours_care = document.getElementById("hours_care")
取而代之的是,拥有一个根据标题获取正确元素的功能。这样的东西会很好:
function getHoursAndPast (title) {
var lowerTitle = title.toLowerCase();
var hours = document.getElementById("hours_" + lowerTitle)
var past = document.getElementById("past_" + lowerTitle)
return [hours, past]
}
此函数returns您要获取的元素数组。然后,您可以在循环中使用它和 DE-structure 这个数组。我不会使用地图,因为您对从中获取数组不感兴趣。相反,使用 forEach
data.forEach(datum => {
let dataTitle = datum.title;
let dataTimeFrames = datum.timeframes.daily;
const [hours, past] = getHoursAndPast(dataTitle);
hours.innerHTML = `<p>${dataTimeFrames.current}hrs</p>`;
past.innerHTML = `<p>Yesterday - ${dataTimeFrames.previous}hrs</p>`;
})
一种方法是创建一个包含对 HTML 元素的引用的对象。这打破了循环中的数据特定信息,使其更易于管理。当然,您仍然需要处理有点冗长的 dataObj,这并不理想。
const dataObj = {
Work: {
hoursElement: document.getElementById('hours_work'),
pastElement: document.getElementById('past_work'),
},
Study: {
hoursElement: document.getElementById('hours_study'),
pastElement: document.getElementById('past_study'),
}
// Etc....
}
for (let i = 0; i < data.length; i++) {
let dataTitle = data[i].title;
let dataTimeFrames = data[i].timeframes.daily;
dataObj[dataTitle].hoursElement.innerHTML = `<p>${dataTimeFrames.current}hrs</p>`;
dataObj[dataTitle].pastElement.innerHTML = `<p>Yesterday - ${dataTimeFrames.previous}hrs</p>`;
}
使用一些 data-* 而不是 ID 会大大简化您的任务。
鉴于此 HTML 示例(在您的 GitHub 上找到):
<!-- Social Card -->
<div class="card-social">
<div class="card-top card-img">
<img src="public/images/icon-social.svg" alt="book icon">
</div>
<a class="card-bot-anchor" href="#">
<div class="card-bot card__info">
<h2>Social</h2>
<img src="public/images/icon-ellipsis.svg" alt="3 dots icon">
<p id="hours-social" data-title="Self Care" data-timeframe="current" class="hours-current margin-top1">hrs</p>
<p id="past-social" data-title="Self Care" data-timeframe="previous" class="past-toggle">Category Toggle</p>
</div>
</a>
</div>
注意插件
data-title="Self Care" data-timeframe="current"
你的循环将是
data.forEach(activity => {
let r = activity.title,
t = activity.timeframes.daily;
document.querySelector(`[data-title='${r}'][data-timeframe='current']`).innerHTML = `<p class="hours-current">${t.current}hrs</p>`);
document.querySelector(`[data-title='${r}'][data-timeframe='previous']`).innerHTML = `<p>Yesterday - ${t.previous}hrs</p>`;
}
而且很可能您可以丢弃 ID 和为它们创建的一堆变量。