仅使用javascript通过用户输入查询基于JSON的API
我一直在看关于使用JSON数据和JS的教程,决定使用API并制作一个简单的应用程序。我遇到了一个障碍,我不确定是什么导致了这个问题。问题在于我使用用户输入修改查询字符串的方式。当我将我的端点设置为静态并去掉“movieSearch”函数时,如下所示:仅使用javascript通过用户输入查询基于JSON的API,javascript,json,api,addeventlistener,Javascript,Json,Api,Addeventlistener,我一直在看关于使用JSON数据和JS的教程,决定使用API并制作一个简单的应用程序。我遇到了一个障碍,我不确定是什么导致了这个问题。问题在于我使用用户输入修改查询字符串的方式。当我将我的端点设置为静态并去掉“movieSearch”函数时,如下所示: const movies = []; const endpoint = 'http://www.omdbapi.com/?apikey=myAPIkey=batman'; fetch(endpoint) .then(blob => blo
const movies = [];
const endpoint = 'http://www.omdbapi.com/?apikey=myAPIkey=batman';
fetch(endpoint)
.then(blob => blob.json())
.then(data => movies.push(...data.Search));
假设它是静态的,它可以按预期工作
我目前的代码是:
const movies = [];
function movieSearch() {
const replace = this.value;
const endpoint = 'http://www.omdbapi.com/?apikey=myAPIkey=' + replace;
movies.length = 0;
fetch(endpoint)
.then(blob => blob.json())
.then(data => movies.push(...data.Search));
}
function findMatches(wordToMatch, movies) {
return movies.filter(film => {
const regex = new RegExp(wordToMatch, 'gi');
return film.Title.match(regex) || film.Year.match(regex)
})
}
function displayMatches() {
const matchArray = findMatches(this.value, movies);
const html = matchArray.map(film => {
const regex = new RegExp(this.value, 'gi');
const titleName = film.Title.replace(regex, `<span class="hl">${this.value}</span>`)
const yearName = film.Year.replace(regex, `<span class="hl">${this.value}</span>`)
return `
<li>
<span class="name">${titleName}, ${yearName}</span>
<span class="population">${film.imdbID}</span>
</li>
`;
}).join('');
suggestions.innerHTML = html;
}
const searchInput = document.querySelector('.search');
const suggestions = document.querySelector('.suggestions');
searchInput.addEventListener('keyup', displayMatches);
searchInput.addEventListener('change', displayMatches);
searchInput.addEventListener('keyup', movieSearch);
导致此行为的问题:
movieSearch
函数是异步的,可能无法及时更新数据函数查找匹配(文字匹配、电影){
返回电影。过滤器(电影=>{
console.log(film.Title,wordToMatch);
log(film.Title.toLowerCase().includes(wordToMatch));
返回film.Title.toLowerCase().includes(wordToMatch)| | film.Year.toLowerCase().includes(wordToMatch);
});
}
函数显示匹配项(电影、值){
const matchArray=findMatches(value.toLowerCase(),movies);
const html=matchArray.map(film=>{
const regex=new RegExp(值'gi');
const titleName=film.Title.replace(regex,`${value}`);
const=film.Year.replace(regex,`${value}`);
返回`
${titleName},${earname}
${film.imdbID}
`;
}).加入(“”);
suggestions.innerHTML=html;
}
const searchInput=document.querySelector('.search');
const suggestions=document.querySelector(“.suggestions”);
searchInput.addEventListener('keyup',()=>{
常数端点https://www.omdbapi.com/?apikey=63f88e02&s=“+searchInput.value;
获取(端点)
.then(blob=>blob.json())
。然后(数据=>{
log(“来自API的响应”);
控制台日志(数据);
如果(!data.Error)显示匹配(data.Search、searchInput.value);
});
});
Guess:由于movieSearch函数是异步的,所以movies数组可能不会总是及时更新。尝试在displayMatches函数中添加console.log(movies)。我试图重现您的问题,但它对我来说不起作用:我做了一些小的更改,使它能够与一个开放的API一起工作,我可以使用它进行测试。提示:对于基本字符串搜索,您可以使用“string”。includes('value'):我不这么认为,只要看一下它,您是否可以发布一个jsbin或JSFIDLE示例?如果API密钥应该进入url变量,那么无论如何它都将是公共的…@Abbe-Sure!这是:非常感谢,这解决了问题,帮助我理解我应该如何写它。再次感谢!
<form class="search-form">
<input type="text" class="search" placeholder="Movies">
<ul class="suggestions">
<li>test1</li>
<li>test2</li>
</ul>
</form>
{"Search":[{"Title":"Batman Begins","Year":"2005","imdbID":"tt0372784","Type":"movie","Poster":"https://m.media-amazon.com/images/M/MV5BZmUwNGU2ZmItMmRiNC00MjhlLTg5YWUtODMyNzkxODYzMmZlXkEyXkFqcGdeQXVyNTIzOTk5ODM@._V1_SX300.jpg"},{"Title":"Batman v Superman: Dawn of Justice","Year":"2016","imdbID":"tt2975590","Type":"movie","Poster":"https://m.media-amazon.com/images/M/MV5BYThjYzcyYzItNTVjNy00NDk0LTgwMWQtYjMwNmNlNWJhMzMyXkEyXkFqcGdeQXVyMTQxNzMzNDI@._V1_SX300.jpg"},{"Title":"Batman","Year":"1989","imdbID":"tt0096895","Type":"movie","Poster":"https://m.media-amazon.com/images/M/MV5BMTYwNjAyODIyMF5BMl5BanBnXkFtZTYwNDMwMDk2._V1_SX300.jpg"},{"Title":"Batman Returns","Year":"1992","imdbID":"tt0103776","Type":"movie","Poster":"https://ia.media-imdb.com/images/M/MV5BOGZmYzVkMmItM2NiOS00MDI3LWI4ZWQtMTg0YWZkODRkMmViXkEyXkFqcGdeQXVyODY0NzcxNw@@._V1_SX300.jpg"},{"Title":"Batman Forever","Year":"1995","imdbID":"tt0112462","Type":"movie","Poster":"https://m.media-amazon.com/images/M/MV5BNWY3M2I0YzItNzA1ZS00MzE3LThlYTEtMTg2YjNiOTYzODQ1XkEyXkFqcGdeQXVyMTQxNzMzNDI@._V1_SX300.jpg"},{"Title":"Batman & Robin","Year":"1997","imdbID":"tt0118688","Type":"movie","Poster":"https://m.media-amazon.com/images/M/MV5BMGQ5YTM1NmMtYmIxYy00N2VmLWJhZTYtN2EwYTY3MWFhOTczXkEyXkFqcGdeQXVyNTA2NTI0MTY@._V1_SX300.jpg"},{"Title":"The Lego Batman Movie","Year":"2017","imdbID":"tt4116284","Type":"movie","Poster":"https://m.media-amazon.com/images/M/MV5BMTcyNTEyOTY0M15BMl5BanBnXkFtZTgwOTAyNzU3MDI@._V1_SX300.jpg"},{"Title":"Batman: The Animated Series","Year":"1992–1995","imdbID":"tt0103359","Type":"series","Poster":"https://m.media-amazon.com/images/M/MV5BNzI5OWU0MjYtMmMwZi00YTRiLTljMDAtODQ0ZGYxMDljN2E0XkEyXkFqcGdeQXVyNTA4NzY1MzY@._V1_SX300.jpg"},{"Title":"Batman: Under the Red Hood","Year":"2010","imdbID":"tt1569923","Type":"movie","Poster":"https://m.media-amazon.com/images/M/MV5BYTdlODI0YTYtNjk5ZS00YzZjLTllZjktYmYzNWM4NmI5MmMxXkEyXkFqcGdeQXVyNTA4NzY1MzY@._V1_SX300.jpg"},{"Title":"Batman: The Dark Knight Returns, Part 1","Year":"2012","imdbID":"tt2313197","Type":"movie","Poster":"https://m.media-amazon.com/images/M/MV5BMzIxMDkxNDM2M15BMl5BanBnXkFtZTcwMDA5ODY1OQ@@._V1_SX300.jpg"}],"totalResults":"344","Response":"True"}
function findMatches(wordToMatch, movies) {
return movies.filter(film => {
console.log(film.Title, wordToMatch);
console.log(film.Title.toLowerCase().includes(wordToMatch));
return film.Title.toLowerCase().includes(wordToMatch) || film.Year.toLowerCase().includes(wordToMatch);
});
}
function displayMatches(movies, value) {
const matchArray = findMatches(value.toLowerCase(), movies);
const html = matchArray.map(film => {
const regex = new RegExp(value, 'gi');
const titleName = film.Title.replace(regex, `<span class="hl">${value}</span>`);
const yearName = film.Year.replace(regex, `<span class="hl">${value}</span>`);
return `
<li>
<span class="name">${titleName}, ${yearName}</span>
<span class="population">${film.imdbID}</span>
</li>
`;
}).join('');
suggestions.innerHTML = html;
}
const searchInput = document.querySelector('.search');
const suggestions = document.querySelector('.suggestions');
searchInput.addEventListener('keyup', () => {
const endpoint = 'https://www.omdbapi.com/?apikey=63f88e02&s=' + searchInput.value;
fetch(endpoint)
.then(blob => blob.json())
.then(data => {
console.log('response from API');
console.log(data);
if (!data.Error) displayMatches(data.Search, searchInput.value);
});
});