简体   繁体   English

Accordion JS 问题 - 单击时它会打开到手风琴的底部,而不是停留在我单击的顶部

[英]Accordion JS Problem - when click it opens to the bottom of the accordion instead of staying at top where i clicked

Having an issue with an accordion where when i open one, it scrolls to the bottom instead of staying at where i clicked and expanding.手风琴有问题,当我打开手风琴时,它会滚动到底部,而不是停留在我单击并展开的位置。 I THOUGHT it may be b/ci have other JS on the site that may be conflicting but i removed it from the codepen below and tried it and i still see the same issue.我认为可能是 b/ci 网站上的其他 JS 可能存在冲突,但我从下面的 codepen 中删除了它并尝试了它,但我仍然看到同样的问题。

Update: Codepen and see below for instructions on how to test it to see what i mean:更新: Codepen并在下面查看有关如何测试它以了解我的意思的说明:

As mentioned, the site has other JS that i put in the codepen but if you remove it, you'll see the problems still happen.如前所述,该站点还有其他 JS 放入 codepen,但如果您删除它,您会看到问题仍然存在。

When viewing Codepen link, on the right side, that is the unrelated JS is for other aspects on the site.查看 Codepen 链接时,在右侧,即不相关的 JS 用于站点上的其他方面。 The actual Accordion Javascript is on the HTML panel in the CODEPEN at the very bottom (at the bottom of the HTML).实际的 Accordion Javascript 位于 CODEPEN 最底部(HTML 底部)的 HTML 面板上。

To see what I see:看看我所看到的:

  • open up section 2打开第 2 节
  • Then scroll down to section 3 and click it to open it, you'll see that it auto scrolls to the bottom of section 3.然后向下滚动到第 3 部分并单击它打开它,您会看到它自动滚动到第 3 部分的底部。

Or或者

  • with section 3 open, try to open section 4 and it scrolls to the bottom instead of staying at the top.在第 3 部分打开的情况下,尝试打开第 4 部分,它会滚动到底部而不是停留在顶部。

I wanted the first accordion open when reaching the section which it does, however it seems that it has an issue when what's INSIDE the is higher than the height of the screen.我希望第一个手风琴在到达它所在的部分时打开,但是当里面的东西高于屏幕的高度时,它似乎有问题。

I'd like it though that if click on Accordion Title 4 that it stays at the same point on the screen instead of taking me to the bottom of the panel.我希望如果单击 Accordion Title 4,它会停留在屏幕上的同一点,而不是将我带到面板的底部。

Right now, if i click on accordion 3 for example, it takes me to the bottom of the accordion and i have to scroll up to the accordion 3 title.现在,例如,如果我单击手风琴 3,它会将我带到手风琴的底部,我必须向上滚动到手风琴 3 的标题。 As mentioned, it seems to do this or have this problem ONLY when the height of the panel is higher than the height of the 100VH如前所述,似乎只有当面板的高度高于 100VH 的高度时才会这样做或有这个问题

IMPORTANT NOTE: it does seem that when all accordion panels are closed, and i try to open one it doesn't do this.重要提示:似乎当所有手风琴面板都关闭时,我尝试打开一个它不会这样做。 For example, i reloaded the page and the first accordion is open by default, and i tried to open the last one which i have a contact form in my real code, and it had the problem of scrolling to the bottom of the panel.例如,我重新加载了页面,默认情况下第一个手风琴是打开的,我试图打开最后一个在我的真实代码中有联系表单的页面,它有滚动到面板底部的问题。 If i closed the first one though, and they're all closed, it doesn't seem to have that issue如果我关闭了第一个,并且它们都关闭了,它似乎没有那个问题

Any help would be appreciated!任何帮助,将不胜感激! Thanks!谢谢!

