动态设置滚动坐标并从这些坐标以200px滚动容差更改DOM元素

Dynamically set scroll coordinates & change DOM element with 200px scroll tolerance from these coordinates

本文关键字:坐标 滚动 DOM 元素 200px 设置 动态      更新时间:2023-09-26

我有一个单页网站,有两个div模块,点击后会展开。

第一个位于顶部的 Hero 部分中,当前代码按预期工作。第二个在页面下方的另一部分。目前,第二个模块在滚动发生后立即关闭。

我需要做的是在单击div时获取文档滚动坐标。然后,一旦用户向上或向下滚动 200px,div就会关闭。无论它(div(在网站上的哪个位置。

我在这里和其他地方找到的所有问题仅涉及设置相对于页面加载窗口位置的滚动容差。但对我来说,这不是傻瓜。这个网站是响应式的,当它改变div的初始位置时,意志/可能是未知的。我需要某种方式在单击div时动态存储视口滚动位置,然后分配 200px 容差。

我希望这是有道理的。我已经在这里待了大约 12+小时了。求救:)

这是小提琴

如果你不想去小提琴这是必要的代码

.HTML:

<body>
  <section id="hero">
    <div>
      <div class="module-cta hero-cta">
        <a class="module-cta__button"><!-- Fallback location -->
          <span class="module-cta__text">PRESS ME</span>
        </a>
        <div class="module-cta__open">
          <div class="module-cta__open-inner">
            <div class="hero-cta__contact-points">
              <div class="phone">
                <div class="hero-cta_contact_logo">
                  <span><!-- phone.svg" --></span>
                </div><!-- .service-logo -->
                <div class="contact_trigger">
                  <a>Scroll down to 200px to see</a>
                </div><!-- .contact_trigger -->
              </div><!-- .phone -->
              <div class="email">
                <div class="hero-cta_contact_logo">
                  <span><!-- email.svg --></span>
                </div><!-- .service-logo -->
                <div class="contact_trigger">
                  <a>this div fold back up</a>
                </div><!-- .contact_trigger -->
              </div><!-- .email -->
            </div><!-- .hero-cta__contact-points -->
            <button class="module-cta__close module-cta__cancel"><i class="icon"><span></span></i></button>
          </div><!-- .hero-cta__open-inner -->
        </div><!-- .hero-cta__open -->
      </div><!-- .hero-cta -->
    </div>
  </section>
  <section class="spacer"></section>
  <section id="service_area">
    <div class="area_input">
      <div class="module-cta area-cta wow fadeInUp" id="form_module">
        <a class="module-cta__button area-cta__button">
          <span class="module-cta__text area-cta__text">NOW PRESS ME</span>
        </a>
        <div class="module-cta__open area-cta__open">
          <div class="module-cta__open-inner area-cta__open-inner">
            <div class="area-cta__search">
              <form class="postcode_form" id="postcode_form" name="postcode_form" action="#">
                <input type="number" id="your_postcode" class="your_postcode" name="postcode" placeholder="3???">
                <button type="button" class="area-btn"><span></span></button>
                <a class="call-now">##########</a>
              </form>
            </div><!-- .area-cta__search -->
            <button class="module-cta__close module-cta__cancel"><i class="icon"><span></span></i></button>
          </div><!-- .area-cta__open-inner -->
        </div><!-- .area-cta__open -->
      </div><!-- .area-cta -->
    </div><!-- .area_input -->
  </section>
  <section class="spacer"></section>
</body>

脚本:我相信其中很多都可以清理和缩小,但现在我只是想让它全部进行。

// opens & closes modules by clicking module name
$('.module-cta__button').on('click', function(){
  if($(this).parent().hasClass('hero-cta')){
    $(this).parent().toggleClass('module-cta--active');
  } else {
    if($(this).parent().hasClass('area-cta')){
      $(this).parent().toggleClass('module-cta--active');
    }
  }
});
// closes modules with .module-cta__close btn
$('.module-cta__close').on('click', function(){
  if($(this).closest('div .module-cta').hasClass('module-cta--active')){
    $(this).closest('div .module-cta').removeClass('module-cta--active');
  }
});
// closes modules on scroll.
// * works but doesn't apply scroll tolerance of 200px for #area
$(window).scroll(function(){
  var currentPos = $(window).scrollTop();
  var module = $('div .module-cta');
  if(module.hasClass('module-cta--active') && module.position().top <= currentPos+200){
    $('div .module-cta--active').removeClass('module-cta--active');
  }
});

// closes modules when escape key is pressed
$(window).keydown(function(escape){
  var key = escape.which;
  if(key == 27){
    $('div .module-cta--active').removeClass('module-cta--active');
  }
});

小提琴css

  • 提前感谢您的任何帮助或有用的建议。

我整理了一个更小、更简单的演示,只是为了向您展示完成此操作所需的变量。本质上,单击div 时,使用 $(document).scrollTop() 捕获当前文档滚动位置。还要存储对已单击的当前div 的引用。

滚动

时,检查当前滚动和新滚动之间的差异,并使用单击的div 引用,在差异为 200 或更大时缩小div。下面的JS小提琴;

https://jsfiddle.net/jLqu4pas/

来自小提琴的代码;

var currentScroll;
var lastClickedDiv;
$('section').click(function(){
  $(this).css({'height' : '400'})
  currentScroll = $(document).scrollTop();
  lastClickedDiv = $(this);
  console.log(currentScroll);
})
$(window).scroll(function(){
  if($(document).scrollTop() > currentScroll + 200){
    lastClickedDiv.css({'height' : 0})
  }
})

所以我整理了一个可能对你有帮助的脚本。

我已经对它进行了一些基本的测试,但是如果您遇到任何问题,请发表评论。

// Generate offsets and return them as an object
function generateOffsets($element, tolerance)
{
  var offsets = $element.offset(),
      offsetTop = offsets.top;
  return {
    scrollPos: offsetTop,
    toleranceTop: offsetTop - tolerance,
    toleranceBottom: offsetTop + tolerance
  };
}
// Run a callback when the user leaves the scroll tolerance of a set of elements
function closeOnScroll($elements, tolerance, callback)
{
  $elements.each(function() {
    var $element = $(this),
        offsets = generateOffsets($element, tolerance),
        resizeEvent;
    // On resize, regenerate the offsets so they stay up to date
    $(window).on('resize', function(e) {
      resizeEvent = e;
      offsets = generateOffsets($element, tolerance);
    });
    // On scroll check if we've left the tolerance area, if so run the event and unbind
    $(window).on('scroll', function(e) {
      var windowPos = $(this).scrollTop();
      if (windowPos < offsets.toleranceTop || windowPos > offsets.toleranceBottom) {
        callback($element);
        $(this).unbind(e);
        $(this).unbind(resizeEvent);
      }
    }); 
  });
}
// Example: Apply the event to a set of elements
$('.btn').click(function() {
  closeOnScroll($('div .module-cta'), 200, function($element) {
    $element.removeClass('module-cta--active');
  });
});

使用脚本要记住的是,每次用户单击您的按钮时都需要应用它。你可能会说,你为什么要这样做 - 但它实际上有一些严重的性能影响。

事件依赖于滚动和调整大小,这两者都非常慢,尤其是在没有像此脚本中那样去抖动的情况下。但是,我在脚本中所做的是在事件发生后取消绑定事件。否则,调整大小和滚动将针对每个按钮不断发生,直到时间结束。通过"取消绑定"事件,可以确保页面长时间运行的性能。

我们不想毁了那些漂亮的动画吧?