У меня есть этот код, как показано ниже, который дает мне несколько вкладок. У меня проблема с селектором: если вы нажмете на нижнюю строку, селектор не сдвинется вниз.
Также, если изменить его размер, селектор станет еще хуже. Есть ли способ заставить Selector работать правильно, чтобы он заполнил контейнер-оболочку или просто соответствовал тексту?
<style>
@import url('https://fonts.googleapis.com/css?family=Roboto');
@import url('https://use.fontawesome.com/releases/v5.0.13/css/all.css');
body {
font-family: 'Roboto', sans-serif;
}
.wrapper {
/*
text-align: center;
*/
margin: 50px auto;
}
.tabs {
margin-top: 50px;
font-size: 15px;
padding: 0px;
list-style: none;
background: #fff;
box-shadow: 0px 5px 20px rgba(0, 0, 0, 0.1);
/*
display: inline-block;
*/
border-radius: 50px;
position: relative;
}
.tabs a {
text-decoration: none;
color: #777;
text-transform: uppercase;
padding: 10px 20px;
display: inline-block;
position: relative;
z-index: 1;
transition-duration: 0.6s;
}
.tabs a.active {
color: #fff;
}
.tabs a i {
margin-right: 5px;
}
.tabs .selector {
height: 100%;
display: inline-block;
position: absolute;
left: 0px;
top: 0px;
z-index: 1;
border-radius: 50px;
transition-duration: 0.6s;
transition-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55);
background: #05abe0;
background: -moz-linear-gradient(45deg, #05abe0 0%, #8200f4 100%);
background: -webkit-linear-gradient(45deg, #05abe0 0%, #8200f4 100%);
background: linear-gradient(45deg, #05abe0 0%, #8200f4 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#05abe0', endColorstr='#8200f4', GradientType=1);
}
.tabs-content {
display: none;
}
.tabs-content.active {
display: block;
}
</style>
<script type = "text/javascript" src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class = "wrapper">
<nav class = "tabs">
<div class = "selector"></div>
<a href = "javascript:void(0)" class = "active" data-id = "1"><i class = "fas fa-burn"></i>Avengers</a>
<a href = "javascript:void(0)" data-id = "2"><i class = "fas fa-bomb"></i>Guardians of The Galaxy</a>
<a href = "javascript:void(0)" data-id = "3"><i class = "fas fa-bolt"></i>Thor</a>
<a href = "javascript:void(0)" data-id = "4"><i class = "fab fa-superpowers"></i>Black Panther</a>
<a href = "javascript:void(0)" data-id = "4"><i class = "fab fa-superpowers"></i>Black Panther</a>
<a href = "javascript:void(0)" data-id = "4"><i class = "fab fa-superpowers"></i>Black Panther</a>
<a href = "javascript:void(0)" data-id = "4"><i class = "fab fa-superpowers"></i>Black Panther</a>
<a href = "javascript:void(0)" data-id = "4"><i class = "fab fa-superpowers"></i>Black Panther</a>
<a href = "javascript:void(0)" data-id = "4"><i class = "fab fa-superpowers"></i>Black Panther</a>
<a href = "javascript:void(0)" data-id = "4"><i class = "fab fa-superpowers"></i>Black Panther</a>
</nav>
</div>
<div class = "tabs-content active" id = "content1">
<p>
Bacon ipsum dolor sit amet beef venison beef ribs kielbasa. Sausage pig leberkas, t-bone sirloin shoulder
bresaola. Frankfurter rump porchetta ham. Pork belly prosciutto brisket meatloaf short ribs.
</p>
<p>
Brisket meatball turkey short loin boudin leberkas meatloaf chuck andouille pork loin pastrami spare ribs
pancetta rump. Frankfurter corned beef beef tenderloin short loin meatloaf swine ground round venison.
</p>
</div>
<div class = "tabs-content" id = "content2">
<p>
Bacon ipsum dolor sit amet landjaeger sausage brisket, jerky drumstick fatback boudin ball tip turducken.
Pork
belly meatball t-bone bresaola tail filet mignon kevin turkey ribeye shank flank doner cow kielbasa shankle.
Pig
swine chicken hamburger, tenderloin turkey rump ball tip sirloin frankfurter meatloaf boudin brisket ham
hock.
Hamburger venison brisket tri-tip andouille pork belly ball tip short ribs biltong meatball chuck. Pork chop
ribeye tail short ribs, beef hamburger meatball kielbasa rump corned beef porchetta landjaeger flank. Doner
rump
frankfurter meatball meatloaf, cow kevin pork pork loin venison fatback spare ribs salami beef ribs.
</p>
<p>
Jerky jowl pork chop tongue, kielbasa shank venison. Capicola shank pig ribeye leberkas filet mignon brisket
beef kevin tenderloin porchetta. Capicola fatback venison shank kielbasa, drumstick ribeye landjaeger beef
kevin
tail meatball pastrami prosciutto pancetta. Tail kevin spare ribs ground round ham ham hock brisket
shoulder.
Corned beef tri-tip leberkas flank sausage ham hock filet mignon beef ribs pancetta turkey.
</p>
</div>
<script type = "text/javascript">
var tabs = $('.tabs');
var items = $('.tabs').find('a').length;
var selector = $(".tabs").find(".selector");
var activeItem = tabs.find('.active');
var activeWidth = activeItem.innerWidth();
var activeHeight = activeItem.innerHeight();
$(".selector").css({
"left": activeItem.position.left + "px",
"right": activeItem.position.right + "px",
"width": activeWidth + "px",
"height": activeHeight + "px"
});
$(".tabs").on("click", "a", function (e) {
e.preventDefault();
$('.tabs a').removeClass("active");
$(this).addClass('active');
var activeWidth = $(this).innerWidth();
var itemPos = $(this).position();
$(".selector").css({
"left": itemPos.left + "px",
"width": activeWidth + "px"
});
// Hide all tabs
$('.tabs-content').hide();
// Get id of link clicked
var id = $(this).data("id");
// Show current tab
$('#content' + id).show();
});
</script>



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вместо того, чтобы использовать div «селектор», не могли бы вы просто применить стиль к активному тегу «a»?
Редактировать
Хорошо, я вижу, что вы пытаетесь сделать в отношении анимации селектора для выбранного элемента.
Добавьте «справа» и «снизу» в CSS .selector следующим образом:
.tabs .selector {
height: 100%;
display: inline-block;
position: absolute;
left: 0px;
top: 0px;
right:0px;
bottom:0px;
z-index: 1;
border-radius: 50px;
transition-duration: 0.6s;
transition-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55);
background: #05abe0;
background: -moz-linear-gradient(45deg, #05abe0 0%, #8200f4 100%);
background: -webkit-linear-gradient(45deg, #05abe0 0%, #8200f4 100%);
background: linear-gradient(45deg, #05abe0 0%, #8200f4 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#05abe0', endColorstr='#8200f4', GradientType=1);
}
И добавьте «верхнюю» позицию в следующую часть кода:
$(".tabs").on("click", "a", function (e) {
e.preventDefault();
$('.tabs a').removeClass("active");
$(this).addClass('active');
var activeWidth = $(this).innerWidth();
var itemPos = $(this).position();
$(".selector").css({
"left": itemPos.left + "px",
"top": itemPos.top + "px",
"width": activeWidth + "px"
});
Редактировать 2
Чтобы установить все элементы одинаковой ширины, вы можете использовать:
var maxWidth = 0;
var $element;
$(".tabs a").each(function(){
$element = $(this);
if ($element.width() > maxWidth){
maxWidth = $element.width();
}
});
$(".tabs a").each(function(){
$(this).width(maxWidth);
});
Редактировать 3
Это пример кода, который обсуждался в комментариях:
<script type = "text/javascript" src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class = "wrapper">
<nav class = "tabs">
<div class = "selector"></div>
<a href = "javascript:void(0)" class = "active" data-id = "1"><i class = "fas fa-burn"></i>Avengers</a>
<a href = "javascript:void(0)" data-id = "2"><i class = "fas fa-bomb"></i>Guardians of The Galaxy</a>
<a href = "javascript:void(0)" data-id = "3"><i class = "fas fa-bolt"></i>Thor</a>
<a href = "javascript:void(0)" data-id = "4"><i class = "fab fa-superpowers"></i>Black Panther</a>
<a href = "javascript:void(0)" data-id = "5"><i class = "fab fa-superpowers"></i>Black Panther</a>
<a href = "javascript:void(0)" data-id = "6"><i class = "fab fa-superpowers"></i>Black Panther</a>
<a href = "javascript:void(0)" data-id = "7"><i class = "fab fa-superpowers"></i>Black Panther</a>
<a href = "javascript:void(0)" data-id = "8"><i class = "fab fa-superpowers"></i>Black Panther</a>
<a href = "javascript:void(0)" data-id = "9"><i class = "fab fa-superpowers"></i>Black Panther</a>
<a href = "javascript:void(0)" data-id = "10"><i class = "fab fa-superpowers"></i>Black Panther</a>
</nav>
</div>
<div class = "tabs-content active" id = "content1">
<p>
Bacon ipsum dolor sit amet beef venison beef ribs kielbasa. Sausage pig leberkas, t-bone sirloin shoulder
bresaola. Frankfurter rump porchetta ham. Pork belly prosciutto brisket meatloaf short ribs.
</p>
<p>
Brisket meatball turkey short loin boudin leberkas meatloaf chuck andouille pork loin pastrami spare ribs
pancetta rump. Frankfurter corned beef beef tenderloin short loin meatloaf swine ground round venison.
</p>
</div>
<div class = "tabs-content" id = "content2">
<p>
Bacon ipsum dolor sit amet landjaeger sausage brisket, jerky drumstick fatback boudin ball tip turducken.
Pork
belly meatball t-bone bresaola tail filet mignon kevin turkey ribeye shank flank doner cow kielbasa shankle.
Pig
swine chicken hamburger, tenderloin turkey rump ball tip sirloin frankfurter meatloaf boudin brisket ham
hock.
Hamburger venison brisket tri-tip andouille pork belly ball tip short ribs biltong meatball chuck. Pork chop
ribeye tail short ribs, beef hamburger meatball kielbasa rump corned beef porchetta landjaeger flank. Doner
rump
frankfurter meatball meatloaf, cow kevin pork pork loin venison fatback spare ribs salami beef ribs.
</p>
<p>
Jerky jowl pork chop tongue, kielbasa shank venison. Capicola shank pig ribeye leberkas filet mignon brisket
beef kevin tenderloin porchetta. Capicola fatback venison shank kielbasa, drumstick ribeye landjaeger beef
kevin
tail meatball pastrami prosciutto pancetta. Tail kevin spare ribs ground round ham ham hock brisket
shoulder.
Corned beef tri-tip leberkas flank sausage ham hock filet mignon beef ribs pancetta turkey.
</p>
</div>
<script>
var maxWidth = 0;
var $element;
$(".tabs a").each(function(){
$element = $(this);
if ($element.width() > maxWidth){
maxWidth = $element.width();
}
});
$(window).on('resize', function(){
$(".selector").hide();
var activeItem = $(".tabs a[class*='active']");
var id = activeItem.data("id");
setSelectorPosition(id);
});
$(".tabs a").each(function(){
$(this).width(maxWidth);
});
// Set first active link
setSelectorPosition(1);
$(".tabs").on("click", "a", function (e) {
e.preventDefault();
$('.tabs a').removeClass("active");
$(this).addClass('active');
// Get id of link clicked
var id = $(this).data("id");
// Set selector position
setSelectorPosition(id);
// Hide all tabs
$('.tabs-content').hide();
// Show current tab
$('#content' + id).show();
});
function setSelectorPosition(id) {
var activeItem = $(".tabs").find("[data-id='" + id + "']");
var activeWidth = activeItem.innerWidth();
var itemPos = activeItem.position();
$(".selector").css({
"left": itemPos.left + "px",
"top": itemPos.top + "px",
"width": activeItem.innerWidth() + "px",
"height": activeItem.innerHeight() + "px"
});
$(".selector").show();
}
</script>
<style>
@import url('https://fonts.googleapis.com/css?family=Roboto');
@import url('https://use.fontawesome.com/releases/v5.0.13/css/all.css');
body {
font-family: 'Roboto', sans-serif;
}
.wrapper {
text-align: center;
margin: 50px auto;
}
.tabs {
margin-top: 50px;
font-size: 15px;
list-style: none;
background: #fff;
box-shadow: 0px 5px 20px rgba(0, 0, 0, 0.1);
display: inline-block;
border-radius: 50px;
position: relative;
}
.tabs a {
text-decoration: none;
color: #777;
text-transform: uppercase;
padding: 10px 20px;
display: inline-block;
position: relative;
z-index: 1;
transition-duration: 0.6s;
}
.tabs a.active {
color: #fff;
}
.tabs a i {
margin-right: 5px;
}
.tabs .selector {
display:none;
height: 100%;
position: absolute;
left: 0px;
top: 0px;
right:0px;
bottom:0px;
z-index: 1;
border-radius: 50px;
transition-duration: 0.6s;
transition-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55);
background: #05abe0;
background: -moz-linear-gradient(45deg, #05abe0 0%, #8200f4 100%);
background: -webkit-linear-gradient(45deg, #05abe0 0%, #8200f4 100%);
background: linear-gradient(45deg, #05abe0 0%, #8200f4 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#05abe0', endColorstr='#8200f4', GradientType=1);
}
.tabs-content {
display: none;
}
.tabs-content.active {
display: block;
}
</style>
Это работает, но у меня есть еще 2 проблемы с ним. Когда я раскомментирую text-align в оболочке, он перестает работать правильно. И это не очень хорошо выглядит при переключении через другие элементы (во-первых, он выходит за пределы оболочки, но в целом это выглядит неприятно. Может быть, есть способ изменить размер текста на основе самого длинного txt? и, возможно, центрировать его? сделает его немного более приятным?
Я добавил пример для создания всех элементов одинаковой ширины.
Вы также можете добавить $(window).on('resize', function(){ ** Установить здесь позицию селектора ** }); так что, если размер окна браузера изменяется, он правильно устанавливает положение селектора.
Да, кажется, что селектор размещается неправильно, если я меняю обертку на .wrapper { text-align: center;margin: 50px auto; }
Вы имеете в виду только начальный селектор? Остальное, кажется, работает нормально, как в этом примере: jsfiddle.net/1rgsj96L
Да, первоначальный. И, как вы заметили, выходит за рамки. Не уверены, сможет ли он правильно заполнять границы?
Взгляните на обновленную скрипту, которая устанавливает позицию исходного элемента: jsfiddle.net/4asdLomn.
Я снова обновил, чтобы решить проблему с начальной загрузкой, чтобы она была скрыта по умолчанию, а затем отображалась после того, как она установлена в первый раз: jsfiddle.net/4asdLomn/2
Ага, вроде нормально работает. Еще одна проблема из моего списка. еще 2 впереди. Проблема с изменением размера, о которой вы уже упоминали, и выход за пределы обертки? Можно ли было бы подогнать его поплотнее? И границы совпадают? Или это слишком много работы и трудно сделать?
См. обновление с добавленным кодом изменения размера. Не уверен, что вы имеете в виду под выходом за пределы, как это можно воспроизвести? Это в конкретном браузере, я тестирую в Google Chrome: jsfiddle.net/4asdLomn/3
И я думаю, что самая сложная часть здесь будет заключаться в том, чтобы он фактически заполнил границы (с точки зрения селектора, который должен соответствовать границе обертки, когда он находится в верхнем левом, верхнем правом, нижнем левом, нижнем правом и правом и левом. Если вы знаете что я имею в виду?Но я предполагаю, что это серьезная работа над частью CSS.
Да, я думаю, проблема в том, что из-за того, что кривая границы не соответствует кривой селектора из-за размера вкладок div, это будет довольно сложно, и где селектор находится в абсолютном положении, он не знает, что нельзя выйти за пределы содержащего div.
Верно. Хорошо, не могли бы вы обновить свой ответ окончательными данными, чтобы он был полезен для всех?
Я обновил свой ответ, не беспокойтесь, надеюсь, я помог :-)
Еще одна вещь, если бы я хотел иметь селектор четного размера для каждой строки? Это возможно/легко? Предполагая, что я перестану использовать круглые углы, я думаю, это будет выглядеть лучше? В зависимости от количества элементов в строке оно может быть разным. Например, первая строка имеет 5-7 элементов, а нижняя - 3 или 1. Селектор для нижнего элемента должен заполнить всю страницу.
Или, что еще лучше, иметь четное число в каждой строке, если это возможно.
Я думаю, что проблема с тем, что он не работает, и необходимость установить для всех ссылок одинаковую ширину связана с тем, что полоса прокрутки показывает и не показывает, когда выбраны ссылки, у которых не было содержимого вкладок, что поэтому сделало div «tabs» немного шире или уже. Я добавил содержимое вкладок для всех элементов и удалил код «одинаковая ширина для всех ссылок» и думаю, что это работает намного лучше: jsfiddle.net/sgt045ab
Это выглядит лучше, но не работает, если это всего лишь 1 строка (селектор не выровнен должным образом).
Также есть способ setSelectorPosition(1); исправить это, чтобы 1 не был жестко запрограммирован? Как он принимает активную вкладку (действительно активную) при запуске? У меня есть код, который автоматически генерирует идентификаторы, а идентификатор не называется 1,2,3 и так далее.
var activeItem = $(".tabs a[class*='active']"); var id = activeItem.data("id"); setSelectorPosition(id); кажется, помогает
Я, наверное, мог. Я просто не очень разбираюсь в CSS/JS/HTML, поэтому я действительно не знаю, что делаю.