向下滚动一个不断增长的页面到底部。

3

我有一个页面。当我手动滚动时,它会不断增长,然后我可以一遍又一遍地滚动直到滚动条到达底部(一个很好的例子是Facebook时间线页面)。

我尝试写:

static IWebDriver driver = new ChromeDriver(@"C:\selenium\net40");
IJavaScriptExecutor js = driver as IJavaScriptExecutor;

然后我进入了一个页面并执行了以下操作:
js.ExecuteScript("window.scroll(0, document.height)");

但是我可以滚动更多。

如果页面不断增长,如何使其滚动到底部?

任何帮助都将不胜感激!


根据您目前给出的答案,我认为我们可能需要一些澄清。您希望这个滚动条何时出现? - MaxPRafferty
4个回答

2

很遗憾,没有任何事件会在页面总高度发生变化时触发。因此有两种可能的解决方案:

您可以使用计时器定期“盲目”滚动到底部。

setInterval(function () { window.scroll(0, document.height); }, 100);

或者,您可以使用“DOMSubtreeModified”事件,在高度更改时每次滚动到底部。该事件在文档中任何内容更改时触发,因此如果您经常更改DOM,则可能会减慢浏览器速度。但是,这种解决方案将保证在页面增长时立即滚动到底部。

//scroll to bottom when anything changes in the dom tree.
var height = document.height;
document.addEventListener('DOMSubtreeModified', function () {
    if (document.height != height) {
        height = document.height;
        window.scroll(0, height);
    }
});

2

window.scroll(0, document.height)会滚动到已知的可滚动区域。问题是当你滚动到页面底部时,会下载更多数据。因此,可滚动区域会发生变化。您需要根据需要滚动多次。

例如,可以使用此脚本

var timeId = setInterval( function() {
    if(window.scrollY!==document.body.scrollHeight)
        window.scrollTo(0,document.body.scrollHeight);
    else
        clearInterval(timeId);
},500);

编辑:

在某些页面上,window.scrollY永远不会等于document.body.scrollHeight,因此setInterval将永远不会被清除:这将防止您返回顶部。

var timeId = setInterval( function() {
    if(window.scrollY<(document.body.scrollHeight-window.screen.availHeight))
        window.scrollTo(0,document.body.scrollHeight);
    else
    {
        clearInterval(timeId);
        window.scrollTo(0,0);
    }
},500);

@CybermaxsBetclic,谢谢!你离成功更近了...滚动条滚到底部后,我试图将其移回顶部:它到达了顶部,但然后继续向下移动:js.ExecuteScript("var timeId = setInterval( function() { if(window.scrollY!=document.body.scrollHeight) window.scrollTo(0,document.body.scrollHeight); else clearInterval(timeId); },500);"); js.ExecuteScript("window.scrollTo(0, 0);"); - Alon Shmiel

2

我同意目标,但从用户角度来看,不赞成建议的代码方法。如果我进入一个需要使用ajax(或任何其他方法)部分加载所有内容的设计需求页面上,我希望页面在不打扰我滚动的情况下默默地完成。因此,最好的方法是在后台依次调用多个请求,只要还有更多内容需要加载就继续。如果您同意这个解决方案,则通常需要一个函数来处理window.onload事件,发起第一个调用,处理响应并为获取更多内容而调用自身。


看起来是一个不错的方法,但我看到两个问题:你可能不知道如何调用更多的内容,这将需要在Selenium测试中放置特定于站点的js代码(不易维护)。在Selenium中,用户角度并不重要。 - Cybermaxs
网站特定代码?你的整个测试套件不是本来就是针对特定网站的吗?我敢打赌,当我用它来测试Facebook时,你为Google+编写的测试套件肯定会失败。 - Ardesco

1
以下两个函数将在新内容加载时强制页面滚动:
JS:
var attachScrollModified = function () {
    document.addEventListener('DOMSubtreeModified', function () {
        this.removeEventListener('DOMSubtreeModified', arguments.callee, false);
        window.scroll(0, getBottomElemPos());
        attachScrollModified();
    });
}

var getBottomElemPos = function () {
    var scrollElem = document.getElementById("scrollElem");
    if (scrollElem) {
        document.body.removeChild(scrollElem);
    }
    scrollElem = document.createElement("div");
    scrollElem.id = "scrollElem";
    document.body.appendChild(scrollElem);
    return scrollElem.offsetTop;
}

示例链接:http://jsfiddle.net/MaxPRafferty/aHGD6/

将它们放置在页面的<script>中,然后调用:

js.ExecuteScript("attachScrollModified();");

这可能会导致无限循环地不断使用ajax获取更多的内容。

非常感谢您的尝试,但我没有任何按钮,并且我不明白如何在您的代码中删除按钮的行... 非常感谢! - Alon Shmiel
1
@AlonShmiel 好的!修改了答案和 jsfiddle,使其可以在用户点击之外进行附加。 - MaxPRafferty

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