关于javascript:如何使用搜索栏过滤我的bootstrap 4导航栏链接?

How can I filter my bootstrap 4 navbar links with a search bar?

我正在使用bootstrap 4转换我的旧网站,所以这绝对是一个学习过程。

我的网站布局很好,但我意识到我的左侧垂直导航栏有很多链接。其中许多都聚集在倒塌的巢中。

我想最好在导航栏的顶部添加一个搜索栏,这样我就可以根据在搜索栏中输入的部分字符串过滤链接。这适用于不隐藏在隐藏的DIV(或class=collapsedboosttrap 4ul)中的链接。

我想感谢您在修改我的代码以显示过滤结果(包括隐藏在折叠的ul中的任何链接)方面的帮助?

这是一把小提琴

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$('.search-filter').on('keyup', function() {
  var input = $('.search-filter').val();
  var filter = input.toLowerCase();

  if (filter.length == 0) { // show all if filter is empty
    $('a').each(function() {
      $(this).show(); // show links
    });
    return;
  } else {
    $('a').removeClass('collapsed');
    $('a').each(function() {
      $(this).hide(); // hide all links once search is begun
    });

    $('a:contains("' + filter + '")').each(function() {
      $(this).removeClass('collapsed'); // remove bootstrap 4 collapsed class designation
      $(this).show(); // show only matched links to search string?

    });
  }
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@import url('https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css');

.navbar-nav.sidebar-nav {
  position: absolute;
  left: 0;
  top: 0;
  margin-top: 56px;
  padding-bottom: 56px;
  height: 100vh;
  background: #292b2c;
  -webkit-flex-direction: column;
  -ms-flex-direction: column;
  flex-direction: column;
  overflow: auto;
}

.navbar-brand {
  display: inline-block;
  padding-top: .25rem;
  padding-bottom: .25rem;
  margin-right: 1rem;
  font-size: 1.25rem;
  line-height: inherit;
  white-space: nowrap;
  color: #fff;
}

.navbar-nav .nav-link {
  color: rgba(255, 255, 255, .5);
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
  <ul class="sidebar-nav navbar-nav">
    <li class="nav-item active">
      <i class="fa fa-fw fa-home"> Home
   
</li>

    <li class="nav-item">
      <label for="nav-search" class="col-2 col-form-label sr-only">Search links</label>
     
        <input class="form-control form-control-sm search-filter" type="search" id="nav-search" placeholder="Search for tools">
     
   
</li>

    <li class="nav-item">
      <span class="navbar-brand">Popular tools</span>
   
</li>

    <li class="nav-item">
      <i class="fa fa-fw fa-calculator"> Calculator
   
</li>

    <li class="nav-item">
      <i class="fa fa-fw fa-battery-3"> Battery
   
</li>

    <li class="nav-item">
      <i class="fa fa-fw fa-database"> Pancake Batter
   
</li>


    <li class="nav-item">
      <i class="fa fa-fw fa-clock-o"> Marzipan
   
</li>

    <li class="nav-item">
      <i class="fa fa-fw fa-tags"> Cakes and Muffins
   
</li>

    <li class="nav-item">
      <span class="navbar-brand">Categories</span>
   
</li>

    <li class="nav-item">
      <i class="fa fa-fw fa-flask"> Cars
      <ul class="sidebar-second-level collapse" id="collapseComponents">
       
<li>

          American
          <ul class="sidebar-third-level collapse" id="collapseMulti2">
           
<li>

              Ford
           
</li>

           
<li>

              GMC
           
</li>

         
</ul>

       
</li>

       
<li>

          European
          <ul class="sidebar-third-level collapse" id="collapseMulti3">
           
<li>

              BMW
           
</li>

           
<li>

              Audi
           
</li>

         
</ul>

       
</li>

     
</ul>

   
</li>

 
</ul>



<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js">
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js">


好吧,我想我已经自己解决了(在这篇文章的一个不区分大小写的过滤器的帮助下)。

1)我更新了链接,将它们包装在一个div with id #link-content中,以将我的过滤器与home和search输入分开。

2)我添加了上述不区分大小写的方法

我的HTML:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
   <ul class="sidebar-nav navbar-nav">
      <li class="nav-item active">
         <i class="fa fa-fw fa-home"> Home
     
</li>

      <li class="nav-item">
         <label for="nav-search" class="col-2 col-form-label sr-only">Search links</label>
         
            <input class="form-control form-control-sm search-filter" type="search" id="nav-search" placeholder="Search for tools">
         
     
</li>

 <!-- added this to wrap the links-->    
      <li class="nav-item">
         <span class="navbar-brand">Popular tools</span>
     
</li>

      <li class="nav-item filter">
         <i class="fa fa-fw fa-calculator"> Calculator
     
</li>

      <li class="nav-item  filter">
         <i class="fa fa-fw fa-battery-3"> Battery
     
</li>

      <li class="nav-item  filter">
         <i class="fa fa-fw fa-database"> Pancake Batter
     
</li>


      <li class="nav-item  filter">
         <i class="fa fa-fw fa-clock-o"> Marzipan
     
</li>

      <li class="nav-item  filter">
         <i class="fa fa-fw fa-tags"> Cakes and Muffins
     
</li>

      <li class="nav-item  filter">
         <span class="navbar-brand">Categories</span>
     
</li>

      <li class="nav-item">
         <i class="fa fa-fw fa-flask"> Cars
         <ul class="sidebar-second-level collapse" id="collapseComponents">
           
<li>

               American
               <ul class="sidebar-third-level collapse" id="collapseMulti2">
                 
<li>

                     Ford
                 
</li>

                 
<li>

                     GMC
                 
</li>

               
</ul>

           
</li>

           
<li>

               European
               <ul class="sidebar-third-level collapse" id="collapseMulti3">
                 
<li>

                     BMW
                 
</li>

                 
<li>

                     Audi
                 
</li>

               
</ul>

           
</li>

         
</ul>

     
</li>

     
   
</ul>

我的更新代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Case insensitive method for filter
jQuery.expr[':'].casecontains = (a, b, c) => jQuery(a).text().toUpperCase().indexOf(c[3].toUpperCase()) >= 0;

$('.search-filter').on('keyup', function () {
            var input = $('.search-filter').val();
                        console.log('input: '+input);
            if (input.length != 0) {
            // first hide the div #link-content lists from view
            $('#link-content li').hide();
            // but secretly unhide the collapsed links
            // using .show, so the nested uls can be viewed
            $('#link-content li.nav-item ul').show();
            // then filter in the matching links only
            $('#link-content li:casecontains("'+input+'")').show();
            } else {
            // secretly unhide the collapsed links
            $('#link-content li.nav-item ul').hide();  
            // if search is empty, show the div and reset columns
            $('#link-content li').show();
            }
        });

下面是一个打开任何隐藏链接的工作示例(boosttrap 4中的折叠类)。


我使用的方法是记住哪些项匹配,然后使用该列表取消隐藏父项。

更新了fiddle:https://jsfiddle.net/j2gpann3/1/

这种方法的优点是隐藏的子菜单项(如"宝马"等)现在将显示在搜索中,并且与其他隐藏项之间不会有巨大的差距。regex搜索会搜索每个单词的出现情况,因此即使它们与菜单项文本的顺序不对,它仍然会匹配。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
$('.search-filter').on('keyup', function() {
  var matches = [];
  var input = $.trim($('.search-filter').val());
  var val = '^(?=.*\\b' + input.split(/\s+/).join('\\b)(?=.*\\b') + ').*$'; // using individual word matching filter from http://stackoverflow.com/a/9127872/1544886
  var filter = RegExp(val, 'i');

  if (input.length === 0) { // show all if filter is empty

    $('.collapse').removeClass('show').addClass('collapsed'); // hide collapsable items fast.
    $('.hide').removeClass('hide'); // remove any hidden elements from previous searches
  } else {
    $('.collapse').addClass('show'); // show all collapsed items

    $('ul.sidebar-nav a:not(".home")').filter(function() { // skip home
<li>
 so it shows permanently
        $this = $(this);

        // test for a match to search string
        text = $this.text().replace(/\s+/g, ' ');
        var isMatch = filter.test(text);

                // store match so we can unhide parents of this item
        if (isMatch) matches.push($this);

        return !isMatch;
    }).parent().addClass('hide'); // this hides any
<li>
 that doesn't match search terms. Hiding  results in large gaps in the output

    $.each(matches, function() { // unhide parents of our matches
        this.parentsUntil(".sidebar-nav",".hide").removeClass('
hide');
    });
  }
});

演示需要在home链接中添加一个home类,以防止搜索隐藏该类:

1
<i class="fa fa-fw fa-home"> Home

增加了一个用于hide的css类:

1
2
3
.hide {
  display: none;
}


如果删除:

1
toLowerCase();

如果你把它打得很好,所有的东西都很匹配。问题是,您将搜索词设为小写,但它与小写词不匹配。所以当你输入计算器时,它不匹配,因为实际的导航项显示为计算器,大写C。

因此,您也可以通过HTML或JavaScript将导航项设置为小写,或者使用不同的方式(即使用ID),但如果站点是动态的,这将导致问题。

有些奇怪的工作可能是将每个单词的第一个字母大写,使其与HTML相匹配。看看如何将每个单词的第一个字母大写,比如两个单词的city?