【问题标题】:Keep a particular element in view, even when its previous siblings are growing?保持一个特定元素的视野,即使它之前的兄弟姐妹正在增长?
【发布时间】:2013-08-06 16:44:53
【问题描述】:

我有一个页面,其中各种元素的内容被 AJAX 化到一个核心结构中。结构本身非常简单,元素没有任何特殊的定位:

<body>
    <article id="one"></article>
    <article id="two"></article>
    <article id="three"></article>
</body>

每篇文章的内容是通过 AJAX 调用加载的,并且每篇文章的内容长度无法提前知道。此外,可以使用 URL 导航到每个部分(因此我可以使用 mysite.com/two 访问 #two;它会加载页面并向下滚动到请求的文章)。

这很好用,当然,在加载完所有内容之后,但我的问题是目标元素之前的内容还没有加载。因为元素必须扩展以适应内容,它会下推目标元素,所以不是得到这个:

____________________
| Target Element   |
|                  |
|__________________|
| Next Element     |
|__________________|

你明白了:

_____________________
| Previous Element  |
|                   |
|                   |
|___________________|
| Target Element    |
|___________________|

我尝试为内容块设置最小高度,但这仅在部分时间有效,并且只有在最终高度接近原始高度时才真正有效。

理想情况下,我希望视口相对于内容保持在相同的位置,即使用户在所有内容加载之前已经滚动,但我会在用户尝试之前保持该位置滚动。

有什么办法可以做到这两点吗?

【问题讨论】:

  • 如何将 URL 参数转换为哈希?能不能延迟一点?
  • @isherwood - 这是一个快速的字符串替换,但不,我不能拖延。一半是在给定部分加载,就好像它是它自己的页面一样。
  • 好的。回到哈希的 ajax 回调呢?
  • @isherwood - 如果偶尔闪烁,但这似乎有效。添加您的评论作为答案,如果它经得起一些进一步的测试,我一定会标记它。 :)

标签: javascript jquery css


【解决方案1】:

这个呢:

  1. 获取加载 ajax 调用之前任何先前元素的高度。保存它。
  2. 如果加载完成后,在成功完成 ajax 调用时,获取新高度。
  3. 使用差值计算它的大小。
  4. 向上滚动页面。

如果元素在当前元素之后,则不要滚动。

一边

这是我对某些网页的不满之一。他们加载,你开始阅读。然后一个 2 英寸高的添加幻灯片将您正在阅读的内容移出页面。或者更糟糕的是,您向下滚动并开始阅读,并且没有明显的原因,文本只是从页面底部滑出,因为一个看不见的添加刚刚加载到上面。

【讨论】:

  • 抛开 - 是的,我很同情。不过,这不是我的设计,我无法对这个项目做出这样的决定。 =/
【解决方案2】:

在这里创建了一个小演示:http://jsfiddle.net/dS5tq/

看看这个。

页面加载后尝试向下滚动到第二个 div。

我使用setTimeout 添加更多文本并为文本克隆现有段落。

HTML 代码

<div>
    <div id='one' class='box'>
        <p>um vulputate pretium id nec lorem. Cras ut pharetra massa. Aliquam venenatis ipsum pellentesque lorem viverra eleifend. Pellentesque in<p>
    </div>
    <div id='two' class='box'>
        <p>ger elementum, orci eu tincidunt vehicula, nisl felis semper odio, lacinia elementum risus leo vitae dui. Fusce dictum, justo a consequat ullamcorp<p>
    </div>
    <div id='three' class='box'>
        <p>ce in cursus leo. Integer lorem urna, lacinia mollis libero aliquam, consequat luctus lacus. Mauris pulvinar consequat justo, sed mattis sapien<p>
    </div>
</div>

CSS 代码

* { padding : 0; 
    margin : 0; 
}
.box {
    font-family : Arial;
    border : 1px solid #ccc;
    background-color : #eee;
    padding : 10px 10px 0 10px;
    line-height : 24px;
    margin : 10px;
}
p {
    margin-bottom : 10px;
}
#two {
    background-color : #ece;
}
#three {
    background-color : #eec;
}

JavaScript 代码

$(function() {
    setTimeout(function() {
        addContent($('#one p:last').clone(), $('#one'));
    }, 3000);

    setTimeout(function() {
        addContent($('#one p:last').clone(), $('#three'));
    }, 5000);
});

function addContent(data, tgt) {
    var current_pos = $(window).scrollTop();
    var tgt_pos = $(tgt).offset().top;

    if(tgt_pos < current_pos) {
        var currentHeight = $(tgt).height();
        $(tgt).append(data);
        var newHeight = $(tgt).height();
        $(window).scrollTop(current_pos + newHeight - currentHeight);
    } else {
        $(tgt).append(data);
    }
}

如果这有帮助,请告诉我。

【讨论】:

    【解决方案3】:

    将目标设置为绝对定位并将其放在屏幕顶部滚动到它,这实际上是滚动到顶部,然后在重置目标元素的窗口对象上放置一个 on-first-scroll 事件。 http://jsfiddle.net/DjBHX/

    // get the target element
    var target = $("#two");
    // set it to absolute position
    // now its at the top no matter what
    target.css("position", "absolute");
    target.css("top", 0);
    // scroll to the top of the page / target
    window.scrollTo(0, 0);
    // fake loading
    $("article").each(function() {
        // load $(this).load(blah);
        var elm = $(this)
        var spam = this.id; 
        for(var i=0; i<4; i++)
            spam += spam + "<br>";
        elm.html(spam);
    });
    // first scroll set target back to static positioning
    (function() {
        var fnFirstScroll = function () {
            // remove the event
            $(window).off("scroll", fnFirstScroll);
            // reset the target article
            target.css("position", "static");
            target.css("top", "auto");
            window.setTimeout(function() {
                window.scrollTo(0, target.offset().top);
            }, 10);
        }
        $(window).on("scroll", fnFirstScroll);
    })();
    

    【讨论】:

      【解决方案4】:

      也许看看做一个ajax成功功能:

      $.ajax({
        ...
        success: function() {
          // simulate link click or somesuch
        }
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-22
        • 1970-01-01
        • 2013-12-13
        • 1970-01-01
        相关资源
        最近更新 更多