首页 > 解决方案 > onClick JS没有转到页面顶部

问题描述

我有一个带有初始描述的页面,后跟 2 个按钮,用户可以在其中选择 typeA 或 typeB。它们按“目标”工作:当用户单击 typeA 时,出现与 typeA 相关的内容,按钮下方;与B型相同。

typeA 是最常见的选择,然后,当页面加载时,javascript 会模拟对 typeA 的点击并打开相应的内容。为了避免隐藏初始描述,还有另一个 javascript 将页面放在顶部。在 Chrome 和 Edge 上工作,而不是在 Firefox 上工作。

我想在用户单击时重复相同的过程:打开相应的内容,但将页面定位在顶部,或者至少显示按钮。我认为事件 onClick 调用相同的 js backToTop 会起作用 - 但不是。

我在 js 上设置了一个警告并在那里输入但不执行:始终保持所选按钮的内容在其更好的可见性中。

我试过:

window.location.href = '#top';
window.scrollBy(0, -500);
document.html.scrollTop = document.documentElement.scrollTop = 0;

没有成功。

我究竟做错了什么?

<head>

<meta charset="UTF-8">
<title>TOP PAGE TEST</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
  
<style>
body,html {margin-left:auto; margin-right:auto;width:70%; font-family:verdana; font-size:1.2em;}
.menuFAQ {background:#aaa; font-size:2em; width:100%;}
    .menuFAQ ul {list-style-type:none; position:relative; margin-left:-40px; /* to avoid user agent chrome */}
.menuFAQ li {display:inline-block; margin-top:10px; margin-bottom:10px; width:49%; background:#fff; text-align:center; box-shadow:2px 3px 4px 0px rgba(170,170,170,1); font-weight:400; line-height:80px;}   
.menuFAQ li a {display:block; color:#020062; background:#fff; font-weight:400; text-decoration:none;}
.menuFAQ li .active,.menuFAQ li:hover a {color:#fff; font-weight:400; background-image:linear-gradient(#165686, #0f3a5a); }

:target {color:#fff;font-size:1em;}

div.items>div:not(:target) {display:none}
div.items>div:target {display:block; margin-left:auto; margin-right:auto; color:#000; border:1px solid #aaa;}
</style>
	
</head>
<body>
<div id="top">Top Page</div>

<br>textExp1<br>textExp2<br>textExp3<br>textExp4<br>textExp5

<div class="menuFAQ">
  <ul>
    <li><a id="preferedFAQ" onclick="backToTop()" class="target" href="#typeA">TypeA</a></li>
    <li><a                  onclick="backToTop()" class="target" href="#typeB">TypeB</a></li>
  </ul>
</div>

<div class="items">
  <div id="typeA">
    <nav>
      A long and variable text size to explain TypeA  <br>text1A<br>text2A<br>text3A<br>text4A<br>text5A<br>text6A<br>text7A<br>text8A<br>text9A<br>textAA<br>textBA<br>textCA<br>textDA
      <br>[...]
    </nav>
  </div>
</div>

<div class="items">
  <div id="typeB">
    <nav>
      A long and variable text size to explain TypeB
      <p>text1B</p><p>text2B</p><p>text3B</p>
      <br>[...]
    </nav>
  </div>
</div>

  
<script>
const allTargetLinks = document.querySelectorAll('.target')

allTargetLinks.forEach(targetLink => {
   targetLink.addEventListener('click', () => {
        allTargetLinks.forEach(targetLink => {
           targetLink.classList.remove('active')
        })
   targetLink.classList.add('active')
   })
})

window.onload = function() {assignPreferedFAQ()};

function assignPreferedFAQ() {
    document.getElementById("preferedFAQ").click();
    backToTop();
};
 
function backToTop() {
   //document.html.scrollTop = document.documentElement.scrollTop = 0;
   //document.body.scrollTop = document.documentElement.scrollTop = 0;
	
     document.body.scrollTop = 0;
     document.documentElement.scrollTop = 0;
};
</script>

标签: javascripthtmlcss

解决方案


关于如何处理click事件和href属性,您在那里遇到了真正的混乱,即:

  • 您的链接上有onclick属性,并且您在 JS 中为它们添加了另一个侦听器
  • 你没有event.preventDefault()在你的功能中,当你点击一个链接时默认的浏览器行为是让你找到它的href路径

我已经清理了一些东西并改变了一些东西。由于我们需要防止默认行为:target选择器不再起作用,所以我做了你已经对链接做的事情,并active为你的内容添加了一个类。clickHandler()现在将active根据需要删除和添加类。最后只需滚动到顶部。这是片段:

document.querySelectorAll('.target').forEach(targetLink => targetLink.addEventListener('click', clickHandler, false));


function clickHandler(ev) {
  ev.preventDefault(); // prevent browser from automatically scrolling to href pos
  
  if (!ev.currentTarget.classList.contains('active')) {
    // disable active elements
    document.querySelector('.target.active').classList.remove('active');
    document.querySelector('.items div.active').classList.remove('active');

    // add class to the clicked on button and its corresponding content tab
    ev.currentTarget.classList.add('active');
    
    // to prevent pointless string slicing below, you'd have to store ids somewhere else i.e in the data-id attribute
    const id = ev.currentTarget.href.slice(ev.currentTarget.href.lastIndexOf('#') + 1);
    document.getElementById(id).classList.add('active');
  }
  
  window.scrollTo(0,0);
}
* {
  font-family: verdana;
  font-size: 1em;
}

.menuFAQ {
  background: #aaa;
  font-size: 2em;
  width: 100%;
}

.menuFAQ ul {
  list-style-type: none;
  text-align: center;
  padding: 0;

  /* to avoid user agent chrome */
}

.menuFAQ li {
  display: inline-block;
  width: 48%;
  margin-top: 10px;
  margin-bottom: 10px;
  background: #fff;
  text-align: center;
  box-shadow: 2px 3px 4px 0px rgba(170, 170, 170, 1);
  font-weight: 400;
  line-height: 80px;
}

.menuFAQ li a {
  display: block;
  color: #020062;
  background: #fff;
  font-weight: 400;
  text-decoration: none;
}

.menuFAQ li .active,
.menuFAQ li:hover a {
  color: #fff;
  font-weight: 400;
  background-image: linear-gradient(#165686, #0f3a5a);
}

div.items>div {
  display: none;
}

div.items>div.active {
  display: block;
  margin-left: auto;
  margin-right: auto;
  color: #000;
  border: 1px solid #aaa;
}
<div id="top">Top Page</div>

<br>textExp1<br>textExp2<br>textExp3<br>textExp4<br>textExp5

<div class="menuFAQ">
  <ul>
    <li><a class="target active" href="#typeA">TypeA</a></li>
    <li><a class="target" href="#typeB">TypeB</a></li>
  </ul>
</div>

<div class="items">
  <div class="active" id="typeA">
    <nav>
      A long and variable text size to explain TypeA <br>text1A<br>text2A<br>text3A<br>text4A<br>text5A<br>text6A<br>text7A<br>text8A<br>text9A<br>textAA<br>textBA<br>textCA<br>textDA
      <br>[...]
    </nav>
  </div>
</div>

<div class="items">
  <div id="typeB">
    <nav>
      A long and variable text size to explain TypeB
      <p>text1B</p>
      <p>text2B</p>
      <p>text3B</p>
      <br>[...]
    </nav>
  </div>
</div>

请注意,现在您的内容仅使用 class 加载,而不是人为地单击页面加载active


推荐阅读