【发布时间】:2017-06-15 12:09:48
【问题描述】:
我完成了这个简单应用程序的功能方面,但现在我还想添加一些好的用户体验,所以我想在 JSON 加载时以及在它显示承诺结果之前添加一个加载动画(微调器),但我似乎无法通过谷歌搜索找到解决方案。
这是笔:https://codepen.io/kresimircoko/pen/ZLJjVM。
这里是 JavaScript 代码:
const API_KEY = '?api_key=625023d7336dd01a98098c0b68daab7e';
const root = 'https://www.warcraftlogs.com:443/v1/';
const zonesBtn = document.querySelector('#zones');
const responseList = document.querySelector('#response');
console.clear();
const requestJSON = objType => {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onload = function() {
try {
resolve(JSON.parse(this.responseText));
}
catch (e) {
reject(e);
}
};
xhr.onerror = reject;
xhr.open('GET', root + objType + API_KEY);
xhr.send();
});
};
function displayBosses(zoneID) {
let bosses = document.querySelectorAll(`.bosses[data-zoneid="${zoneID}"]`);
requestJSON('zones')
.then(data => {
let output = '';
data.find(zone =>
zone.id === parseInt(zoneID, 10)
).encounters.map(encounter => {
output += `<li class="boss" data-zoneid="${zoneID}">${encounter.name}</li>`;
bosses.forEach(boss => {
boss.innerHTML = output;
});
}).join('');
});
}
function displayZones() {
let output = '';
requestJSON('zones')
.then(zones => {
return zones.map(zone => {
output += `
<ul data-zoneid="${zone.id}" class="zones">
<span>${zone.name}</span>
<ul data-zoneid="${zone.id}" class="bosses"></ul>
</ul>`;
response.innerHTML = output;
}).join('');
})
.then(responseList.style.display = 'flex');
}
zonesBtn.addEventListener('click', displayZones);
responseList.addEventListener('click', evt => {
const target = evt.target.parentElement;
const zoneID = target.dataset.zoneid;
displayBosses(zoneID);
if (target.classList.contains('clicked'))
target.classList.remove('clicked');
else
target.classList.add('clicked')
});
【问题讨论】:
-
您是要自己创建微调器还是将您引导到一个好的微调器插件/库/sn-p?简而言之,您需要在发送数据的 xhr 调用之前或之后调用渲染微调器的函数,然后在数据返回时移除微调器。最坏的情况,只需在 html 顶部放置一个半透明的灰色叠加层,因此 UI(绝对位置等)有点“不可用”,并使用 css 规则
cursor: wait;将光标指针更改为默认微调器 -
@Shilly 我会自己创建微调器,我想避免使用库和外部代码,至少在这种情况下是这样。所以你的意思是我应该在
displayZones函数的第一个.then中调用spinner rendering function?随时纠正我:) -
不,在第一个'then'之前,因为'then'只有在数据返回时才会解析。因此,要么向你的 ajax 调用添加一个回调参数,要么让 ajax 调用始终显示一个微调器,或者在启动异步 requestJSON.then() 之前调用它。你需要在第一个“then”中再次删除微调器。有点像:
function displayBosses(zoneID) { showSpinner(); requestJSON().then( hideSpinner(); data.find(....... -
@Shilly 听起来应该可以解决问题
标签: javascript json ecmascript-6 es6-promise