简体   繁体   English

如何使用 Javascript 从一系列 HTTP 搜索查询中自动打印搜索结果?

[英]How can I use Javascript to automatically print search results from a series of HTTP search queries?

I have a tampermonkey script where I'm trying to take an array of names, and for each one perform a search and print the page.我有一个 tampermonkey 脚本,我试图在其中获取一组名称,并为每个名称执行搜索并打印页面。 It runs automatically when you load the page, which is why the if statement is necessary.它会在您加载页面时自动运行,这就是为什么需要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();
        });

    } 
})

My problem is that it is only running the $(submit).trigger('click');我的问题是它只运行$(submit).trigger('click'); on the last loop through.在最后一个循环中。 So if my array is 'one, two, three' it will enter 'one' into the search bar, replace it with 'two,' then 'three,' and only then will it actually trigger the search button.因此,如果我的数组是“一、二、三”,它将在搜索栏中输入“一”,将其替换为“二”,然后是“三”,然后它才会真正触发搜索按钮。

Is the submit handled via AJAX?提交是否通过 AJAX 处理?

  • Yes, it's an AJAX form: you need to wait for the server to respond and the DOM to update before you take a screenshot.是的,它是一个 AJAX 表单:您需要等待服务器响应和 DOM 更新,然后才能截取屏幕截图。
  • No, it's a normal POST form: your Javascript runtime will disappear when the document is replaced with the next HTTP request.不,这是一个普通的 POST 表单:当文档被下一个 HTTP 请求替换时,您的 Javascript 运行时将消失。
  • No, it's an inline javascript search within the DOM: still a good idea to use a promise or other deferral strategy to be sure that everything has updated before you print.不,它是 DOM 内的内联 javascript 搜索:仍然是使用承诺或其他延迟策略以确保在打印之前所有内容都已更新的好主意。

Either way, I'd suggest an onclick handler on the button to help you debug further.无论哪种方式,我都建议在按钮上使用onclick处理程序来帮助您进一步调试。 I bet it is being fired, but you're continuing with operations rather than deferring until the response has loaded.我敢打赌它正在被解雇,但您正在继续操作而不是推迟到响应加载。

Each new request clobbers the last, so even though all of them trigger, you only see the last one take effect.每个新请求都会破坏最后一个,因此即使它们都触发了,您也只会看到最后一个生效。

( This answer is in response to what I perceive as the real need, "How can I use Javascript to automatically print search results from a series of HTTP search queries?", in good faith that the poster will tweak the question accordingly. ) 这个答案是对我认为的真正需求的回应,“我如何使用 Javascript 自动打印来自一系列 HTTP 搜索查询的搜索结果?”,真诚地希望发布者会相应地调整问题。

You are actually trying to use Javascript to print search results from different pages.您实际上是在尝试使用 Javascript 来打印来自不同页面的搜索结果。 Your approach will not work for this purpose ( and therefore the original question of $.each looping is invalid );您的方法不适用于此目的(因此$.each循环的原始问题无效); every time the search is submitted, your Javascript runtime and userscripts are nuked.每次提交搜索时,您的 Javascript 运行时和用户脚本都会被破坏。

To accomplish the end goal, you need to separate the query loop from the window that submits the HTTP request.为了实现最终目标,您需要将查询循环与提交 HTTP 请求的窗口分开。 The trick: create an iframe containing this website, then control that iframe from the top window.诀窍:创建一个包含该网站的 iframe,然后从top窗口控制该 iframe。

Here's code that could be copied into the developer console directly.这是可以直接复制到开发人员控制台的代码。 I've only tested it with the console, but it should be adaptable for script injectors like Tampermonkey.我只用控制台测试过它,但它应该适用于像 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;
})()

Note that the parts designed specifically for your use case are fieldname and formname at the top.请注意,专门为您的用例设计的部分是顶部的fieldnameformname The rest of this is completely generic;其余部分是完全通用的; you could use with any website that has appropriate name attributes on the input and form elements.您可以与任何在inputform元素上具有适当name属性的网站一起使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM