【问题标题】:how to filter elements by name如何按名称过滤元素
【发布时间】:2018-09-03 08:09:18
【问题描述】:

我有 3 部电影(Annihilation、Bomb x City 和 The Commuter),我不知道如何放置 javascript 代码,所以当我开始搜索“ann”时,只出现了 annihilation 电影框而其他未显示...像过滤...请帮助我不太擅长这些东西,我想学习。提前致谢。

<header>
  <div class="container">
    <div id="branding">
      <h1><span id="logo">mov</span>BLANK</h1>
    </div>
    <nav>
      <ul>
        <input type="text" id="filterInput" placeholder="Search...">
        <li class="current"><a href="index.html">Home</a></li>
        <li><a id="newprojection" href="./html/newprojection.html">New projection</a></li>
        <li><a id="buyticket" href="./html/buyticket.html">Buy a Ticket</a></li>
        <li><a id="newuser" href="./html/newuser.html">New user</a></li>
        <li><a id="loginbtn" href="./html/login.html">Log in</a></li>
        <li>
          <a id="buy" href="#"></a>
        </li>
      </ul>
    </nav>
  </div>
</header>

<section id="boxes">
  <div id="div1" class=".container">
    <div id="annihilation" class="moviebox">
      <a class="moviea" href="./html/annihilation.html"><img src="./img/movie1.jpg"></a>
      <a id="delete" href="#">X</a>
      <h3 class="moviea">Annihilation</h3>
      <p class="moviea">Genre: Adventure, Fantasy</p>
    </div>
    <div id="bombcity" class="moviebox">
      <a class="imgmovie" href="./html/bombcity.html"><img src="./img/movie2.jpg"></a>
      <a id="change" href="#">X</a>
      <h3 class="namemovie">Bomb City</h3>
      <p class="genremovie">Genre: Action, Crime</p>
    </div>
    <div id="commuter" class="moviebox">
      <a class="imgmovie" href="./html/commuter.html"><img src="./img/movie3.jpg"></a>
      <a id="buy2" href="#">X</a>
      <h3 class="namemovie">The Commuter</h3>
      <p class="genremovie">Genre: Action, Drama</p>
    </div>
    <div id="bookmarksResults"></div>
  </div>
</section>

【问题讨论】:

  • 欢迎来到stackoverflow!在问这里之前,您应该对如何使用 JavaScript 实现这一点进行更多研究。有许多关于使用 JavaScript 构建可搜索列表的教程,可以通过 Google 快速搜索轻松找到。

标签: javascript html filtering


【解决方案1】:

我会将属性 onkeyup 添加到您的输入元素并将其设置为查看输入文本的函数,然后循环遍历您的电影框 div 元素并在 h3 元素文本不包含输入值时隐藏它们。

例子:

<input type="text" id="filterInput" placeholder="Search..." onkeyup="filterTable(this)" />

function filterTable(input) {
    var search = input.value;
    var movieDivs = document.querySelectorAll('div.moviebox');
    for (var i = 0; i < movieDivs.length; i++;) {
        var h3 = movieDivs[i].querySelector('h3');
        if (h3.innerText.indexOf(search) >= 0)
            movieDivs[i].style.display = '';
        else
            movieDivs[i].style.display = 'none';
    }
}