The JS that is for the accordion on the HTML panel (left) at the bottom is底部 HTML 面板(左)上手风琴的 JS 是

  // W3C's JS Code
  var acc = document.getElementsByClassName("accordion");
  var i;
    
  // Open the first accordion
  var firstAccordion = acc[0];
  var firstPanel = firstAccordion.nextElementSibling;
  firstAccordion.classList.add("active");
  firstPanel.style.maxHeight = firstPanel.scrollHeight + "px";

  // Add onclick listener to every accordion element
  for (i = 0; i < acc.length; i++) {
    acc[i].onclick = function() {
      // For toggling purposes detect if the clicked section is already "active"
      var isActive = this.classList.contains("active");

      // Close all accordions
      var allAccordions = document.getElementsByClassName("accordion");
      for (j = 0; j < allAccordions.length; j++) {
        // Remove active class from section header
        allAccordions[j].classList.remove("active");

        // Remove the max-height class from the panel to close it
        var panel = allAccordions[j].nextElementSibling;
        var maxHeightValue = getStyle(panel, "maxHeight");
      
      if (maxHeightValue !== "0px") {
          panel.style.maxHeight = null;
        }
      }

      // Toggle the clicked section using a ternary operator
      isActive ? this.classList.remove("active") : this.classList.add("active");

      // Toggle the panel element
      var panel = this.nextElementSibling;
      var maxHeightValue = getStyle(panel, "maxHeight");
      
      if (maxHeightValue !== "0px") {
        panel.style.maxHeight = null;
      } else {
        panel.style.maxHeight = panel.scrollHeight + "px";
      }
    };
  }
  
  // Cross-browser way to get the computed height of a certain element. Credit to @CMS on StackOverflow (http://stackoverflow.com/a/2531934/7926565)
  function getStyle(el, styleProp) {
  var value, defaultView = (el.ownerDocument || document).defaultView;
  // W3C standard way:
  if (defaultView && defaultView.getComputedStyle) {
    // sanitize property name to css notation
    // (hypen separated words eg. font-Size)
    styleProp = styleProp.replace(/([A-Z])/g, "-$1").toLowerCase();
    return defaultView.getComputedStyle(el, null).getPropertyValue(styleProp);
  } else if (el.currentStyle) { // IE
    // sanitize property name to camelCase
    styleProp = styleProp.replace(/\-(\w)/g, function(str, letter) {
      return letter.toUpperCase();
    });
    value = el.currentStyle[styleProp];
    // convert other units to pixels on IE
    if (/^\d+(em|pt|%|ex)?$/i.test(value)) { 
      return (function(value) {
        var oldLeft = el.style.left, oldRsLeft = el.runtimeStyle.left;
        el.runtimeStyle.left = el.currentStyle.left;
        el.style.left = value || 0;
        value = el.style.pixelLeft + "px";
        el.style.left = oldLeft;
        el.runtimeStyle.left = oldRsLeft;
        return value;
      })(value);
    }
    return value;
  }
}

This is a workaround, works, but not very smoothly, to have a smoth experience I bellieve you will need to change to a way where the clickable elements are always on the same spot, because the content is very long.这是一种解决方法,有效,但不是很顺利,我相信您需要更改为可点击元素始终位于同一位置的方式,因为内容很长。 For example tabs instead of the accordion, where the tabs will always be on top and the content will be toggled beneath.例如选项卡而不是手风琴,其中选项卡将始终位于顶部,内容将在下方切换。

Here it is:这里是:

Add an id to each of the accordions, for example:为每个手风琴添加一个id ,例如:

<button id="section1" class="accordion">Section 1</button>

<button id="section2" class="accordion">Section 2</button>

and so forth..

And add this piece of code anywhere inside the function in acc[i].onclick = function() { }并将这段代码添加到acc[i].onclick = function() { }中 function

setTimeout(() => {
        location.href = "#" + accordions[i].id;
      }, 200);

When we use for example location.href = "#someid" the browser will position the page to show the element that has that id.例如,当我们使用location.href = "#someid"时,浏览器将 position 页面显示具有该 ID 的元素。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM