javascript - 如何使用我创建的代码创建新的“最近搜索”按钮?我仍然在开发工具中收到错误消息,不知道该怎么办
问题描述
我正在努力不仅在本地存储中为最近的搜索创建一个空间,而且还在我的主项目页面上创建一个新的工作按钮。我收到一条错误消息,“addEventListener("click", buttonClickHandler); 我在代码最底部的调用无法读取“null”的属性,所以我想知道我在开始时哪里出错了。我现在已经尝试过多次修改这段 JS 了,但我现在不知道从哪里开始。有什么建议吗?
var cityFormEl = document.querySelector("#city");
var cityNameInputEl = document.querySelector("#location");
var dateFormEl = document.querySelector("#date");
var dateNameInputEl = document.querySelector("#today");
var historyButtonsEl = document.querySelector("#search-item");
var historyCardEl = document.querySelector("#recent-searches");
var trashEl = document.querySelector("#trash");
var searchHistoryArray = []
var formSubmitHandler = function (event) {
event.preventDefault();
// get city name value from input element
var cityBtn = cityNameInputEl.value.trim();
// Set city name in local storage and generate history buttons
if (cityBtn) {
searchHistoryArray.push(cityBtn);
localStorage.setItem("citySearch", JSON.stringify(searchHistoryArray));
localStorage.setItem("dateSearch", JSON.stringify(searchHistoryArray));
var searchHistoryEl = document.createElement('button');
searchHistoryEl.className = "btn";
searchHistoryEl.setAttribute("data-city", "data-date", cityBtn)
searchHistoryEl.innerHTML = cityBtn;
historyButtonsEl.appendChild(searchHistoryEl);
historyCardEl.removeAttribute("style")
cityNameInputEl.value = "";
}
else {
alert("Please enter a Date and a City name");
}
}
// Load any past city searches
var loadHistory = function () {
searchArray = JSON.parse(localStorage.getItem("citySearch"));
if (searchArray) {
searchHistoryArray = JSON.parse(localStorage.getItem("citySearch", "dateSearch"));
for (let i = 0; i < searchArray.length; i++) {
var searchHistoryEl = document.createElement('button');
searchHistoryEl.className = "btn";
searchHistoryEl.setAttribute("data-city", "data-date", searchArray[i])
searchHistoryEl.innerHTML = searchArray[i];
historyButtonsEl.appendChild(searchHistoryEl);
historyCardEl.removeAttribute("style");
}
}
}
// Search using search history buttons
var buttonClickHandler = function (event) {
var cityBtn = event.target.getAttribute("data-city", "data-date",);
if (cityBtn) {
formSubmitHandler(cityBtn);
}
}
// Clear Search History
var clearHistory = function (event) {
localStorage.removeItem("citySearch", "dateSearch");
historyCardEl.setAttribute("style", "display: none");
}
cityFormEl.addEventListener("submit", formSubmitHandler);
historyButtonsEl.addEventListener("click", buttonClickHandler);
trashEl.addEventListener("click", clearHistory);
loadHistory();
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Adventure Time</title>
<link rel="stylesheet" href="../adventure-time/assets/css/styles.css" />
<link rel="stylesheet" href="../adventure-time/build/styles.css" />
</head>
<body>
<header>
<nav class="flex justify-between items-center">
<a href="#"><img class="max-w-xs p-8" src="../adventure-time/assets/img/adventure-time-logo-reverse.png"
alt="Logo of Adventure Time" /></a>
<a href="#recent-searches" class="recent-search-nav">Recent Searches</a>
</nav>
<section class="hero">
<div class="hero-statement">
<h2>
Your <span id="adventure"> Adventure</span> <br />
Starts here
</h2>
<p>Enter a time and place to start your journey</p>
<br />
</div>
<form class="search-input flex justify-between">
<div id="date">
<input type="date" id="today" name="date" value="2021-08-01" min="2021-08-01" max="2022-12-31"
class="date-input cst-btn cst-btn-lft">
</div>
<div class="time-input cst-btn cst-btn-cntr"><input type="time" id="time" name="time" min="07:00"
max="22:00" required></div>
<div class="location-input cst-btn cst-btn-cntr">
<div id="city">
<label>City</label>
<input id="location" type="text" tabindex="3" name="city">
</div>
</div>
<button class="cst-btn cst-btn-rgt" id="search"><a href=adventure.html>Find my Adventure</a></button>
</form>
</section>
<!-- HERO END -->
</header>
<main class="m-auto w-3/4">
<div id="recent-searches">
<h2 class="text-black text-4xl text-center">Recent Searches</h2>
<div class="recent-searches flex justify-around">
<div class="search-item">
<h4>Los Angeles, CA</h4>
<p>Sat, Jul 7 at 3:00 PM</p>
</div>
<div class="search-item">
<h4>Portland, OR</h4>
<p>Sat, Jul 7 at 3:00 PM</p>
</div>
<div class="search-item">
<h4>New York, NY</h4>
<p>Sat, Jul 7 at 3:00 PM</p>
</div>
<div class="search-item">
<h4>Vancouver, BC</h4>
<p>Sat, Jul 7 at 3:00 PM</p>
</div>
</div>
</div>
</div>
</main>
<footer class="main-footer">
<h5>Made with ❤️  by Team Awesome</h5>
</footer>
<script src="../adventure-time/assets/js/script.js"></script>
</body>
</html>
解决方案
我运行了你的代码并得到了这个错误(虽然我不完全确定这是否是你所引用的):
Uncaught TypeError: historyButtonsEl is null
抛出此 TypeError 的原因在于您的 JS 的这一行:
var historyButtonsEl = document.querySelector("#search-item");
您正在选择一个ID等于“search-item”的元素;但是,您的 html 中对“搜索项”的唯一引用是class。要解决此问题,只需执行以下操作:
var historyButtonsEl = document.querySelector(".search-item");
注意“。” 代替 '#'。'#' 选择id而 '.' 选择课程。另外,虽然我不确定您尝试使用此 querySelector() 选择什么,但我应该警告您使用 querySelector() 选择类将返回该类的第一个找到的元素,而不是该类的所有元素(为此使用 querySelectorAll())。希望这有帮助。
推荐阅读
- css - 遮罩图像css,使其仅显示圆圈的一部分
- javascript - javascript Uncaught (in promise) DOMException
- javascript - 未捕获(承诺):错误:运行时编译器未在 Angular 中加载
- node.js - 如何使用 Winston3 在 Windows 事件日志中记录事件?
- sql-server - 两台sql server如何同步第二台
- hyperledger-composer - 如何打开 .CTO 文件以使用 VScode 更新内容?
- apache-kafka - Spark Streaming 能否在仅指定 1 个 kafka 代理的情况下自动发现新的 kafka 代理?
- java - 如何将 Gremlin Tinkerpop Vertex 转换为 POJO
- python - 如何正确将 CSV 导出到 sql server 数据库?
- python - 如何使用opencv python填充多边形