【问题标题】:How to scroll to the vertical center of targeted html sections with JavaScript?如何使用 JavaScript 滚动到目标 html 部分的垂直中心?
【发布时间】:2018-10-03 16:59:01
【问题描述】:

我无法将此代码转换为可在 iOS 11、Safari、Chrome 和 FF 上以相同行为运行的 vanilla js。我遇到的主要问题是得到 offsetUnit,它帮助我滚动到该部分的中心,以便文本显示在窗口中间。

$(document).on('click', 'a[href^="#"]', function (e) {
  e.preventDefault();
  var offsetUnit = $(window).height() * 0.5;
  $('html, body').scrollTop($($.attr(this, 'href')).offset().top+offsetUnit);
});
* {
  margin: 0;
  padding: 0;
}

section {
  height: 200vh;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
}

section > div {
  height: 100vh;
  width: 100%;
  flex: 1;
  background-color: pink;
  display: flex;
  align-items: center;
  justify-content: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<nav>
  <ul>
    <li>
      <a href="#about">About</a>
    </li>
    <li>
      <a href="#treatments">Treatments</a>
    </li>
    <li>
      <a href="#prices">Prices</a>
    </li>
    <li>
      <a href="#contact">Contact</a>
    </li>
  </ul>
</nav>

<section id="about"><div>About</div></section>
<section id="treatments"><div>Treatments</div></section>
<section id="prices"><div>Prices</div></section>
<section id="contact"><div>Contact</div></section>
目前在 vanilla js 中的失败尝试
function scrollPlease(element) {  
  const offsetUnit = (window.innerHeight + "px") * 0.5;
  window.scrollTo({
    'top': element.offsetTop + offsetUnit
  });
}

const link = document.querySelectorAll("[href='href_value']");
const section = document.querySelectorAll("section");

link.addEventListener('click', () => {
  scrollPlease(section);
});

https://codepen.io/2ne/pen/JmXPLB?editors=1010 - 链接到 codepen

【问题讨论】:

  • offsetUnit有什么问题?您是否获得了与预期不同的价值?还是未定义?您尝试过的 vanillajs 代码是什么?
  • 向我们展示您的尝试。没有它,您的问题就是一项任务,是对编码服务的请求,这使得它在本网站上非常离题。
  • 该问题没有回答如何获得视口高度的 50%,即在 css 中相当于 50vh 单位。它也不处理 iOS 11 如何处理视口的高度。不重复。
  • 对不起,我应该发布我的尝试,但我不想通过遵​​循我失败的方法来引导答案。我会尽快发布我的尝试。谢谢
  • 没关系。这个想法是允许你在这里提问,而不是让你的老板或客户这样做,这会不利于你的兴趣。另一个标准是您的问题应该足够笼统,以便其他人可以从其答案中受益。一次帮助一个用户比一次帮助 10、100 甚至 1k 更没有意义。

标签: javascript jquery html


【解决方案1】:

您正在将offsetUnit 转换为字符串,然后尝试将其作为无效的数字进行操作。此外,您需要将事件侦听器附加到每个链接(您不能像使用 jQuery 那样将侦听器附加到集合)。您没有像在 jQuery 原始文件中那样指定要在 js 中滚动到哪个 section (相反,您只是将所有 section 元素的集合传递给您的函数)。用 cmets 更正了下面的示例(下面的工作 sn-p 中的干净示例):

const links = document.querySelectorAll('a[href^="#"]');
const offsetUnit = window.innerHeight * 0.5;

// the "elems" variable below and the commented loop in the listener code mimic the original jquery scroll positioning
// const elems = document.querySelectorAll('html, body');

for (const link of links) {
  link.addEventListener('click', (event) => {
    event.preventDefault();
    const section = document.querySelector(event.currentTarget.getAttribute('href'));
    window.scrollTo(0, section.offsetTop + offsetUnit);
    
    // the loop below mimics the original jquery (same outcome as window.scrollTo above)
    // for (const elem of elems) {
    //   elem.scrollTop = section.offsetTop + offsetUnit;
    // }
    
  });
}

const links = document.querySelectorAll('a[href^="#"]');
const offsetUnit = window.innerHeight * 0.5;
for (const link of links) {
  link.addEventListener('click', (event) => {
    event.preventDefault();
    let section = document.querySelector(event.currentTarget.getAttribute('href'));
    window.scrollTo(0, section.offsetTop + offsetUnit);
  });
}
* {
  margin: 0;
  padding: 0;
}

section {
  height: 200vh;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
}

section > div {
  height: 100vh;
  width: 100%;
  flex: 1;
  background-color: pink;
  display: flex;
  align-items: center;
  justify-content: center;
}
<nav>
  <ul>
    <li>
      <a href="#about">About</a>
    </li>
    <li>
      <a href="#treatments">Treatments</a>
    </li>
    <li>
      <a href="#prices">Prices</a>
    </li>
    <li>
      <a href="#contact">Contact</a>
    </li>
  </ul>
</nav>
<section id="about">
  <div>About</div>
</section>
<section id="treatments">
  <div>Treatments</div>
</section>
<section id="prices">
  <div>Prices</div>
</section>
<section id="contact">
  <div>Contact</div>
</section>

【讨论】:

  • 啊,好吧,所以我的代码甚至根本不起作用?它只是使用本机目标行为?
  • @2ne - 你明白了
  • Microsoft Edge v42 给我一个语法错误并且代码不起作用。有任何想法吗? "var section = document.querySelector(e.target.getAttribute('href'));"
  • @2ne 您遇到的语法错误是什么?它在 Edge 中也不适合我,但我没有看到语法错误,因为沙盒 iframe 安全警告正在阻止 sn-p(以及小提琴和笔)中的所有内容。我会在 sn-p 之外启动它,看看,然后告诉你我发现了什么。
  • 感谢您如此迅速地修复它。 Edge 是世界上最被高估的浏览器。希望 M$ 会在 IE11 之后的一天调用它 :)
猜你喜欢
  • 1970-01-01
  • 2014-10-13
  • 1970-01-01
  • 2012-06-24
  • 1970-01-01
  • 2019-07-27
  • 2021-11-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多