【问题标题】:Maintain scroll position with jQuery Mobile slide transition使用 jQuery Mobile 幻灯片转换保持滚动位置
【发布时间】:2012-09-25 17:27:33
【问题描述】:

我目前正在开发一个使用 jQuery Mobile 的移动网站。切换页面时,我使用幻灯片过渡。因为这些页面相当长,所以需要滚动。

当向下滚动并单击链接时,当页面在滑入新页面之前滚动到顶部时,会出现可见的跳转。由于在某些时候需要滚动到顶部时,两个页面并排放置。

我尝试过的一件事是: 我可以从顶部偏移新页面,使其从页面滚动到的级别开始,并在动画完成时将偏移重置回 0,但页面将保持向下滚动。如果我使用 window.scrollTo 或 jQuery 的 scrollTop() 会出现明显的闪烁,其中固定标题最为明显。

我还能做些什么来保持旧页面滚动但新页面不滚动?

我已经在第三代 iPod touch、iPhone 4 和 iPhone 4s 上对此进行了测试,令人惊讶的是,到目前为止,闪烁最少的设备是 iPod touch。

【问题讨论】:

    标签: jquery css jquery-mobile


    【解决方案1】:

    只需添加此 CSS

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

    (来自here

    【讨论】:

      【解决方案2】:

      我正在回答这个问题,因为它是关于这个主题的原始问题,并清楚地表明这里的问题是一个明显的闪烁,使用来自 JQM 库的window.scrollTo()jQuery's scrollTop() 或有争议的$.mobile.silentScroll() (超时+滚动)。

      我最近不得不解决完全相同的问题,这就是我想出的: 伟大的 JQM 团队过去在优化和加速低端移动设备的转换方面做得很好。

      简而言之,JQM 通过尝试将pages§.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);
        }
      };
      

      这里使用的JQMpageevents如下:

      $(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-cached 的页面,需要自定义页面历史记录,因为:

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

      这是一个例子:

      slide 转换被故意放慢以检查结果:

      【讨论】:

        【解决方案3】:

        只要把 return false; 在被调用的 javascript 函数的末尾。

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

        你也可以使用 preventDefault();或 event.stopPropagation();功能

        推荐人: event.preventDefault() vs. return false

        希望对您有所帮助。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-04-21
          • 1970-01-01
          • 2013-01-23
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多