【问题标题】:Links scroll to top and do not follow target on mobile链接滚动到顶部并且不跟随移动设备上的目标
【发布时间】:2020-04-18 15:25:48
【问题描述】:

我正在尝试创建一个带有日历、按日期列出和按位置列出的活动页面。这通过使用由 JavaScript 控制的选项卡显示/隐藏视图来工作。我整理了一个CodePen demo here,但请记住,由于有一些 AJAX 请求,它缺少一些功能,并且我无法在此示例中重现该问题。但您至少可以查看代码并大致了解正在发生的事情。

问题出现在移动设备上(在 iOS 上测试)的两个列表视图中。当我点击一个链接时,页面会滚动到顶部,而不是跟随该链接。但是,如果页面已经滚动到顶部,我可以点击最顶部的链接。我不知道问题出在哪里,但我不会在我的 JavaScript 中的任何地方调用scrollTop() 或类似的东西。我确实更改了document.location.hash 的值,但仅在以#tabs > li 为目标时。

一如既往地感谢任何帮助。提前致谢。

编辑 1

应 Oded BD 的要求,我的 goToPage 函数,我将其命名为 tabsChildrenClick(第 29-38 行):

function tabsChildrenClick($tab) {
  $tabsChildren.each(function () {
    $($(this).data('href') + 'View').hide();
    $(this).removeClass('active')
  });

  let view = $tab.data('href');
  document.location.hash = view;
  $(view + 'View').show();
}

它采用触发更改的选项卡的 jQuery 对象,隐藏所有三个视图并使所有三个选项卡都处于非活动状态,从给定的 $tab 中获取 data-href(例如#calendar)的值和使用它来更新document.location.hash 并显示适当的视图。

请注意,我从原始演示中删除了第 30-33 行(在函数的开头),因为它们引用了不同项目中的变量和/或在此项目中不需要(复制/粘贴错误):

30 $activeTab.addClass('active');
31 galleryPage = archivePage = 1;
32 galleryEmpty = archiveEmpty = false;
33

编辑 2

我之前可能没有明确说明这一点,但我的问题在于单击列表项选项卡和锚标记。解决页面在 tab 点击时滚动到顶部的两个答案并没有解决它在 anchor 点击时滚动到顶部的问题。我希望这能提供一些澄清。

编辑 3

我想我知道问题出在哪里,以及为什么我无法在我的演示中重现它。我添加了一个隐藏在页面滚动上的页脚,所以如果$(window).scrollTop() == 0,页脚是可见的,否则如果$(window).scrollTop() > 0,页脚隐藏。这可能是我沮丧的原因。代码来了。

编辑 4

这是代码,但删除它并没有像我希望的那样解决问题:

// scrolling footer
const breakpointMd = 768;
let hidden = false;
function showHideFooter() {
  let $footer = $('#footer');
  let width = $(window).width();
  let position = $('#content').scrollTop();

  if (width < breakpointMd) {
    if (position === 0 && hidden) {
      // similar to $footer.show();
      $footer.animate({
        'bottom': '0px',
      }, 500);

      hidden = false;
    } else if (position !== 0 && !hidden) {
      // similar to $footer.hide();
      $footer.animate({
        'bottom': '-49px',
      }, 500);

      hidden = true;
    }
  } else {
    hidden = false;
    $footer.css('bottom', '0px');
    $footer.show();
  }
}

$(window).on('scroll resize orientationchange', showHideFooter);
$('#content').scroll(showHideFooter);

编辑 5

我已将滚动页脚添加到演示中,因为我仍然认为它会导致问题。我已经更新了CodePen demo 以包含页脚,现在问题已经重现。我还添加了一些 return false; 语句,但这并没有帮助。

另一个值得注意的变化是我用&lt;div id="grid"&gt; 标记为整个页面添加了一个包装器。这可能会影响滚动。

【问题讨论】:

  • 您是否在页面中使用锚标记?如果是这样,您可能需要使用 tabindex。这里有答案:stackoverflow.com/questions/5832436/…
  • 感谢您的建议,但这没有帮助。动态添加值很痛苦,但我认为允许用户通过链接进行标签是值得的。感谢您向我介绍此属性!
  • 在我看来,您在您的列表中使用href 标记只是作为数据属性进行导航,是这样吗?因此,您可以完全避免使用 href 标记,或者您需要在 all 您的点击/点击处理程序中返回 false。这里是关于帽子话题的讨论:Which “href” value should I use for JavaScript links, “#” or “javascript:void(0)”?
  • 你能展示你的goToPage函数吗?
  • 查看我的编辑。我相信您请求的功能就是我所说的tabsChildrenClick(),但如果这不是您的意思,请告诉我。

标签: javascript jquery html css


【解决方案1】:

修改 document.location.hash 将导致浏览器滚动到该元素。如果页面上没有具有该 ID 的元素,则会滚动到页面顶部。

为什么不使用

history.pushState({}, '', '#' + view);

或

history.replaceState({}, '', '#' + view);

改为?

 

在此处查看更多解决方案: Modifying location.hash without page scrolling

 

编辑:仔细查看您提供的代码笔,我发现您在两个地方有以下行。

document.location.href = '#' + context['day'];

用

替换它们
history.pushState({}, '', '#' + context['day']);

应该解决您链接的代码笔中的问题。

【讨论】:

【解决方案2】:

我想有两种方法可以做到这一点。

选项 1:event.preventDefault()

调用传递给处理程序的事件对象的.preventDefault() 方法。如果您使用 jQuery 绑定您的处理程序,则该事件将是 jQuery.Event 的一个实例,它将是 .preventDefault() 的 jQuery 版本。如果您使用addEventListener 绑定您的处理程序,它将是Event 和.preventDefault() 的原始DOM 版本。无论哪种方式都可以满足您的需求。

例子:

$('#ma_link').click(function($e) {
    $e.preventDefault();
    doSomething();
});

document.getElementById('#ma_link').addEventListener('click', function (e) {
    e.preventDefault();
    doSomething();
})

选项 2:return false;

In jQuery:

从事件处理程序返回 false 将自动调用 event.stopPropagation() 和 event.preventDefault()

因此,使用 jQuery,您也可以使用这种方法来防止默认链接行为:

$('#ma_link').click(function(e) {
     doSomething();
     return false;
});

如果您使用的是原始 DOM 事件,这也适用于现代浏览器,因为 HTML 5 规范规定了这种行为。但是,旧版本的规范没有,因此如果您需要与旧浏览器的最大兼容性,您应该明确调用.preventDefault()。有关规格详细信息,请参阅event.preventDefault() vs. return false (no jQuery)。

【讨论】:

  • 这些并不能解决问题。对于选项卡下方的锚标记,我没有单击事件处理程序,而且正如我所料,添加一个也无济于事。问题必须在我的代码中的其他地方。
猜你喜欢
  • 1970-01-01
  • 2014-06-20
  • 1970-01-01
  • 1970-01-01
  • 2020-02-26
  • 2019-08-22
  • 1970-01-01
  • 2016-05-06
  • 2018-01-07
相关资源
最近更新 更多