html getElementsByTagName返回undefined,即使脚本在/body [closed]之前也是如此

zzwlnbp8  于 2023-05-27  发布在  其他
关注(0)|答案(2)|浏览(171)

**关闭。**此题需要debugging details。目前不接受答复。

编辑问题以包括desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem。这将帮助其他人回答这个问题。
5天前关闭。
Improve this question
我是一个完全的JavaScript初学者,我完全被阻塞了。我试图创建一个搜索栏过滤系统,通过适应在教程中找到的代码。目标是能够按名称、导演或发行年份过滤电影列表。
这些信息中的每一个分别在标签<h1><h2>然后<h3>之间。排序是由getElementsByTagName完成的,并与导演和发行年份的预期一样工作,但只要我添加电影的标题,就什么都不起作用了。
从我在Firefox中看到的,原因是我存储电影名称的变量没有定义(Uncaught TypeError:a未定义)。经过一些研究,我能够读到当脚本在页面加载之前运行时会出现此错误,所以我将其放置在/body之前,但问题仍然存在。
我想知道我的代码有什么问题。

function myFunction() {
  // Declare variables
  var input, filter, ul, li, a, b, c, i, title, director, date;
  input = document.getElementById('myInput');
  filter = input.value.toUpperCase();
  ul = document.getElementById("myUL");
  li = ul.getElementsByTagName('li');

  // Loop through all list items, and hide those who don't match the search query
  for (i = 0; i < li.length; i++) {
    a = li[i].getElementsByTagName("h1")[0];
    b = li[i].getElementsByTagName("h2")[0];
    c = li[i].getElementsByTagName("h3")[0];
    title = a.textContent || a.innerText;
    director = b.textContent || b.innerText;
    date = c.textContent || c.innerText;
    if (title.toUpperCase().indexOf(filter) > -1 || director.toUpperCase().indexOf(filter) > -1 || date.toUpperCase().indexOf(filter) > -1) {
      li[i].style.display = "";
    } else {
      li[i].style.display = "none";
    }
  }
}
<ul id="myUL" class="gallery container">
  <li>
    <div class="overlay"></div>
    <div class="info">
      <a href="#" class="btn"><img src="example.jpg"></a>
      <div class="description">
        <h1 style="display:none">TITLE</h1>
        <h2>DIRECTOR</h2>
        <h3>DATE</h3>
        <p>
          SYNOPSIS
        </p>
      </div>
    </div>
    <div class="bg-img">
      <img src="example2.jpg">
    </div>
  </li>
</ul>
6ioyuze2

6ioyuze21#

在OP中,<script>标记位于正确的位置。不幸的是,这只是解决方案的一部分。

问题

  • HTML中的<input>在哪里?
  • 为每个类别过滤器添加复选框:titledirectordate
  • certain circumstances下使用过时的方法(如.getElementsByTagName())可能会出现问题。使用.querySelectorAll()
  • window的“load”事件上调用搜索函数没有什么意义。页面和用户之间的交互可以在<input id="find"><form>上触发的“单击”、“输入”、“更改”或“提交”事件上处理。在本例中,<form>环绕所有元素,并注册到"submit" event
  • .textContent.innerTextalmost identical,使用其中一个。
  • <h1><h6>是标题,应用于按重要性顺序组织的内容标题。一个页面只能使用一个<h1>。将<h1><h2><h3>添加到每个<li>中不仅碍眼,而且在语义上也很糟糕。使用CSS调整font-sizefont-weight
    示例中有详细注解
    **注意:**源代码的某些部分标有 * 用于演示目的 *,这不是必需的,只是为了生成<ul>的内容。
// For demo purposes
const data = [{
  "title": "Plain Dirty (a.k.a. Briar Patch)",
  "director": "Jodi MacEllen",
  "date": "7/16/2018"
}, {
  "title": "Cake",
  "director": "Faber Pude",
  "date": "5/3/2012"
}, {
  "title": "Exit Smiling",
  "director": "Bryant Whytock",
  "date": "1/26/1972"
}, {
  "title": "Mission: Impossible III",
  "director": "Allison Kayzer",
  "date": "5/14/1986"
}, {
  "title": "Hollywood Between Paranoia and Sci-Fi. The Power of Myth",
  "director": "Isacco Yoell",
  "date": "3/14/1980"
}, {
  "title": "Barabbas",
  "director": "Humfrid Scandrett",
  "date": "6/12/2018"
}, {
  "title": "Stolen (Stolen Lives)",
  "director": "Harv Ginman",
  "date": "2/19/2014"
}, {
  "title": "Casper",
  "director": "Ferne Nester",
  "date": "9/20/2011"
}, {
  "title": "Journey to the Beginning of Time",
  "director": "Dodi Chaster",
  "date": "12/4/2014"
}, {
  "title": "Home Run",
  "director": "Nonna Bugler",
  "date": "5/4/1972"
}];

