导航元素的滑动背景只适用于2个元素,不能更多

Sliding background for navigation elements works only with 2 elements, not more

本文关键字:元素 2个 不能 适用于 背景 导航      更新时间:2023-09-26

我的页面上有一个响应式页面选择器。我正在尝试为当前活动的元素创建一个彩色背景。目前的代码工作良好的2个元素,但如果我添加更多,那么定位将无法工作。这可能与我对.index() jQuery函数缺乏了解有关。

下面是控制背景位置的JavaScript代码:($.parseURL()函数只是测试页面的URL,然后这段代码将其与给定的列表元素匹配)

$.pageSlider = function(todo){
    if (todo === 'update'){
        $('.pageSlider a.active:not([href="'+$.parseURL().hash+'"])').removeClass('active');
        $('.pageSlider a[href="'+$.parseURL().hash+'"]').addClass('active');
        $('.pageSlider').each(function(){
            var $this = $(this);
            var $slideBtn = $this.find('a.slide-button');
            
            var $navs = $this.find('a[href]');
            var navsSize = $navs.size();
            var percent = 100/navsSize;
            var actNavIndx = $navs.index('a.active');
            $navs.css('width',percent+'%');
               console.log(actNavIndx);
            $slideBtn.css('width',percent+'%').animate({left:((actNavIndx*-1)*percent)+'%'});
        });
        return $('.pageSlider a.active[href="'+$.parseURL('/index.php').hash+'"]');
    }
};
window.location.hash = 'lounge';
$.pageSlider("update");
$(window).on('hashchange',function(){
    $.pageSlider("update");
});

2元素演示:

(function($) {
  $.parseURL = function(str) {
    if (typeof str === 'undefined' && typeof window.location.href !== 'undefined') str = window.location.href;
    var check = {
        whole: /^((http|https):'/'/)?((.*'.)?.*'..*|localhost|'d{1,3}'.'d{1,3}'.'d{1,3}'.'d{1,3})'/.*/,
        protocol: /^(http|https):'/'//,
        absolute: /^'/'/((.*'.)?.*'..*|localhost|'d{1,3}'.'d{1,3}'.'d{1,3}'.'d{1,3})'//,
        relative: /^['/](?!'/).*('..*|'/)?.*$/,
        params: /'?.*=.*('&.*'=.*)+[^#.*]/,
      },
      r = {
        protocol: undefined,
        hostname: undefined,
        hash: undefined,
        href: {
          original: undefined,
          noparams: undefined,
        },
        parentDomain: undefined,
        parameters: undefined,
        pathname: {
          nohash: undefined,
          withhash: undefined,
        },
        type: undefined,
      };
    if (typeof str !== 'string') throw new TypeError('Argument must be a string!');
    else if (!check.whole.test(str) && !check.absolute.test(str) && !check.relative.test(str)) throw new Error('Invalid string');
    r.href.original = str;
    if (str.indexOf('#') !== -1) {
      r.hash = str.substring(str.indexOf('#'));
      str = str.substring(0, str.indexOf('#'));
    }
    if (check.params.test(str)) {
      r.parameters = {};
      var urlparams = str.match(check.params)[0].substring(1).split("&");
      for (var i = 0, l = urlparams.length; i < l; i++) {
        var item = urlparams[i].split('=');
        r.parameters[item[0]] = item[1];
      }
      str = str.replace(check.params, '');
      r.href.noparams = str + (typeof r.hash !== 'undefined' ? r.hash : '');
    }
    if (check.protocol.test(str)) {
      r.protocol = str.match(check.protocol)[0];
      r.hostname = str.replace(check.protocol, '');
      r.hostname = r.hostname.substring(0, r.hostname.indexOf('/'));
      r.parentDomain = r.hostname.split('.');
      r.parentDomain.splice(0, 1);
      r.parentDomain = r.parentDomain.join('.');
      if (r.parentDomain == '') r.parentDomain = r.hostname;
      var tmp = str.replace(check.protocol, '');
      r.pathname.nohash = tmp.substring(tmp.indexOf('/'));
      tmp = undefined;
      r.type = 'normal';
    } else {
      r.protocol = window.location.href.match(check.protocol)[0];
      if (check.absolute.test(str)) { //Link starts with "//"
        var tmp = str.replace(/^'/'//, '');
        r.hostname = tmp.substring(0, tmp.indexOf('/'));
        r.pathnam.nohashe = tmp.substring(tmp.indexOf('/'));
        r.type = 'absolute';
        r.href.original = r.href.original.replace(/^'/'//g, r.protocol);
      } else if (check.relative.test(str)) {
        r.hostname = window.location.href.replace(check.protocol, '');
        r.hostname = r.hostname.substring(0, r.hostname.indexOf('/'));
        r.pathname.nohash = r.href.original;
        r.type = 'relative';
      } else {
        throw new Error('Invalid string');
      }
    }
    r.pathname.withhash = r.pathname.nohash + r.hash;
    return r;
  };
  if (typeof $('.pageSlider')[0] !== 'undefined') {
    $.pageSlider = function(todo) {
      if (todo === 'update') {
        $('.pageSlider a.active:not([href="' + $.parseURL().hash + '"])').removeClass('active');
        $('.pageSlider a[href="' + $.parseURL().hash + '"]').addClass('active');
        $('.pageSlider').each(function() {
          var $this = $(this);
          var $slideBtn = $this.find('a.slide-button');
          var $navs = $this.find('a[href]');
          var navsSize = $navs.size();
          var percent = 100 / navsSize;
          var actNavIndx = $navs.index('a.active');
          $navs.css('width', percent + '%');
          console.log(actNavIndx);
          $slideBtn.css('width', percent + '%').animate({
            left: ((actNavIndx * -1) * percent) + '%'
          });
        });
        return $('.pageSlider a.active[href="' + $.parseURL('/index.php').hash + '"]');
      }
    };
    window.location.hash = 'lounge';
    $.pageSlider("update");
    $(window).on('hashchange', function() {
      $.pageSlider("update");
    });
  }
})(jQuery);
body {
  background-color: #777;
}
@media all and (max-width: 500px) {
  .pageSlider {
    white-space: normal;
  }
  .pageSlider a[href] {
    display: block !important;
    width: 100% !important;
  }
  .pageSlider a[href].active {
    background-color: #cccc00;
  }
  .pageSlider .slide-button {
    display: none;
  }
}
.pageSlider {
  margin: 15px auto !important;
  font-size: 1.2em;
  white-space: nowrap;
  height: 35px;
}
.pageSlider a[href] {
  display: inline-block;
  text-align: center;
  text-decoration: none;
  color: #fff;
  position: relative;
  z-index: 2;
}
.pageSlider a[href].active {
  color: #000;
}
.pageSlider .slide-button {
  background-color: #cccc00;
  position: relative;
  top: -35px;
  display: inline-block;
  padding: 0;
  float: left;
  height: inherit;
  z-index: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<div class="pageSlider">
  <a href="#lounge" class="active">Visitor's Lounge</a>
  <a href="#streams">News Stream</a>
  <a class="slide-button"></a>
</div>

vs。3元素demo

(function($){
    $.parseURL = function(str) {
        if (typeof str === 'undefined' && typeof window.location.href !== 'undefined') str = window.location.href;
        var check = {
                whole: /^((http|https):'/'/)?((.*'.)?.*'..*|localhost|'d{1,3}'.'d{1,3}'.'d{1,3}'.'d{1,3})'/.*/,
                protocol: /^(http|https):'/'//,
                absolute: /^'/'/((.*'.)?.*'..*|localhost|'d{1,3}'.'d{1,3}'.'d{1,3}'.'d{1,3})'//,
                relative: /^['/](?!'/).*('..*|'/)?.*$/,
                params: /'?.*=.*('&.*'=.*)+[^#.*]/,
            },
            r = {
                protocol:       undefined,
                hostname:       undefined,
                hash:           undefined,
                href: {
                    original:   undefined,
                    noparams:   undefined,
                }, 
                parentDomain:   undefined,
                parameters:     undefined,
                pathname:       {
                    nohash:     undefined,
                    withhash:   undefined,
                },
                type:           undefined,
            };
        if (typeof str !== 'string') throw new TypeError('Argument must be a string!');
        else if (!check.whole.test(str) && !check.absolute.test(str) && !check.relative.test(str)) throw new Error('Invalid string');
        
        r.href.original = str;
        
        if (str.indexOf('#') !== -1){
            r.hash = str.substring(str.indexOf('#'));
            str = str.substring(0,str.indexOf('#'));
        }
        if (check.params.test(str)){
            r.parameters = {};
            var urlparams = str.match(check.params)[0].substring(1).split("&");
            for (var i=0,l=urlparams.length; i<l; i++){
                var item = urlparams[i].split('=');
                r.parameters[item[0]] = item[1];
            }
            str = str.replace(check.params,'');
            r.href.noparams = str+(typeof r.hash !== 'undefined' ? r.hash : '');
        }
        if (check.protocol.test(str)){
            r.protocol = str.match(check.protocol)[0];
            r.hostname = str.replace(check.protocol,'');
            r.hostname = r.hostname.substring(0,r.hostname.indexOf('/'));
            r.parentDomain = r.hostname.split('.');
            r.parentDomain.splice(0,1);
            r.parentDomain = r.parentDomain.join('.');
            if (r.parentDomain == '') r.parentDomain = r.hostname;
            
            var tmp = str.replace(check.protocol,'');
                r.pathname.nohash = tmp.substring(tmp.indexOf('/'));
            tmp = undefined;
            
            r.type = 'normal';
        }
        else {
            r.protocol = window.location.href.match(check.protocol)[0];
            
            if (check.absolute.test(str)){ //Link starts with "//"
                var tmp = str.replace(/^'/'//,'');
                r.hostname = tmp.substring(0,tmp.indexOf('/'));
                r.pathnam.nohashe = tmp.substring(tmp.indexOf('/'));
                r.type = 'absolute';
                r.href.original = r.href.original.replace(/^'/'//g,r.protocol);
            }
            else if (check.relative.test(str)){
                r.hostname = window.location.href.replace(check.protocol,'');
                r.hostname = r.hostname.substring(0,r.hostname.indexOf('/'));
                r.pathname.nohash = r.href.original;
                r.type = 'relative';
            }
            else {
                throw new Error('Invalid string');
            }
        }
        
        r.pathname.withhash = r.pathname.nohash+r.hash;
        
        return r;
    };
    
    if (typeof $('.pageSlider')[0] !== 'undefined'){
        $.pageSlider = function(todo){
            if (todo === 'update'){
                $('.pageSlider a.active:not([href="'+$.parseURL().hash+'"])').removeClass('active');
                $('.pageSlider a[href="'+$.parseURL().hash+'"]').addClass('active');
            $('.pageSlider').each(function(){
                var $this = $(this);
                var $slideBtn = $this.find('a.slide-button');
                
                var $navs = $this.find('a[href]');
                var navsSize = $navs.size();
                var percent = 100/navsSize;
                var actNavIndx = $navs.index('a.active');
                
                $navs.css('width',percent+'%');
                console.log(actNavIndx);
                $slideBtn.css('width',percent+'%').animate({left:((actNavIndx*-1)*percent)+'%'});
            });
                
                return $('.pageSlider a.active[href="'+$.parseURL('/index.php').hash+'"]');
            }
        };
        window.location.hash = 'lounge';
        $.pageSlider("update");
        $(window).on('hashchange',function(){
            $.pageSlider("update");
        });
    }
})(jQuery);
body {
    background-color:#777;    
}
@media all and (max-width: 500px){
    .pageSlider {
        white-space: normal;
    }
    .pageSlider a[href]{
        display: block !important;
        width: 100% !important;
    }
    .pageSlider a[href].active {
        background-color: #cccc00;
    }
    .pageSlider .slide-button {
        display: none;
    }
}
.pageSlider {
    margin: 15px auto !important;
    font-size: 1.2em;
    white-space: nowrap;
    height: 35px;
}
.pageSlider a[href] {
    display: inline-block;
    text-align: center;
    text-decoration: none;
    color: #fff;
    position: relative;
    
    z-index: 2;
}
.pageSlider a[href].active {
    color: #000;
}
.pageSlider .slide-button {
    background-color: #cccc00;
    position: relative;
    top: -35px;
    display: inline-block;
    padding: 0;
    float: left;
    height: inherit;
    z-index: 1;
}
        <div class="pageSlider">
            <a href="#lounge" class="active">Visitor's Lounge</a>
            <a href="#streams">News Stream</a>
            <a href="#test">Test</a>
            <a class="slide-button"></a>
        </div>

你的index()确实是误用了:

var actNavIndx = $navs.index('a.active');

应为:

var actNavIndx = $this.children('a.active').index();

和动画:

$slideBtn.css('width',percent+'%').animate({left:((actNavIndx*-1)*percent)+'%'});

应为:

$slideBtn.css('width',percent+'%').animate({left:((actNavIndx)*percent)+'%'});