анимационная строка под двумя css вкладками - PullRequest
0 голосов
/ 11 марта 2020

Пожалуйста, я хочу знать, как создать анимацию, подобную этой, используя JS или Jquery или Vue Переходы, (я использую bootstrap).

Я хочу переместить строку под TAB1 справа, когда я нажимаю на TAB2. Как я могу оживить div, чтобы плавно перемещаться слева направо и наоборот?

tabs animation Это мой код:

<div class="col-md-12">
  <div class="col-md-6">
        <p>TAB1</p>
  </div>
  <div class="col-md-6">
        <p>TAB2</p>
  </div>
</div>
<div class="col-md-6">
<span style="height:10px;background-color:"></span>
</div>

Ответы [ 6 ]

0 голосов
/ 11 марта 2020

Вы можете использовать этот простой пример для справки, который использует jQuery.

$(document).on('click', '.slider-tabs .nav-link', function() {
  handleTabChange($(this));
});

handleTabChange($('.slider-tabs .active'));

function handleTabChange(tab) {
  var nav = tab.closest('.nav');
  $('.indicator', nav).css({
    width: tab.outerWidth(),
    left: tab.position().left
  });
  tab.siblings().removeClass('active');
  tab.addClass('active');
}
.slider-tabs.nav {
  position: relative;
  margin: 10px;
}

.slider-tabs.nav .nav-link.active {
  background: transparent !important;
  color: #8b076e;
}

