Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/424.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何同步注入脚本?_Javascript_Selenium Webdriver - Fatal编程技术网

Javascript 如何同步注入脚本?

Javascript 如何同步注入脚本?,javascript,selenium-webdriver,Javascript,Selenium Webdriver,许多人建议我只使用.onload并在脚本准备好后启动回调。那对我不起作用。我正在编写一个函数,它希望立即生成一个元素,而不是稍后。以下是我得到的: webdriver.By.sizzle = function(selector) { driver.executeScript("if(typeof Sizzle==='undefined'){var s=document.createElement('script');s.type='text/javascript';s.src='http

许多人建议我只使用
.onload
并在脚本准备好后启动回调。那对我不起作用。我正在编写一个函数,它希望立即生成一个元素,而不是稍后。以下是我得到的:

webdriver.By.sizzle = function(selector) {
    driver.executeScript("if(typeof Sizzle==='undefined'){var s=document.createElement('script');s.type='text/javascript';s.src='https://raw.github.com/jquery/sizzle/master/src/sizzle.js';document.head.appendChild(s);}");
    return new webdriver.By.js("return Sizzle('"+selector.replace(/"/g,'\\"')+"')[0]");
};
我想注入(如果它还没有包括在内),然后返回一个
HtmlElement
。如果需要,它可以等待,但必须返回HtmleElement

所有这些基本上只是说“不要这样做”,但我想不出其他办法

这是用于JavaScript的selenium web驱动程序的选择器



driver.executeScript
将接受参数。我想知道是否可以传入一个
webdriver.promise
并在加载脚本时调用它。。。?我不知道如何“兑现”承诺。

为什么不将sizzle作为页面脚本要求。坚持

<script src="sizzle.js"></script>


在头部的某个地方,它将在其他脚本运行之前加载。要动态执行此操作,只需将脚本附加到头部。有一个演示程序,显示在分析和评估注入时脚本执行暂停。

这里的最佳选择是重新设计/重组代码,以处理Sizzle的异步加载,并通过回调函数返回结果。这就是javascript的设计方式。它没有同步加载远程资源的“好”方法

据我所知,同步加载远程资源(如JS文件)的唯一方法是使用阻塞AJAX调用加载资源(将受到相同来源的限制,因此您必须将其托管在服务器上),然后将资源加载到内存中后,您可以执行它(使其加载)。然后,您可以调用其中定义的函数并返回它们的结果


这种情况不好的原因是,阻塞ajax调用将在加载远程资源时锁定浏览器一段不确定的时间。那种类型的设计不利于用户体验



我唯一能想到的另一个选择是,在页面加载期间,确保已经指定了所有必需的资源,以便在脚本需要它们时已经预加载它们。按需加载远程资源是导致异步问题的原因。

速度有点慢,但我想我找到了解决方案:

webdriver.By.sizzle = function(selector) {
    driver.executeScript("return typeof Sizzle==='undefined'").then(function(noSizzle) {
        if(noSizzle) driver.executeScript(fs.readFileSync('sizzle.min.js', {encoding: 'utf8'}));
    });
    return new webdriver.By.js("return Sizzle('"+selector.replace(/"/g,'\\"')+"')[0]");
};

我刚刚下载了脚本,我正在将整个过程注入内联。这样我就不需要等待任何东西。

传递回调/返回承诺。一个简单的示例展示了如何动态加载脚本:。不清楚“返回HTML元素”是什么意思。@jfriend00动态生成的脚本是异步加载的,OP希望同步加载,这样他可以在插入脚本后从函数返回。@Fabriciomatté-没有“好”的方法动态同步加载外部脚本。在页面加载过程中,可以使用
document.write()
完成,也可以使用阻止AJAX调用(hack、cough、cough)完成,但这两种方法通常都不是很好的开发方法。应该修改代码,以处理使用回调或promies或类似性质的东西加载远程资源的异步性质。这就是好的javascript设计的工作原理。@jfriend00:不知道你读过我写的任何东西。。。我发布的示例代码正是这样做的。问题是我在两种不同的环境下工作;我可以在客户端执行代码,但它必须返回某些内容,否则我无法对其执行任何操作。我没有访问权限,因为我正在通过Selenium加载网页,然后注入我自己的代码。请阅读我发布的代码。。。我是。没有任何帮助。在这一点上,值得考虑的是,如果您需要加载立即返回某些内容的代码,那么selenium可能不是合适的工具,但是这种方法不起作用。如果您不能让代码等待,那么您试图解决的问题可能不是您实际需要解决的问题。“这不好的原因是,阻塞ajax调用将在加载远程资源时锁定浏览器一段不确定的时间。这种类型的设计不利于用户体验。”--没有用户。这是一个自动测试。它可以根据需要等待多久。无法提前指定资源;我正在将它注入一个使用selenium加载的页面。@Mark,然后可以使用同步ajax锁定浏览器。我给了你一条追求的道路。下面是一个类似的问题/答案: