粘性位置中断 JS 事件侦听器

时间:2021-03-30 00:48:09

标签: javascript html css

我遇到了这样一种情况:我试图在侧边菜单中添加一个也很粘的幻灯片。每当我将 position:sticky 添加到我的菜单容器时,它都会显示整个菜单(而不是通过负左值将其推离屏幕)并且用于打开和关闭菜单的按钮不再起作用。

顺便说一下,菜单动画在绝对容器上完全正常。所以我想知道我是否遗漏了一些东西才能同时工作,或者你根本不能同时做这件事(或者至少不是我想要的方式。

Here's a link a codepen I made to show the issue:

这是css的一个片段:

#side-menu-container{
  width: 100%;
  max-width: 300px;
  height: 100%;
  min-height: 1000px;
  position: absolute;
  left: 0;
  top: 0;
}

/* if I change the positioning here, the event will work */
#side-menu{
  width: 100%;
  max-width: 330px;
  padding: 1rem 0;
  background: #cccccc;
  position: sticky;
  left: -300px;
  top: 100px;
}

#side-menu ul{
  text-align: center;
}

#side-menu li{
  list-style-type: none;
  margin: 1rem;
}

#side-menu-btn{
  width: 50px;
  height: 50px;
  position: absolute;
  left: 100%;
  background: #cccccc;
  cursor: pointer;
}

#side-menu.side-menu-open{
  left: 0;
}

哦,我应该提到我已经尝试将我的主容器元素(包含按钮和菜单)设置为相对,并且我还尝试将 z-index:0 和 z-index:99999 添加到主容器元素容器、按钮和菜单无济于事。这让我觉得没有一个元素覆盖它。

2 个答案:

答案 0 :(得分:2)

我在此代码中列出了您的所有问题

  1. 首先你的父 div 容器有 left: 0;
  2. 其次,您的 main 将 css height 删除。
  3. 最后,由于您的父母,您的 javascript 不会打开添加的类 side-menu-open

希望对您有所帮助,如果您有任何疑问,请在下方评论。 ?

const sideMenu = document.querySelector('#side-menu-container');
const sideMenuBtn = document.querySelector('#side-menu-btn');


sideMenuBtn.addEventListener('click', () => {
  sideMenu.classList.toggle('side-menu-open');
})
*{
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

main{
  width: 100%;
}

section {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  margin: 2rem auto;
  position: relative;
}

h1{
  width: 100%;
  max-width: 750px;
  margin-bottom: 2rem;
  text-align: center;
}

section p{
  width: 100%;
  max-width: 750px;
  margin-bottom: 1rem;
  line-height: 25px;
}

#side-menu-container{
  width: 100%;
  max-width: 300px;
  height: 100%;
  position: absolute;
  left: -300px;
  top: 0;
}

/* if I change the positioning here, the event will work */
#side-menu{
  width: 100%;
  max-width: 330px;
  padding: 1rem 0;
  background: #cccccc;
  position: sticky;
  top: 100px;
}

#side-menu ul{
  text-align: center;
}

#side-menu li{
  list-style-type: none;
  margin: 1rem;
}

#side-menu-btn{
  width: 50px;
  height: 50px;
  position: absolute;
  left: 100%;
  background: #cccccc;
  cursor: pointer;
}