.slider-tabs.nav .indicator {
  position: absolute;
  top: 100%;
  min-width: 0;
  width: 0;
  height: 5px;
  background: red;
  transition: left .3s, width .3s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">

<nav class="nav nav-pills slider-tabs">
  <a class="text-sm-center nav-link active" href="#">Active</a>
  <a class="text-sm-center nav-link" href="#">Products</a>
  <a class="text-sm-center nav-link" href="#">Services</a>
  <a class="text-sm-center nav-link" href="#">Link</a>
  <a class="text-sm-center nav-link disabled" href="#">Disabled</a>
  <div class="indicator"></div>
</nav>
0 голосов
/ 11 марта 2020

.navbar {
            list-style: none;
            margin: 50px auto;
            max-width: 720px;
            padding: 0;
            width: 100%;
        }

        .navbar-item {
            background: #fff;
            display: block;
            float: left;
            margin: 0;
            padding: 0;
            width: 20%;
            text-align: center;
        }

        .navbar-item:first-child {
            border-radius: 3px 0 0 3px;
        }

        .navbar-item:last-child {
            border-radius: 0 3px 3px 0;
        }

        .navbar-item.navbar-item-active a {
            color: #e80000;
        }

        .navbar-item a {
            color: #313131;
            display: block;
            padding-top: 20px;
            padding-bottom: 20px;
            text-decoration: none;
        }

        .navbar-item a:hover {
            color: #e80000;
        }

        .navbar-indicator {
            position: relative;
            z-index: 0;
        }

        .navbar-indicator .navbar-item:last-child:before,
        .navbar-indicator .navbar-item:last-child:after {
            content: '';
            display: block;
            position: absolute;
            pointer-events: none;
            -webkit-transition: left 1.3s ease;
            transition: left 1.3s ease;
        }

        .navbar-indicator .navbar-item:last-child:before {
            border: 6px solid transparent;
            border-top-color: #e80000;
            width: 0;
            height: 0;
            top: 0;
            left: 10%;
            margin-left: -3px;
        }

        .navbar-indicator .navbar-item:last-child:after {
            background: #e80000;
            top: -6px;
            bottom: -6px;
            left: 0;
            width: 20%;
            z-index: -1;
        }

        .navbar-indicator .navbar-item:nth-child(1).navbar-item-active~.navbar-item:last-child:after {
            left: 0%;
        }

        .navbar-indicator .navbar-item:nth-child(1).navbar-item-active~.navbar-item:last-child:before {
            left: 10%;
        }

        .navbar-indicator .navbar-item:nth-child(2).navbar-item-active~.navbar-item:last-child:after {
            left: 20%;
        }

        .navbar-indicator .navbar-item:nth-child(2).navbar-item-active~.navbar-item:last-child:before {
            left: 30%;
        }

        .navbar-indicator .navbar-item:nth-child(3).navbar-item-active~.navbar-item:last-child:after {
            left: 40%;
        }

        .navbar-indicator .navbar-item:nth-child(3).navbar-item-active~.navbar-item:last-child:before {
            left: 50%;
        }

        .navbar-indicator .navbar-item:nth-child(4).navbar-item-active~.navbar-item:last-child:after {
            left: 60%;
        }

        .navbar-indicator .navbar-item:nth-child(4).navbar-item-active~.navbar-item:last-child:before {
            left: 70%;
        }

        .navbar-indicator .navbar-item:nth-child(1):hover~.navbar-item:last-child:after {
            left: 0% !important;
        }

        .navbar-indicator .navbar-item:nth-child(1):hover~.navbar-item:last-child:before {
            left: 10% !important;
        }

        .navbar-indicator .navbar-item:nth-child(2):hover~.navbar-item:last-child:after {
            left: 20% !important;
        }

        .navbar-indicator .navbar-item:nth-child(2):hover~.navbar-item:last-child:before {
            left: 30% !important;
        }

        .navbar-indicator .navbar-item:nth-child(3):hover~.navbar-item:last-child:after {
            left: 40% !important;
        }

        .navbar-indicator .navbar-item:nth-child(3):hover~.navbar-item:last-child:before {
            left: 50% !important;
        }

        .navbar-indicator .navbar-item:nth-child(4):hover~.navbar-item:last-child:after {
            left: 60% !important;
        }

        .navbar-indicator .navbar-item:nth-child(4):hover~.navbar-item:last-child:before {
            left: 70% !important;
        }

        .navbar-indicator .navbar-item:last-child:hover:before,
        .navbar-indicator .navbar-item:last-child.navbar-item-active:before {
            left: 90% !important;
        }

        .navbar-indicator .navbar-item:last-child:hover:after,
        .navbar-indicator .navbar-item:last-child.navbar-item-active:after {
            left: 80% !important;
        }

        *,
        *:before,
        *:after {
            box-sizing: border-box;
        }

        .navbar:before,
        .navbar:after {
            content: " ";
            display: table;
        }

        .navbar:after {
            clear: both;
        }

        html {
            background-color: #313131;
            font-family: 'Open Sans', sans-serif;
            font-weight: 800;
        }

        .toggle {
            color: #fff;
            font-family: sans-serif;
            text-align: center;
        }
<!doctype html>
<html lang="en">

<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>css animate border left to right - tabmenu</title>
</head>
<body>
    <ul class="navbar navbar-indicator">
        <li class="navbar-item"><a href="#">Menu 1</a></li>
        <li class="navbar-item"><a href="#">Menu 2</a></li>
        <li class="navbar-item navbar-item-active"><a href="#">Menu 3</a></li>
        <li class="navbar-item"><a href="#">Menu 4</a></li>
        <li class="navbar-item"><a href="#">Menu 5</a></li>
    </ul>
</body>

</html>
0 голосов
/ 11 марта 2020

Я сделал две разные версии.

Первая - это Vue speci c, которая также реализует эффект наведения, так что полоса перемещается при перемещении вкладки и возвращается, если вкладка не была нажата.

Второй пример - простая javascript версия, которая перемещает панель только при нажатии на новую вкладку.

/* Vue Section */
new Vue({
  el: '#app',
  computed: {
    lineStyles() {
      return this.lineTemp == null ? this.line : this.lineTemp;
    }
  },
  mounted() {
    const tab = document.getElementById('nav-tab-1');
    if (tab) {
      let styles = {
        left: tab.offsetLeft,
        width: tab.clientWidth
      }
      this.line = styles;
    }
  },
  data() {
    return {
      currentTab: 2,
      line: {
        left: 0,
        width: 69
      },
      lineTemp: null
    }
  },
  methods: {
    onTabClick(evt) {
      const tab = evt.target
      let styles = {
        left: tab.offsetLeft,
        width: tab.clientWidth
      }
      this.line = styles;
    },
    onTabMouseEnter(evt) {
      const tab = evt.target
      let styles = {
        left: tab.offsetLeft,
        width: tab.clientWidth
      }
      this.lineTemp = styles;
    },
    onTabMouseLeave() {
      this.lineTemp = null;
    }
  }
})


/* Plain JS section */
function onTabClick(evt) {
  setLineStyle(evt.target)
}

function setLineStyle(tab) {
  let line = document.querySelector('.tabs2 > .line')
  line.style.left = tab.offsetLeft + "px";
  line.style.width = tab.clientWidth + "px";
}

/* bind events on load */
window.onload = function() {
  const tabs = document.querySelectorAll('.tabs2 > .nav > .nav-item')
  tabs.forEach((tab, index) => {
    tab.onclick = onTabClick;
    
    if(index == 0) setLineStyle(tab);
  })
}
.line {
  position: absolute;
  bottom: 0;
  transition: left 0.5s ease-in-out, width 0.5s 0.10s;
  height: 10px;
  background-color: blue;
  left: 0;
  width: 69px;
  pointer-events: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script>
<link href="https://unpkg.com/bootstrap@4.4.1/dist/css/bootstrap.min.css" rel="stylesheet" />

<!-- Vue Section -->
<div id="app">
  <h4>Vue Option with hover effect</h4>
  <div class="position-relative">
    <ul class="nav">
      <li v-for="i in 3" :id="`nav-tab-${i}`" class="nav-item" @click="onTabClick" @mouseenter="onTabMouseEnter" @mouseleave="onTabMouseLeave">
        <a class="nav-link" href="#">
          Tab {{ i }}
        </a>
      </li>
    </ul>
    <div class="line" :style="{ left: `${lineStyles.left}px`, width: `${lineStyles.width}px` }"></div>
  </div>
</div>
<hr />

<!-- Plain Javascript Section -->
<div>
  <h4>Plain javascript option with only click</h4>
  <div class="tabs2 position-relative">
    <ul class="nav">
      <li class="nav-item">
        <a class="nav-link" href="#">
          Tab 1
        </a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">
          Long tab 2
        </a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">
          Tab 3
        </a>
      </li>
    </ul>
    <div class="line"></div>
  </div>
</div>
0 голосов
/ 11 марта 2020

Пожалуйста, попробуйте этот код ниже. Я надеюсь, что вы получите ваше решение, включая анимацию.

<div class="col-md-12">
            <div class="tab">
                <p>TAB1</p>
                <p>TAB2</p>
            </div>
        </div>


.tab p {
    display: inline-block;
    margin-right: 30px;
    position: relative;
    margin-bottom: 0;
    font-size: 30px;
}

.tab p:last-child {
    margin-right: 0px;
}

.tab p:before {
    content: '';
    position: absolute;
    left: 0;
    bottom: 0;
    width: 0;
    height: 5px;
    background-color: #8C076E;
    -webkit-transition: .5s;
    transition: .5s
}

.tab p:hover:before {
    width: 100%
}
0 голосов
/ 11 марта 2020

Я использовал эту простую кросс-браузерную библиотеку css для создания множества анимаций. Надеюсь, что это поможет вам решить вашу проблему. (вы можете отделить часть текста и анимировать его нижнюю границу для плавного перемещения слева направо), просто используйте это и сделайте анимацию

анимированной. css

анимация. css> github

0 голосов
/ 11 марта 2020

, если вы хотите сделать это, используйте тег div с position:relative под обеими кнопками, а затем сделайте дочерний элемент этого div с необходимой шириной и задайте его position:absolute. И просто отрегулируйте левое и правое значения на наведение и фокус или ваш требуемый псевдокласс, надеюсь, вы понимаете это

...