Javascript phantomjs-page.evaluate更新后未正确呈现页面;页面#内容显示正确
我已经跌跌撞撞地阅读了这段代码好几天了,在经历了许多挑战之后,我几乎得到了我想要的结果。该代码假设呈现一个类似速度表的仪表(见下文),默认值(速度表指针)为100。我试图使用Javascript(通过PhantomJS/automation)从DOM中删除HTML标记,并用更新的内容替换它内容相同,只是值需要从100改为其他值。 经过大量阅读(我的背景是Ruby),我已经成功地用我想要的HTML更新了DOM,但是用PhantomJS呈现更新后的DOM的图像只会得到部分完整的图像 我注意到有相当多的StackOverflow线程允许页面完全呈现(setTimeout),但是当我添加超时时(参见下面的代码),它被忽略,代码在不到一秒钟的时间内执行 有人可以帮助我以正确的方式实现此超时吗?我认为这就是问题所在,因为执行Javascript phantomjs-page.evaluate更新后未正确呈现页面;页面#内容显示正确,javascript,dom,phantomjs,Javascript,Dom,Phantomjs,我已经跌跌撞撞地阅读了这段代码好几天了,在经历了许多挑战之后,我几乎得到了我想要的结果。该代码假设呈现一个类似速度表的仪表(见下文),默认值(速度表指针)为100。我试图使用Javascript(通过PhantomJS/automation)从DOM中删除HTML标记,并用更新的内容替换它内容相同,只是值需要从100改为其他值。 经过大量阅读(我的背景是Ruby),我已经成功地用我想要的HTML更新了DOM,但是用PhantomJS呈现更新后的DOM的图像只会得到部分完整的图像 我注意到有相当多
Page#evaluate
后,Page#content
的结果是正确的,并且独立打开时,生成的HTML呈现得非常完美
代码:
// Open chart.html from the local filesystem
page.open('file:///c:/temp/chart.html', function(status) {
setTimeout(function() {
page.evaluate(function() {
// Remove the HTML script tag with an ID of 'removeMe' from the DOM
var elem = document.getElementById('removeMe');
document.getElementById('removeMe').parentNode.removeChild(elem);
// Create a new script tag and populate it with the appropriate content
var s = document.createElement('script');
s.type = 'text/javascript';
// Per user request, including the full scriptContent var (originally omitted for brevity)
var scriptContent = 'AmCharts.makeChart("chartdiv", { "type": "gauge", "marginBottom": 20, "marginTop": 40, "startDuration": 0, "fontSize": 13, "theme": "dark", "arrows": [ { "id": "GaugeArrow-1", "value": 30 } ], "axes": [ { "axisThickness": 1, "bottomText": "0 km/h", "bottomTextYOffset": -20, "endValue": 220, "id": "GaugeAxis-1", "valueInterval": 10, "bands": [ { "alpha": 0.7, "color": "#00CC00", "endValue": 90, "id": "GaugeBand-1", "startValue": 0 }, { "alpha": 0.7, "color": "#ffac29", "endValue": 130, "id": "GaugeBand-2", "startValue": 90 }, { "alpha": 0.7, "color": "#ea3838", "endValue": 220, "id": "GaugeBand-3", "innerRadius": "95%", "startValue": 130 } ] } ], "allLabels": [], "balloon": {}, "titles": [] } );';
// suggested elsewhere on SO; for all browser compatibility
try {
s.appendChild(document.createTextNode(scriptContent));
document.head.appendChild(s);
} catch (e) {
s.text = scriptContent;
document.head.appendChild(s);
}
});
}, 5000);
// RENDER THE NEW IMAGE; this is rendering the same image but needle is missing entirely
page.render('after_change.png');
phantom.exit();
});
期望的结果
上述scriptContent
变量包含脚本标记的更新内容;它会将指针值正确更新为75,但更改后。png
缺少指针。我需要指针显示在75
HTML
<script type="text/javascript" src="https://www.amcharts.com/lib/3/amcharts.js"></script>
<script type="text/javascript" src="https:http://cdn.amcharts.com/lib/3/gauge.js"></script>
<script type="text/javascript" src="https://www.amcharts.com/lib/3/themes/dark.js"></script>
<script type="text/javascript" id="removeMe">
...
// these contents should be completely replaced; no other relevant HTML
...
</script>
<body>
<div id="chartdiv" ></div>
</body>
...
//这些内容应该被完全替换;没有其他相关的HTML
...
参考资料
以下是我使用的精确仪表--amCharts仪表的100%默认设置:
让我们按照以下顺序思考此任务的后续操作:
// 1. Open the page
page.open('file:///c:/temp/chart.html', function(status) {
// 2. Make adjustments
page.evaluate(function() {
/// Do stuff
});
// 3. Make screenshot, but not before waiting 5 seconds
// for browser to catch up with step 2.
setTimeout(function(){
page.render('after_change.png');
phantom.exit();
}, 5000);
});
你能发布完整的脚本内容吗?当然,谢谢你的快速回复。暂时发布…你能展示一下你是如何尝试应用setTimeout的吗?当然@Vaviloff,更新以反映你的请求。谢谢另外,我在上面说过setTimeout似乎被忽略了,但我的意思是它正确地延迟了5秒,但结果是一样的——如果我打印输出,它似乎只是在一次爆炸中执行所有操作之前等待了5秒。它应该在
页面中运行。评估块,然后等待5秒钟,然后使用页面捕获屏幕截图。渲染,对吗?谢谢你的帮助!抱歉@Vaviloff,最后更新了一次,在5000毫秒等待后放置最终页面渲染;在这种安排下,根据我的原始问题帖子,setTimeout值被忽略。如果我稍微移动一下订单,它会等待5秒钟再执行任何操作,然后一起执行所有剩余的操作(因此问题仍然存在)。非常感谢您的帮助!:)非常感谢你!我是如此接近。我不能告诉你我在这上面玩了一段时间后有多高兴。非常感谢@Vaviloff!好奇的@Vaviloff,我在上面的代码中等待什么?我是JS新手,但我认为page.open正在执行,然后等待5秒,然后拉屏幕截图——我是否在等待5秒,等待所有执行开始?谢谢,@KurtW,很高兴我能提供帮助。你自己做得很好-问题提得很好。你的代码是这样做的:打开页面,然后做一个屏幕截图,5秒钟后,调整页面内容。很有趣。。。我得回去重读一遍。再次感谢你!