如何使用 Javascript 自动打印一系列 HTTP 搜索查询的搜索结果?
How can I use Javascript to automatically print search results from a series of HTTP search queries?
我有一个 tampermonkey 脚本,我试图在其中获取一组名称,并对每个名称执行搜索并打印页面。它会在您加载页面时自动运行,这就是为什么需要 if
语句的原因。
$(document).ready(function(){
var searchBar = $('input[name="searchfield"]');
var submit = $('button[name="searchbyname"]');
if ( searchBar.val() < 1 ) {
var namesArray = prompt('enter names to search, separated by commas').split(', ');
$.each(namesArray, function(i, v) {
$(searchBar).val(v);
$(submit).trigger('click');
window.print();
});
}
})
我的问题是在最后一个循环中只有 运行 $(submit).trigger('click');
。因此,如果我的数组是 'one, two, three',它将在搜索栏中输入 'one',将其替换为 'two,',然后是 'three,',然后才会真正触发搜索按钮。
是否通过 AJAX 处理提交?
- 是的,它是一个AJAX形式:您需要等待服务器响应和DOM更新后才能截图。
- 不,这是一个正常的 POST 形式: 当文档被下一个 HTTP 请求替换时,您的 Javascript 运行时将消失。
- 不,这是 DOM 中的内联 javascript 搜索: 仍然是使用承诺或其他延迟策略以确保在您打印之前,一切都已更新。
无论哪种方式,我都建议在按钮上使用 onclick
处理程序来帮助您进一步调试。我敢打赌它会被解雇,但您是在继续操作,而不是推迟到响应加载完毕。
每个新请求都会破坏最后一个,因此即使所有请求都触发,您也只能看到最后一个生效。
(这个答案是为了回应我认为真正的需要,"How can I use Javascript to automatically print search results from a series of HTTP search queries?",发帖者会相应地调整问题。)
您实际上是在尝试使用 Javascript 从不同的页面打印搜索结果。您的方法不适用于此目的(因此 $.each
循环的原始问题无效);每次提交搜索时,您的 Javascript 运行时和用户脚本都会被破坏。
要实现最终目标,您需要将查询循环与提交 HTTP 请求的 window 分开。诀窍:创建一个包含此网站的 iframe,然后从 top
window.
控制该 iframe
这是可以直接复制到开发者控制台的代码。我只用控制台测试过它,但它应该适用于像 Tampermonkey 这样的脚本注入器。
(function(){
// Define the bits that work with this particular website.
var fieldname = 'searchfield';
var formname = 'ECPCIS_list';
// Figure out which names need to be searched.
var query_iter = 0
, queries = prompt('What names do you want to search for?').split(',').filter(function (val) {
return val.trim();
});
if (!queries.length) { return; }
// Store the current URL.
var url = window.location.href;
// Reopen the current document (in the context of the current domain security), and replace the
// document contents with a single iframe. The iframe source is equal to the original URL.
document.open();
document.close();
var iframe = document.createElement('IFRAME');
// Make sure that the styles are set up in such a way that the iframe gets full height.
// We'll add a listener that resizes the `top` window (our script) whenever the iframe loads.
document.body.setAttribute('style', "width:100%;height:100%;margin:0;");
iframe.setAttribute('style', "width:100%;height:100%;");
iframe.setAttribute('scrolling', 'no');
// Create a method to handle the query/repeat lifecycle.
var runQuery = function() {
document.body.style.height = iframe.contentWindow.getComputedStyle(iframe.contentDocument.body).getPropertyValue('height');
// Find the search box. If it doesn't exist yet, continue to wait.
var fields = iframe.contentDocument.getElementsByName(fieldname);
if (fields.length == 0) {
setTimeout(100, runQuery);
return;
}
// If this isn't the first iteration, we need to wait to print the screen.
if (query_iter > 0) {
window.print();
if (query_iter >= queries.length) { return; }
}
// Set the query in the search box.
fields[0].value = queries[query_iter];
// Increment the query iteration.
query_iter += 1;
// Submit the form. This will refresh the iframe.
// When it is done loading, runQuery will be executed again.
iframe.contentDocument.getElementsByName(formname)[0].submit();
}
iframe.addEventListener('load', runQuery);
// Stick the iframe into the DOM and load the original page.
// Now it looks like we're in the same page we were just on; the fact that there are two layers
// is visually hidden. IOW, the "window.print" method will capture the right output.
document.body.appendChild(iframe);
iframe.src = url;
})()
请注意,专为您的用例设计的部分是顶部的 fieldname
和 formname
。其余部分是完全通用的;您可以使用任何在 input
和 form
元素上具有适当 name
属性的网站。
我有一个 tampermonkey 脚本,我试图在其中获取一组名称,并对每个名称执行搜索并打印页面。它会在您加载页面时自动运行,这就是为什么需要 if
语句的原因。
$(document).ready(function(){
var searchBar = $('input[name="searchfield"]');
var submit = $('button[name="searchbyname"]');
if ( searchBar.val() < 1 ) {
var namesArray = prompt('enter names to search, separated by commas').split(', ');
$.each(namesArray, function(i, v) {
$(searchBar).val(v);
$(submit).trigger('click');
window.print();
});
}
})
我的问题是在最后一个循环中只有 运行 $(submit).trigger('click');
。因此,如果我的数组是 'one, two, three',它将在搜索栏中输入 'one',将其替换为 'two,',然后是 'three,',然后才会真正触发搜索按钮。
是否通过 AJAX 处理提交?
- 是的,它是一个AJAX形式:您需要等待服务器响应和DOM更新后才能截图。
- 不,这是一个正常的 POST 形式: 当文档被下一个 HTTP 请求替换时,您的 Javascript 运行时将消失。
- 不,这是 DOM 中的内联 javascript 搜索: 仍然是使用承诺或其他延迟策略以确保在您打印之前,一切都已更新。
无论哪种方式,我都建议在按钮上使用 onclick
处理程序来帮助您进一步调试。我敢打赌它会被解雇,但您是在继续操作,而不是推迟到响应加载完毕。
每个新请求都会破坏最后一个,因此即使所有请求都触发,您也只能看到最后一个生效。
(这个答案是为了回应我认为真正的需要,"How can I use Javascript to automatically print search results from a series of HTTP search queries?",发帖者会相应地调整问题。)
您实际上是在尝试使用 Javascript 从不同的页面打印搜索结果。您的方法不适用于此目的(因此 $.each
循环的原始问题无效);每次提交搜索时,您的 Javascript 运行时和用户脚本都会被破坏。
要实现最终目标,您需要将查询循环与提交 HTTP 请求的 window 分开。诀窍:创建一个包含此网站的 iframe,然后从 top
window.
这是可以直接复制到开发者控制台的代码。我只用控制台测试过它,但它应该适用于像 Tampermonkey 这样的脚本注入器。
(function(){
// Define the bits that work with this particular website.
var fieldname = 'searchfield';
var formname = 'ECPCIS_list';
// Figure out which names need to be searched.
var query_iter = 0
, queries = prompt('What names do you want to search for?').split(',').filter(function (val) {
return val.trim();
});
if (!queries.length) { return; }
// Store the current URL.
var url = window.location.href;
// Reopen the current document (in the context of the current domain security), and replace the
// document contents with a single iframe. The iframe source is equal to the original URL.
document.open();
document.close();
var iframe = document.createElement('IFRAME');
// Make sure that the styles are set up in such a way that the iframe gets full height.
// We'll add a listener that resizes the `top` window (our script) whenever the iframe loads.
document.body.setAttribute('style', "width:100%;height:100%;margin:0;");
iframe.setAttribute('style', "width:100%;height:100%;");
iframe.setAttribute('scrolling', 'no');
// Create a method to handle the query/repeat lifecycle.
var runQuery = function() {
document.body.style.height = iframe.contentWindow.getComputedStyle(iframe.contentDocument.body).getPropertyValue('height');
// Find the search box. If it doesn't exist yet, continue to wait.
var fields = iframe.contentDocument.getElementsByName(fieldname);
if (fields.length == 0) {
setTimeout(100, runQuery);
return;
}
// If this isn't the first iteration, we need to wait to print the screen.
if (query_iter > 0) {
window.print();
if (query_iter >= queries.length) { return; }
}
// Set the query in the search box.
fields[0].value = queries[query_iter];
// Increment the query iteration.
query_iter += 1;
// Submit the form. This will refresh the iframe.
// When it is done loading, runQuery will be executed again.
iframe.contentDocument.getElementsByName(formname)[0].submit();
}
iframe.addEventListener('load', runQuery);
// Stick the iframe into the DOM and load the original page.
// Now it looks like we're in the same page we were just on; the fact that there are two layers
// is visually hidden. IOW, the "window.print" method will capture the right output.
document.body.appendChild(iframe);
iframe.src = url;
})()
请注意,专为您的用例设计的部分是顶部的 fieldname
和 formname
。其余部分是完全通用的;您可以使用任何在 input
和 form
元素上具有适当 name
属性的网站。