Element.offsetNNN
относительно его offsetParent
, здесь все ваши элементы имеют offsetParent
для элемента <body>
.
На ваш #js-underline
также влияет это заполнение, или, точнее, его родительский элемент.
Так что, когда вы устанавливаете этот элемент слева от других offsetLeft
, его собственный offsetLeft
все еще там.
Один уродливый обходной путь - это измерение offsetLeft, когда стиль left
равен 0
;
const navbarElementsList = document.getElementsByClassName('js-element');
const navbarUnderline = document.getElementById('js-underline');
const default_left = navbarUnderline.offsetLeft;
let navbarElement;
for (let i = 0, len = navbarElementsList.length; i < len; i++) {
navbarElement = navbarElementsList[i];
navbarElementsList[i].addEventListener('click', function(event){
let underlineStart = this.offsetLeft;
let underlineWidth = this.offsetWidth;
navbarUnderline.style.left = underlineStart - default_left + "px";
navbarUnderline.style.width = underlineWidth.toString() + "px";
});
}
ul {
list-style-type: none;
}
li {
display: inline;
}
a {
cursor: pointer;
}
#js-underline {
position: relative;
left: 0;
width: 25px;
height: 5px;;
background-color: blue;
transition: 0.5s ease;
-moz-transition: 0.5s ease;
-webkit-transition: 0.5s ease;
}
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>test</title>
</head>
<body>
<ul style=" margin-left: 40px ;">
<li><a class="c-navbar__element js-element">aaaaaaa</a></li>
<li><a class="c-navbar__element js-element">bbbb</a></li>
<li><a class="c-navbar__element js-element">c</a></li>
<li><a class="c-navbar__element js-element">ddddddddddddddd</a></li>
<li><div id="js-underline" class="c-navbar__underline"></div></li>
</ul>
</body>
</html>
Другой вариант - разместить абсолютно подчеркивание, чтобы поле больше не влияло на него.
const navbarElementsList = document.getElementsByClassName('js-element');
const navbarUnderline = document.getElementById('js-underline');
let navbarElement;
for (let i = 0, len = navbarElementsList.length; i < len; i++) {
navbarElement = navbarElementsList[i];
navbarElementsList[i].addEventListener('click', function(event){
let underlineStart = this.offsetLeft;
let underlineWidth = this.offsetWidth;
navbarUnderline.style.left = underlineStart + "px";
navbarUnderline.style.width = underlineWidth + "px";
});
}
// set to firt item
navbarElementsList[0].click();
ul {
list-style-type: none;
}
li {
display: inline;
}
a {
cursor: pointer;
}
#js-underline {
position: absolute;
left: 0;
width: 25px;
height: 5px;;
background-color: blue;
transition: 0.5s ease;
-moz-transition: 0.5s ease;
-webkit-transition: 0.5s ease;
}
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>test</title>
</head>
<body>
<ul style=" margin-left: 40px ;">
<li><a class="c-navbar__element js-element">aaaaaaa</a></li>
<li><a class="c-navbar__element js-element">bbbb</a></li>
<li><a class="c-navbar__element js-element">c</a></li>
<li><a class="c-navbar__element js-element">ddddddddddddddd</a></li>
<li>
<div id="js-underline" class="c-navbar__underline"></div>
</li>
</ul>
</body>
</html>