1

我正在使用 Google Books API 来显示简单图书搜索的结果。但是,在执行搜索时,某些项目会重复返回。参见:图书搜索

要获取此数据并以 HTML 格式显示,我这样做:

var result = document.getElementById("result");
var cover, title, author, book_id;
function handleResponse(response) {
  for (var i = 0; i < response.items.length; i++) {
    var item = response.items[i];
    // Create elements
    figure = document.createElement("figure");
    aEmp = document.createElement("a");
    aId = document.createElement("a");
    img = document.createElement("img");
    figcap = document.createElement("figcaption");
    // Get data from JSON
    try {
      cover = item.volumeInfo.imageLinks.thumbnail;
      title = item.volumeInfo.title;
      author = item.volumeInfo.authors;
      book_id = item.id;
    } catch (error) {
      continue;
    } finally {
      // Set value to elements e send to HTML
      result.appendChild(figure);
      aEmp.appendChild(img);
      aId.innerHTML = "ADICIONAR";
      aId.href = `/add/${book_id}`;
      aId.classList.add("dropdown");
      figure.appendChild(aId);
      figure.appendChild(aEmp);
      img.src = cover;
      figcap.innerHTML += `${title}<br>${author}`;
      figure.appendChild(figcap);
    }
  }
}
document.querySelector("form").addEventListener("submit", function (e) {
  result.innerHTML = "";
  search = document.getElementById("search").value;
  var script = document.createElement("script");
  script.src = `https://www.googleapis.com/books/v1/volumes?q=${search}&callback=handleResponse`;
  document.body.appendChild(script);
  e.preventDefault();
});

这是我上传的图片上使用的 JSON 示例:

https://www.googleapis.com/books/v1/volumes?q=$harry+potter&callback=handleResponse

4

3 回答 3

1

浏览了您最后提供的 JSON 数据,但我没有发现 API 响应有任何重复。无法弄清楚数据中可能在哪里进行了重复。

于 2021-06-02T17:31:41.937 回答
1

我在您的 API 搜索中没有看到任何重复的值。

fetch然而,我确实用承诺替换了脚本插入回调黑客。这应该更好地流动。

const results = document.querySelector('.results');
const googleBooksApi = 'https://www.googleapis.com/books/v1';

const formatList = (items) => {
  switch (items.length) {
    case 0: return '';
    case 1: return items[0];
    case 2: return items.join(' and ');
    default: return `${items.slice(0, -1).join(', ')} and ${[...items].pop()}`;
  }
};

// Convenience promise
const fetchBooks = (path) =>
  fetch(`${googleBooksApi}/${path}`)
    .then(response => response.json());

const queryBooksVolumes = (term) =>
  fetchBooks(`volumes?q=${term.replace(' ', '+')}`);

const addBook = (book) => {
  // Create elements
  const figure = document.createElement('figure');
  const aEmp = document.createElement('a');
  const aId = document.createElement('a');
  const img = document.createElement('img');
  const figcap = document.createElement('figcaption');
  const figcapTitle = document.createElement('div');
  const figcapAuthors = document.createElement('div');
  
  // Destructure data fields from book object (JSON)
  const {
    id: bookId,
    volumeInfo: {
      title,
      authors,
      publishedDate,
      imageLinks: { thumbnail }
    }
  } = book;

  const year = new Date(publishedDate).getFullYear();

  figure.classList.add('figure');
  aEmp.appendChild(img);
  aId.innerHTML = 'ADICIONAR';
  aId.href = `/add/${bookId}`;
  aId.classList.add('dropdown');
  figure.appendChild(aId);
  figure.appendChild(aEmp);
  img.src = thumbnail;
  figcapTitle.classList.add('figcap-title');
  figcapTitle.textContent = `${title} (${year})`;
  figcapAuthors.classList.add('figcap-authors');
  figcapAuthors.textContent = formatList(authors);
  figcap.append(figcapTitle);
  figcap.append(figcapAuthors);
  figure.appendChild(figcap);
  results.appendChild(figure);
};

const populateResults = ({ items }) => items
  .sort((
      { volumeInfo: { title: a } },
      { volumeInfo: { title: b } }
    ) =>
      a.localeCompare(b))
  .forEach(addBook);

const handleSearch = (e) => {
  e.preventDefault();
  const query = e.target.elements.search.value.trim();
  results.innerHTML = '';
  if (query.length > 0) {
    queryBooksVolumes(query).then(populateResults);
  }
};

document.forms['book-search'].addEventListener('submit', handleSearch);
html, body { width 100%; height: 100%; margin: 0; padding: 0; }

form { padding: 0.5em; }

.results {
  display: flex;
  flex-direction: row;
  /*flex-wrap: wrap;*/
  align-items: top;
}

form label { font-weight: bold; }
form label::after { content: ':'; }

.figure {
  display: flex;
  flex-direction: column;
  justify-content: center;
  border: thin solid grey;
  align-items: center;
  padding: 0.5em;
}

.figcap-title { font-weight: bold; }
.figcap-authors { font-style: italic; }

.figure img {
  margin: 0.5em 0;
}
<form name="book-search">
  <label>Book Title</label>
  <input type="text" name="search" value="Harry Potter" placeholder="Enter a book title..."/>
  <button>Search</button>
</form>
<div class="results"></div>

于 2021-06-02T17:35:22.027 回答
1

看起来 Google 响应数组中的每个项目都包含一个唯一 ID。在您的回调函数中,遍历返回结果的数组;记住已经在字典/哈希表中看到的 ID。如果以前见过的 ID 再次出现,请跳过该记录。

于 2021-06-02T17:10:29.677 回答