#side-menu-container.side-menu-open{
  left: 0;
}
<main>
  
 <section>
   <div id="side-menu-container">
     <div id="side-menu">
       <div id="side-menu-btn">Open</div>
       <ul>
         <li><a href="">Some Link</a></li>
         <li><a href="">Some Link</a></li>
         <li><a href="">Some Link</a></li>
         <li><a href="">Some Link</a></li>
         <li><a href="">Some Link</a></li>
         <li><a href="">Some Link</a></li>
       </ul>
     </div> 
   </div>
   
   

 <h1>I'm Just Here to be Here</h1>
  
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sit amet finibus neque. Praesent fermentum consequat neque, ac iaculis eros maximus et. Suspendisse aliquet non sem sed eleifend. Sed pretium arcu id nulla sollicitudin venenatis. Nullam posuere ipsum eget pharetra ultrices. Aliquam erat volutpat. Duis quam tortor, dignissim at efficitur vel, volutpat eget orci. Nulla tristique mi odio, viverra rutrum odio molestie sed. Maecenas faucibus justo non rhoncus consequat. Vestibulum quis elementum purus.</p>
  <p>Suspendisse eu leo egestas, euismod justo at, blandit risus. Nam dapibus ac ante vitae pellentesque. Etiam congue ligula ut ante mollis mollis. Interdum et malesuada fames ac ante ipsum primis in faucibus. Ut egestas laoreet pulvinar. Cras sed neque nec est scelerisque maximus in eget turpis. Etiam pharetra accumsan justo, ac pellentesque libero dignissim et. Curabitur id egestas ligula, nec tristique elit. Aenean fringilla urna justo, a congue felis feugiat quis.</p>
  <p>Praesent vehicula consequat enim ac consectetur. Suspendisse eget sem nec mi posuere volutpat sit amet nec eros. Pellentesque et laoreet velit, ut ultricies sapien. Integer hendrerit lorem arcu, in consequat arcu accumsan quis. Sed diam nisl, fermentum id tristique sed, placerat vitae eros. Fusce pulvinar mi urna, in ultrices justo suscipit eget. Proin ut nunc arcu. Nullam dictum ut nulla pulvinar tempus. Sed enim sapien, lacinia vitae ullamcorper non, tempor sed velit. Duis euismod, turpis sed gravida euismod, odio purus finibus tortor, nec euismod libero risus porttitor velit. Duis suscipit erat a fermentum malesuada. Maecenas quam lacus, accumsan sed nunc id, fermentum lobortis augue. Etiam id tortor eros. Ut tincidunt iaculis felis, et efficitur arcu elementum et.</p>
  
</section>
  
</main>

答案 1 :(得分:1)

问题

#side-menu 的负左值不起作用的原因是因为位置粘性仍然在正常流程中设置元素。这意味着元素不能像绝对/固定元素那样超出祖先。

解决方案

解决方案是将#side-menu-container 的左值设置为-300px,然后编辑您的JS 以更改#side-menu-container 的值而不是#side-menu。这符合您的预期,因为 #side-menu-container 是绝对定位的,这意味着它可以位于窗口之外/设置为相对的最近祖先。

postion relative 来自 MDN 的解释:

<块引用>

元素按照正常的流向定位 文档,然后相对于其最近的滚动祖先偏移 和包含块(最近的块级祖先),包括 与表格相关的元素,基于顶部、右侧、底部和 左边。偏移量不会影响任何其他元素的位置。

https://developer.mozilla.org/en-US/docs/Web/CSS/position

我编辑了代码。

CSS

#side-menu-container{
  width: 100%;
  max-width: 300px;
  height: 100%;
  min-height: 1000px;
  position: absolute;
  left: -300px;
  top: 0;
}

/* if I change the positioning here, the event will work */
#side-menu{
  width: 100%;
  max-width: 330px;
  padding: 1rem 0;
  background: #cccccc;
  position: sticky;
  top: 100px;
}

#side-menu ul{
  text-align: center;
}

#side-menu li{
  list-style-type: none;
  margin: 1rem;
}

#side-menu-btn{
  width: 50px;
  height: 50px;
  position: absolute;
  left: 100%;
  background: #cccccc;
  cursor: pointer;
}

#side-menu-container.side-menu-open{
  left: 0;
}

JS

const sideMenu = document.querySelector('#side-menu-container');
const sideMenuBtn = document.querySelector('#side-menu-btn');


sideMenuBtn.addEventListener('click', () => {
  sideMenu.classList.toggle('side-menu-open');
});