// Reference <ul>
const list = document.querySelector("ul");

// For demo purposes
data.forEach(movie => {
  const li = `<li><i>${movie.title}</i> - 
              <b>${movie.director}</b> - 
              <time>${movie.date}</time></li>`;
  list.insertAdjacentHTML("beforeend", li);
});

// Reference the <form>
const F = document.forms.main;
// Reference all <input> and <fieldset>
const fc = F.elements;
// Reference <input id="find">
const find = fc.find;
// Make HTMLCollection of all [name="chx"] into an array
const filters = Array.from(fc.chx);
// Make NodeList of all <li> then into an array
const items = Array.from(document.querySelectorAll("li"));
// Register <form> to "submit" event
F.onsubmit = searchList;

// Event handler passes Event Object
function searchList(event) {
  // Stop <form> from redirecting page
  event.preventDefault();
  /**
   * Get user search words from <input id="find">
   * Convert string into an array.
   */
  const keywords = find.value.toLowerCase().split(" ");
  // Hide all <li>
  items.forEach(li => li.style.display = "none");
  // Get an array of index numbers of each checked checkbox
  const checked = filters.flatMap((chx, idx) => chx.checked ? idx : []);
  /**
   * For each <li>...
   * ...Make an array (text) of text from <i>, <b>, and <time> in <li>...
   * ...Make an array (filtered) of texts of only index that 
   * match the numbers in checked array and convert it into a string...
   * ...If one of the search words is also in the text of the current <li>...
   * ...show the <li>
   */
  items.forEach(li => {
    let text = Array.from(li.children).map(ele => ele.textContent.toLowerCase());
    let filtered = text.filter((txt, cnt) => checked.includes(cnt)).join("");

    if (keywords.some(word => filtered.includes(word))) {
      li.style.display = "list-item";
    }
  });
}
:root {
  font: 2ch/1.15 "Segoe UI";
}

fieldset {
  padding-right: 20px;
}

input {
  font: inherit;
  height: 3.5ex;
}

#find {
  width: 80%;
  margin: 15px 0 0 25px;
}

[type="submit"] {
  font-variant: small-caps;
  cursor: pointer;
}

menu,
label {
  display: flex;
  align-items: center;
  margin-left: 15px;
}

menu {
  list-style: none;
  margin-left: -15px;
}
<form id="main">
  <fieldset>
    <legend>Search by keywords delimited by a space</legend>
    <input id="find" placeholder="x the 2018" type="search"><input type="submit" value="Find">
    <menu>Filters:&nbsp;
      <label><input name="chx" type="checkbox" checked> Title </label>
      <label><input name="chx" type="checkbox" checked> Director </label>
      <label><input name="chx" type="checkbox" checked> Date </label>
    </menu>
    <ul></ul>
  </fieldset>
</form>
xkftehaa

xkftehaa2#

你可以添加windoe.onload来调用你的函数,这意味着只有当页面被加载时,你的函数才会被触发。

window.onload = function() {
  myFunction();
};

function myFunction() {
  // Declare variables
  var input, filter, ul, li, a, b, c, i, title, director, date;
  ul = document.getElementById("myUL");
  li = ul.getElementsByTagName('li');

  // Loop through all list items, and hide those who don't match the search query
  for (i = 0; i < li.length; i++) {
    a = li[i].getElementsByTagName("h1")[0];
    b = li[i].getElementsByTagName("h2")[0];
    c = li[i].getElementsByTagName("h3")[0];
    title = a.textContent || a.innerText;
    director = b.textContent || b.innerText;
    date = c.textContent || c.innerText;
    console.log(title, director, date);

    if (title.toUpperCase().indexOf(filter) > -1 || director.toUpperCase().indexOf(filter) > -1 || date.toUpperCase().indexOf(filter) > -1) {
      li[i].style.display = "";
    } else {
      li[i].style.display = "none";
    }
  }
}
<ul id="myUL" class="gallery container">
  <li>
    <div class="overlay"></div>
    <div class="info">
      <a href="#" class="btn"><img src="https://picsum.photos/200"></a>
      <div class="description">
        <h1 style="display:none">TITLE</h1>
        <h2>DIRECTOR</h2>
        <h3>DATE</h3>
        <p>
          SYNOPSIS
        </p>
      </div>
    </div>
    <div class="bg-img">
      <img src="https://picsum.photos/200">
    </div>
  </li>
</ul>

相关问题