资源描述:它使用自动完成功能来搜索电影,从第三方网站平台OMDb API获取电影数据,并显示关键电影统计数据的比较。大家可以使用此代码拓展运用到其它功能,非常有借鉴意义哦。
使用方法
// Some default classes and variables used in the app
const DEFAULTS = {
DROPDOWN_CLASS_ITEM: "dropdown__menu__item",
DROPDOWN_CLASS_LINK: "dropdown__menu__link",
DROPDOWN_CLASS_ACTIVE: "dropdown--active",
COMPARE_CLASS_WINNER: "compare--winner",
COMPARE_CLASS_LOSER: "compare--loser",
API_BASE_URL: "https://www.omdbapi.com",
API_KEY: "89c28a6e"
};
// Reusable Autocomplete Class
class Autocomplete {
constructor(config) {
({
root: this.root,
optionTemplate: this.optionTemplate,
onOptionSelect: this.onOptionSelect,
inputValue: this.inputValue,
fetchData: this.fetchData
} = config);
this.createRootTemplate(this.root);
this.input = this.root.querySelector(".autocomplete__input");
this.dropdown = this.root.querySelector(".autocomplete__dropdown");
this.resultsWrapper = this.root.querySelector(".results");
this.initListeners();
}
initListeners() {
this.input.addEventListener("input", this.debounce(ev => this.onInput(ev), 500));
document.addEventListener("click", ev => {
if (!this.root.contains(ev.target)) {
this.dropdown.classList.remove(DEFAULTS.DROPDOWN_CLASS_ACTIVE);
}
});
}
async onInput(ev) {
const items = await this.fetchData(ev[0].target.value);
if (!items.length) {
this.dropdown.classList.remove(DEFAULTS.DROPDOWN_CLASS_ACTIVE);
return;
}
this.resultsWrapper.innerHTML = "";
this.dropdown.classList.add(DEFAULTS.DROPDOWN_CLASS_ACTIVE);
for (const item of items) {
const option = document.createElement("li");
option.classList.add(DEFAULTS.DROPDOWN_CLASS_ITEM);
const link = document.createElement("a");
link.classList.add(DEFAULTS.DROPDOWN_CLASS_LINK);
link.innerHTML = this.optionTemplate(item);
option.appendChild(link);
option.addEventListener("click", () => {
this.dropdown.classList.remove(DEFAULTS.DROPDOWN_CLASS_ACTIVE);
this.input.value = this.inputValue(item);
this.onOptionSelect(item);
});
this.resultsWrapper.appendChild(option);
}
}
debounce(callback, delay = 1000) {
return (...args) => {
if (this.timeoutId) clearTimeout(this.timeoutId);
this.timeoutId = setTimeout(() => {
callback.call(null, args);
}, delay);
};
}
createRootTemplate(el) {
el.innerHTML = `
<div class="autocomplete">
<label class="autocomplete__label">
Search
<input class="autocomplete__input" />
</label>
<div class="autocomplete__dropdown dropdown">
<ul class="dropdown__menu results">
</ul>
</div>
</div>
`;
}
}
// Class to compare movies
class MovieComparison {
constructor() {
this.init();
}
movieAutocompleteConfig() {
return {
optionTemplate(movie) {
const imgSrc = movie.Poster === "N/A" ? "" : movie.Poster;
return `
<img src="${imgSrc}" />
${movie.Title} (${movie.Year})
`;
},
inputValue(movie) {
return movie.Title;
},
async fetchData(searchTerm) {
const response = await axios.get(DEFAULTS.API_BASE_URL, {
params: {
apikey: DEFAULTS.API_KEY, // This api can only be used 1000 times a day
s: searchTerm
}
});
return response.data.Error ? [] : response.data.Search;
}
};
}
init() {
new Autocomplete({
...this.movieAutocompleteConfig(),
root: document.querySelector("#left-autocomplete"),
onOptionSelect: movie => {
this.onMovieSelect(
movie,
document.querySelector("#left-details"),
"left"
);
}
});
new Autocomplete({
...this.movieAutocompleteConfig(),
root: document.querySelector("#right-autocomplete"),
onOptionSelect: movie => {
this.onMovieSelect(
movie,
document.querySelector("#right-details"),
"right"
);
}
});
}
async onMovieSelect(movie, summaryElement, side) {
const response = await axios.get(DEFAULTS.API_BASE_URL, {
params: {
apikey: DEFAULTS.API_KEY,
i: movie.imdbID
}
});
summaryElement.innerHTML = this.movieTemplate(response.data);
if (side === "left") {
this.leftMovie = response.data;
} else {
this.rightMovie = response.data;
}
if (this.leftMovie && this.rightMovie) {
this.runComparison();
}
}
runComparison() {
const leftSideStats = document.querySelectorAll("#left-details .compare");
const rightSideStats = document.querySelectorAll("#right-details .compare");
console.log(rightSideStats);
for (const [i, leftStat] of leftSideStats.entries()) {
const rightStat = rightSideStats[i];
const leftSideValue = parseInt(leftStat.dataset.value);
const rightStatValue = parseInt(rightStat.dataset.value);
if (rightStatValue > leftSideValue) {
leftStat.classList.remove(DEFAULTS.COMPARE_CLASS_WINNER);
leftStat.classList.add(DEFAULTS.COMPARE_CLASS_LOSER);
} else {
rightStat.classList.remove(DEFAULTS.COMPARE_CLASS_WINNER);
rightStat.classList.add(DEFAULTS.COMPARE_CLASS_LOSER);
}
}
}
movieTemplate(detail) {
const boxOffice = parseInt(
detail.BoxOffice.replace(/\\$/g, "").replace(/,/g, "")
);
const metascore = parseInt(detail.Metascore);
const imdbScore = parseFloat(detail.imdbRating);
const imdbVotes = parseInt(detail.imdbVotes.replace(/,/g, ""));
const awardsCount = detail.Awards.split(" ")
.filter(Number)
.reduce((acc, cur) => acc + parseInt(cur), 0);
return `
<article class="media">
<h1 class="media__title">${detail.Title}</h1>
<figure class="media__figure">
<img src="${detail.Poster}" />
</figure>
<div class="media__info">
<h4>${detail.Genre}</h4>
<p>${detail.Plot}</p>
</div>
</article>
<article class="compare ${DEFAULTS.COMPARE_CLASS_WINNER}" data-value="${awardsCount}">
<p class="compare__title">${detail.Awards}</p>
<p class="compare__subtitle">Awards</p>
</article>
<article class="compare ${DEFAULTS.COMPARE_CLASS_WINNER}" data-value="${boxOffice}">
<p class="compare__title">${detail.BoxOffice}</p>
<p class="compare__subtitle">Box Office</p>
</article>
<article class="compare ${DEFAULTS.COMPARE_CLASS_WINNER}" data-value="${metascore}">
<p class="compare__title">${detail.Metascore}</p>
<p class="compare__subtitle">Metascore</p>
</article>
<article class="compare ${DEFAULTS.COMPARE_CLASS_WINNER}"" data-value="${imdbScore}">
<p class="compare__title">${detail.imdbRating}</p>
<p class="compare__subtitle">IMDB Rating</p>
</article>
<article class="compare ${DEFAULTS.COMPARE_CLASS_WINNER}"" data-value="${imdbVotes}">
<p class="compare__title">${detail.imdbVotes}</p>
<p class="compare__subtitle">IMDB Votes</p>
</article>
`;
}
}
const comparison = new MovieComparison();
站长提示:
1. 苦力吧素材官方QQ群:
950875342
2. 平台上所有素材资源,需注册登录会员方能正常下载。
3. 会员用户积极反馈网站、素材资源BUG或错误问题,每次奖励
2K币。
4. PHP源码类素材,如需协助安装调试,或你有二次开发需求,可联系苦力吧客服。
5. 付费素材资源,需充值后方能下载,如有任何疑问可直接联系苦力吧客服