等到下拉列表元素在CasperJS中可见

时间:2015-09-15 08:10:09

标签: javascript html-select casperjs

我有这个下拉列表:

<select name="date" class="form-control" on-change:Calendar.submitFilterForm();">
    <option value="2015-09-15">Tue 2015-09-15</option>
    <option value="2015-09-16">Wed 2015-09-16</option>
    <option value="2015-09-17">Thu 2015-09-17</option> 
    <option value="2015-09-18">Fri 2015-09-18</option>
    <option value="2015-09-19">Sat 2015-09-19</option>
    <option value="2015-09-20">Sun 2015-09-20</option>
    <option value="2015-09-21">Mon 2015-09-21</option>
    <option value="2015-09-22">Tue 2015-09-22</option>
</select>

每天晚上00:00(或几秒钟后),上面的下拉列表会更新一个新的(下一个)日,例如<option value="2015-09-23">Wed 2015-09-23</option>会被添加,<option value="2015-09-15">Tue 2015-09-15</option>会消失。

然后我想点击一下可见时添加的下拉列表选项。有可能吗?

现在我用:

casper.thenEvaluate(function(){
    var form = document.querySelector('.form-control');
    form.selectedIndex = 7; //7 equals the last value currently visible.
    $(form).change();
});

它有效,但我应该怎样做make casperjs wait until the options is visible and then directly click on it? 也许我可以制作一个变量var ClickValue = "2015-09-23"或类似的东西?

1 个答案:

答案 0 :(得分:2)

CasperJS不是安排长时间运行任务的正确位置,因为底层浏览器(PhantomJS或Slimer.js)可能会遇到内存问题或以其他方式失败。所以你应该编写一个简短的运行脚本,它只会等待很短的时间,直到元素出现。您可以在午夜之前通过操作系统(Linux上的cron或Windows上的cron)安排执行此脚本。

元素通过JavaScript

出现

如果选择字段由JavaScript更新,那么您只需使用“长” - 运行waitFor()

casper.then(function(){
    var lastDate = this.getElementAttribute(".form-control :last-child", "value");
    this.waitFor(function(){
        return this.getElementAttribute(".form-control :last-child", "value") !== lastDate;
    }, null, null, 600000); // 10 minutes
}).thenEvaluate(function(){
    var form = document.querySelector('.form-control');
    form.selectedIndex = 7; //7 equals the last value currently visible.
    $(form).change();
});

页面重新加载是必要的

如果您只在重新加载页面时才会看到添加的选项,那么每次检查都需要casper.reload()页面。

casper.then(function(){
    var lastDate = this.getElementAttribute(".form-control :last-child", "value");

    function checkReload(){
        var curDate = this.getElementAttribute(".form-control :last-child", "value");
        if (lastDate !== curDate) { // TODO: add timeout handling here
            return; // finished
        }

        this.reload();
        this.wait(1000, checkReload); // check again in a second
    }
    this.then(checkReload);
}).thenEvaluate(function(){
    var form = document.querySelector('.form-control');
    form.selectedIndex = 7; //7 equals the last value currently visible.
    $(form).change();
});

这无限期运行,因此您应该添加超时处理。

无需与预先计算的日期进行比较

上述解决方案的工作原理是将之前的选项值与当前选项值进行比较。这并不完全可靠,因为如果出现错误并且脚本在新选项出现时启动,则脚本将再运行24小时。您也可以通过创建预期的

来更改它以直接计算预期的期权值
var d = new Date(Date.now()+(1000 * 60 * 60 * 24 * 7)); // seven days later
var expectedValue = ""+d.getFullYear()
        +"-"+zeroFill(d.getMonth()+1, 2)
        +"-"+zeroFill(d.getDate(), 2);

expectedValue将取代之前代码段中的lastDate,并且不要忘记将比较从!==翻转到===
zeroFill()取自here