使用jQuery Mobile幻灯片转换保持滚动位置

5
我目前在开发一个移动网站,使用了jQuery Mobile。在切换页面时,我使用了滑动过渡效果。由于这些页面相当长,需要滚动才能看到全部内容。
当向下滚动并单击链接时,在新页面滑入之前,页面会从顶部滚动到底部,导致可见的跳跃。由于这两个页面并排而坐,过渡效果需要将页面滚动到顶部。
有一件事我试过了: 我可以以页面滚动的级别来偏移新页面,当动画完成时将偏移量重置为0,但那样的话页面将保持滚动状态。如果我使用window.scrollTo或jQuery的scrollTop(),固定页眉会出现明显的闪烁。
是否还有其他方法,可以使旧页面保持滚动状态,而新页面不滚动?
我已在iPod touch第三代、iPhone 4和iPhone 4s上进行了测试,令人惊讶的是,迄今为止给我带来最少闪烁问题的设备竟然是iPod touch。
3个回答

0

只需添加此CSS

div[data-role='page'] { bottom: 0; -webkit-overflow-scrolling: touch; }

(从这里


0
我回答这个问题是因为它是关于这个主题最初发布的问题,并清楚地说明了使用window.scrollTo()jQuery的scrollTop()或有争议的$.mobile.silentScroll()(超时+滚动)从JQM库中会出现明显的闪烁问题。
我最近不得不解决完全相同的问题,这就是我想到的: 伟大的JQM团队过去在优化和加速转换方面为低端移动设备做出了巨大的贡献。
简而言之,JQM已经通过尝试将页面§.mobile.silentScroll()函数内的某个值配对来解决了这个关键点。我不得不删除此功能以构建自己的功能。
$(document).on("mobileinit", function () {
  // other settings...
  $.mobile.SerialTransition.prototype.scrollPage = $.noop;
  $.mobile.ConcurrentTransition.prototype.scrollPage = $.noop;
});

由于我有两种页面,第一种需要记住滚动位置(列表页),第二种(卡片页)需要始终从顶部开始,因此我将在自定义的data-attribute中存储此信息。

以下是我示例中三个页面的设置:

<div id="page-one" data-role="page" data-transition-scroll="keep-position">
<div id="page-two" data-role="page" data-transition-scroll="top-position">
<div id="page-three" data-role="page" data-transition-scroll="keep-position">

正如问题中所指出的那样,我还必须将page从顶部偏移,以下是整个代码:

var scrollHandler = {
  setScrollData: function (prevPage, toPage) { 
    if(typeof toPage == "object" && typeof prevPage == "object") {
      $(prevPage).data("scroll-top", $(window).scrollTop());
    }
  },
  resetContent: function (toPage) {
    var scrollMode = $(toPage).data("transition-scroll");
    if(scrollMode === "top-position") {
      var content = $(toPage).find(".ui-content")[0];
      var contentStyle = $(content).attr("style"); /* Force reflow */
        $(content).css({"top": "0px"});
    }
  },
  freezeContent: function (prevPage) {
    var scrollTop = $(prevPage).data("scroll-top"),
        content = $(prevPage).find(".ui-content")[0],
        fixedHeader = $(prevPage).find(".ui-header-fixed")[0],
        headerBottom = $(fixedHeader).outerHeight() - fixedHeader.offsetTop;
    $(content).css({"top": -scrollTop + "px"});
    window.scrollTo(0,0);
  },
  unFreezeContent: function (toPage) {
    var scrollTop = $(toPage).data("scroll-top"),
        scrollMode = $(toPage).data("transition-scroll"),
        content = $(toPage).find(".ui-content")[0],
        contentStyle = $(content).attr("style"); /* Force reflow */
    $(content).removeAttr("style");
    window.scrollTo(0, scrollMode ==="top-position" ? 0 : scrollTop);
  }
};

这里使用的JQM 页面事件 如下:
$(document).on("pagecontainerbeforehide", function(e, ui) { 
  scrollHandler.freezeContent(ui.prevPage);
});

$(document).on("pagecontainerbeforechange", function(e, ui) { 
  scrollHandler.setScrollData(ui.prevPage, ui.toPage);
});

$(document).on("pagecontainerbeforeshow", function(e, ui) { 
  scrollHandler.resetContent(ui.toPage);
});

$(document).on("pagecontainershow", function(e, ui) { 
  scrollHandler.unFreezeContent(ui.toPage);
});

最后,还有一点CSS:
/* large desktop screen */
.ui-header,
.ui-content,
.ui-footer {
  max-width: 870px;
  margin: auto;
}
/* needed for the scrollhandler */
.ui-content {
  position: relative; 
  width: 100%;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

附加说明

对于外部页面和未被DOM缓存的页面,需要自定义页面历史记录,因为:

  1. 在我的示例中,滚动值存储在页面本身中,并且
  2. 当前标准的JQM页面历史记录实现不足以满足此目的。

这里是一个例子:

slide 过渡效果被故意放慢以便检查结果:

transition animation


-1

只需在调用的 JavaScript 函数末尾放置 return false;

     function yourFunctionBeingCalled(){
       /*your code*/
       return false;
     }

你也可以使用 preventDefault(); 或 event.stopPropagation(); 函数。

参考: event.preventDefault() vs. return false

希望有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接