【讨论】:

    【解决方案2】:

    这是我想出的。这是一个学习一些 JS 的好小项目!您应该尝试在给定电影数组的情况下自动创建 html。对于你正在做的事情来说可能有点繁重,但 React 是一个简洁的 JS 库,值得研究和学习。还要小心带有 . 的类名。你通常不想这样做。 (查看您的容器类)

    // grab all the movies
    let movies = document.getElementsByClassName('moviebox');
    //this returns an object we want an array
    //with all the names in it. so lets call OBject.keys() which will
    //return an array with all the keys of this object
    movies = Object.keys(movies)
      .map(key => movies[key].id);
    // what we did was loop through the keys, (0,1,2) and index into the object with them (movies[key]). then since hte id is the name of the movie it seems, we just grab the id (movies[key].id) we then save this update array into the already defined movies array.
    console.log(movies);
    //^ check it out, there are the list of movies, dynamically grabbed!
    
    //lets define a function that will hide a movie given its name.
    //this is a super basic function but it does one thing well.
    function hideMovie(name) {
      document.getElementById(name).style.display = 'none';
      console.log("hide "+name)
    }
    
    //if we can hide a movie we want to be abble to show one too.
    function showMovie(name) {
      document.getElementById(name).style.display = 'block';
    }
    
    //now lets target the input box
    const searchBox = document.getElementById('filterInput');
    //we want to add an event listener so everytime the user inputs something
    //we look through the movies and hide the ones that dont contain the string
    //entered, we also want to make sure we show the right movies too
    searchBox.addEventListener('input', () => {
      const value = searchBox.value;
      const visibleMovies = [];
      console.log(value)
      //lets filter the movies to only include the ones we want to hide
      const hiddenMovies = movies.filter(movie => {
          const hidden = movie.indexOf(value) < 0;
          //if we're not going to hide it lets show it.
          if(!hidden){
            visibleMovies.push(movie)
          }
          return hidden;
        });
      console.log(hiddenMovies)
      
      //loop through and hide the movies.
      for(let i = 0; i< hiddenMovies.length; i++){
        hideMovie(hiddenMovies[i]);
      }
      //loop through and show the movies
      for(let i = 0; i< visibleMovies.length; i++){
        showMovie(visibleMovies[i]);
      }
    })
    <header>
      <div class="container">
        <div id="branding">
          <h1><span id="logo">mov</span>BLANK</h1>
        </div>
        <nav>
          <ul>
            <input type="text" id="filterInput" placeholder="Search...">
            <li class="current"><a href="index.html">Home</a></li>
            <li><a id="newprojection" href="./html/newprojection.html">New projection</a></li>
            <li><a id="buyticket" href="./html/buyticket.html">Buy a Ticket</a></li>
            <li><a id="newuser" href="./html/newuser.html">New user</a></li>
            <li><a id="loginbtn" href="./html/login.html">Log in</a></li>
            <li>
              <a id="buy" href="#"></a>
            </li>
          </ul>
        </nav>
      </div>
    </header>
    
    <section id="boxes">
      <div id="div1" class=".container">
        <div id="annihilation" class="moviebox">
          <a class="moviea" href="./html/annihilation.html"><img src="./img/movie1.jpg"></a>
          <a id="delete" href="#">X</a>
          <h3 class="moviea">Annihilation</h3>
          <p class="moviea">Genre: Adventure, Fantasy</p>
        </div>
        <div id="bombcity" class="moviebox">
          <a class="imgmovie" href="./html/bombcity.html"><img src="./img/movie2.jpg"></a>
          <a id="change" href="#">X</a>
          <h3 class="namemovie">Bomb City</h3>
          <p class="genremovie">Genre: Action, Crime</p>
        </div>
        <div id="commuter" class="moviebox">
          <a class="imgmovie" href="./html/commuter.html"><img src="./img/movie3.jpg"></a>
          <a id="buy2" href="#">X</a>
          <h3 class="namemovie">The Commuter</h3>
          <p class="genremovie">Genre: Action, Drama</p>
        </div>
        <div id="bookmarksResults"></div>
      </div>
    </section>

    【讨论】:

      【解决方案3】:

      可能最好的方法是使用 js 库作为 angular 或 react。

      但这里是一个使用 oninput 事件的 vanila js 的简单示例:

          <header>
            <div class="container">
              <div id="branding">
                <h1><span id="logo">mov</span>BLANK</h1>
              </div>
              <nav>
                <ul>
                  <input type="text" id="filterInput" placeholder="Search..." oninput="filterMovies(this.value)">
                  <li class="current"><a href="index.html">Home</a></li>
                  <li><a id="newprojection" href="./html/newprojection.html">New projection</a></li>
                  <li><a id="buyticket" href="./html/buyticket.html">Buy a Ticket</a></li>
                  <li><a id="newuser" href="./html/newuser.html">New user</a></li>
                  <li><a id="loginbtn" href="./html/login.html">Log in</a></li>
                  <li>
                    <a id="buy" href="#"></a>
                  </li>
                </ul>
              </nav>
            </div>
          </header>
          
          <section id="boxes">
            <div id="movies_boxes_container" class=".container">
              <div id="annihilation" class="moviebox">
                <a class="moviea" href="./html/annihilation.html"><img src="./img/movie1.jpg"></a>
                <a id="delete" href="#">X</a>
                <h3 class="moviea">Annihilation</h3>
                <p class="moviea">Genre: Adventure, Fantasy</p>
              </div>
              <div id="bombcity" class="moviebox">
                <a class="imgmovie" href="./html/bombcity.html"><img src="./img/movie2.jpg"></a>
                <a id="change" href="#">X</a>
                <h3 class="namemovie">Bomb City</h3>
                <p class="genremovie">Genre: Action, Crime</p>
              </div>
              <div id="commuter" class="moviebox">
                <a class="imgmovie" href="./html/commuter.html"><img src="./img/movie3.jpg"></a>
                <a id="buy2" href="#">X</a>
                <h3 class="namemovie">The Commuter</h3>
                <p class="genremovie">Genre: Action, Drama</p>
              </div>
              <div id="bookmarksResults"></div>
            </div>
          </section>
          
          <script> 
            
            
          function filterMovies(val){
            val = val.toUpperCase();
            let moviesBoxes = document.getElementsByClassName('moviebox');
          
              Array.prototype.forEach.call(moviesBoxes, child => {
                let id = child.id.toUpperCase()
                if(!id.includes(val))
                  child.style.display = "none";
                else{
                  child.style.display = "block";
                }
          });
          }
          </script>

      【讨论】:

        【解决方案4】:

        一些html

        <input id='search' type='text'>
        
        <div id='hold_movies'>
          <a class='movie'>Annihilation</a><br>
          <a class='movie'>Bomb x City</a><br>
          <a class='movie'>The Commuter</a>
        </div>
        

        一些jQuery

        $("#search").keyup(function() {
            val = $.trim(this.value);
            if (val === "") {
            $('.movie').show();
            } else {
            $('.movie').hide();
            $(".movie:contains(" + val + ")").show();
            }
            });
        

        结果

        为确保搜索不区分大小写,您可以按如下方式扩展 jQuery:

        $.expr[":"].contains = $.expr.createPseudo(function(arg) {
            return function( elem ) {
                return $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
            };
        });
        

        【讨论】:

          【解决方案5】:
          • 此替代方案使用函数 querySelectorquerySelectorAll 找到元素并进行必要的比较。
          • 此方法使用函数 indexOf 来查找匹配项。
          • 此方法使用名为hide 的类来隐藏与输入值不匹配的元素。
          • 此方法区分大小写。
          • 使用事件 input 捕获输入文本字段中的任何更改。

          document.getElementById('filterInput').addEventListener('input', function() {
            var value = this.value;
            var container = document.getElementById('boxes');
            Array.prototype.forEach.call(container.querySelectorAll('.moviebox'), function(e) {
              e.classList.add('hide');
          
              Array.prototype.forEach.call(e.querySelectorAll('.namemovie'), function(m) {
                if (value.trim() === '' || m.textContent.indexOf(value) !== -1) e.classList.remove('hide');
              });
            })
          })
          .hide {
            display: none
          }
          <header>
            <div class="container">
              <div id="branding">
                <h1><span id="logo">mov</span>BLANK</h1>
              </div>
              <nav>
                <ul>
                  <input type="text" id="filterInput" placeholder="Search...">
                  <li class="current"><a href="index.html">Home</a></li>
                  <li><a id="newprojection" href="./html/newprojection.html">New projection</a></li>
                  <li><a id="buyticket" href="./html/buyticket.html">Buy a Ticket</a></li>
                  <li><a id="newuser" href="./html/newuser.html">New user</a></li>
                  <li><a id="loginbtn" href="./html/login.html">Log in</a></li>
                  <li>
                    <a id="buy" href="#"></a>
                  </li>
                </ul>
              </nav>
            </div>
          </header>
          
          <section id="boxes">
            <div id="div1" class=".container">
              <div id="annihilation" class="moviebox">
                <a class="moviea" href="./html/annihilation.html"><img src="./img/movie1.jpg"></a>
                <a id="delete" href="#">X</a>
                <h3 class="namemovie">Annihilation</h3>
                <p class="genremovie">Genre: Adventure, Fantasy</p>
              </div>
              <div id="bombcity" class="moviebox">
                <a class="imgmovie" href="./html/bombcity.html"><img src="./img/movie2.jpg"></a>
                <a id="change" href="#">X</a>
                <h3 class="namemovie">Bomb City</h3>
                <p class="genremovie">Genre: Action, Crime</p>
              </div>
              <div id="commuter" class="moviebox">
                <a class="imgmovie" href="./html/commuter.html"><img src="./img/movie3.jpg"></a>
                <a id="buy2" href="#">X</a>
                <h3 class="namemovie">The Commuter</h3>
                <p class="genremovie">Genre: Action, Drama</p>
              </div>
              <div id="bookmarksResults"></div>
            </div>
          </section>

          【讨论】:

          • 这里最接近 javascript 函数吗?
          • @AnthonyMcGrath 是的!
          【解决方案6】:

          你必须实现一个过滤器/搜索列表。

          有无数种方法可以解决这个问题,但我会在这里放一个complete example coming from w3schools.com

          这是相关示例,为简单起见,所有代码(css / javascript)都嵌入到单个 html 页面中。

          <!DOCTYPE html>
          <html>
          <head>
          <meta name="viewport" content="width=device-width, initial-scale=1">
          <style>
          * {
            box-sizing: border-box;
          }
          
          #myInput {
            background-image: url('/css/searchicon.png');
            background-position: 10px 12px;
            background-repeat: no-repeat;
            width: 100%;
            font-size: 16px;
            padding: 12px 20px 12px 40px;
            border: 1px solid #ddd;
            margin-bottom: 12px;
          }
          
          #myUL {
            list-style-type: none;
            padding: 0;
            margin: 0;
          }
          
          #myUL li a {
            border: 1px solid #ddd;
            margin-top: -1px; /* Prevent double borders */
            background-color: #f6f6f6;
            padding: 12px;
            text-decoration: none;
            font-size: 18px;
            color: black;
            display: block
          }
          
          #myUL li a:hover:not(.header) {
            background-color: #eee;
          }
          </style>
          </head>
          <body>
          
          <h2>My Phonebook</h2>
          
          <input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
          
          <ul id="myUL">
            <li><a href="#">Adele</a></li>
            <li><a href="#">Agnes</a></li>
          
            <li><a href="#">Billy</a></li>
            <li><a href="#">Bob</a></li>
          
            <li><a href="#">Calvin</a></li>
            <li><a href="#">Christina</a></li>
            <li><a href="#">Cindy</a></li>
          </ul>
          
          <script>
          function myFunction() {
              var input, filter, ul, li, a, i;
              input = document.getElementById("myInput");
              filter = input.value.toUpperCase();
              ul = document.getElementById("myUL");
              li = ul.getElementsByTagName("li");
              for (i = 0; i < li.length; i++) {
                  a = li[i].getElementsByTagName("a")[0];
                  if (a.innerHTML.toUpperCase().indexOf(filter) > -1) {
                      li[i].style.display = "";
                  } else {
                      li[i].style.display = "none";
          
                  }
              }
          }
          </script>
          
          </body>
          </html>
          

          此实现使用 for 循环循环列表中的所有项目以搜索我们正在搜索的字符的位置:.indexOf(filter) 并相应地显示/隐藏当前项目。

          结合在一起的几个基本概念可以实现如此用户友好和强大的使用。

          首先,我建议您将这些功能单元分隔在不同的文件中,完整地编写各个部分并回答您阅读的任何问题或疑问或不清楚的信息。

          在新文件中手写代码,一个字母一个字母。 阅读它,不要复制和粘贴。

          我更喜欢提出建议而不是解决方案,因为您的主要要求似乎是您想学习。 一旦你可以反汇编/重新组装这段代码,在你当前的页面中实现它也很容易。

          花时间,回答自己的问题,开始课程,获取书籍,永不放弃。

          玩得开心!

          【讨论】:

            猜你喜欢
            • 2020-06-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-12-03
            相关资源
            最近更新 更多