代码之家  ›  专栏  ›  技术社区  ›  Leo Odishvili

使用window.print()时丢失焦点

  •  1
  • Leo Odishvili  · 技术社区  · 6 年前

    当我尝试新事物,这可以使你的生活更容易时,我看到了一些吸引我眼球的东西。当您选择页面的某个部分,然后右键单击它时,您可以打印此特定部分。所以…我的猜测是“使用选择API然后打印它!”但是进展不太顺利。我不知道原因和时间,但在尝试使用window.print()时,我失去了注意力。 < BR> 这是我在StackOverflow控制台中尝试的示例代码。你知道怎么做吗?也许 window.print() is wrong method to use here?

    settimeout(函数()。{
    var el=document.getElementsByClassName('default prettyprint prettypted')[0];
    window.getselection().selectAllChildren(el);
    窗口(打印)();
    },3000);
    < /代码> 
    
    

    我选择的内容,然后单击“打印” 我要打印的内容 . 这是我在StackOverflow控制台中尝试的示例代码。你知道怎么做吗?也许吧window.print()这里用的方法不对吗?

    setTimeout(function () {
        var el = document.getElementsByClassName('default prettyprint prettyprinted')[0];
        window.getSelection().selectAllChildren(el);
        window.print();
    }, 3000);
    

    我选择的内容,然后单击“打印” here I'm am clicking print 我要打印的内容

    1 回复  |  直到 6 年前
        1
  •  2
  •   Tschallacka    6 年前

    您将失去焦点,因为浏览器将启动本机打印API,该API通常还包括打开打印对话框或打印预览。当与该对话框进行交互时,单击文本将失去焦点。(在Chrome中,其他浏览器未测试)

    随着使用 monitorEvents 我可以告诉你“发生了什么”

    monitorEvents(window);
     window.getSelection().selectAllChildren(document.getElementsByClassName('post-text')[0]);
    window.print();
    

    
    pointerover PointerEvent {isTrusted: true, pointerId: 1, width: 1, height: 1, pressure: 0, …}
    VM324:1 mouseover MouseEvent {isTrusted: true, screenX: -1644, screenY: 153, clientX: 276, clientY: 60, …}
    VM324:1 pointermove PointerEvent {isTrusted: true, pointerId: 1, width: 1, height: 1, pressure: 0, …}
    VM324:1 mousemove MouseEvent {isTrusted: true, screenX: -1644, screenY: 153, clientX: 276, clientY: 60, …}
    VM324:1 pointerdown PointerEvent {isTrusted: true, pointerId: 1, width: 1, height: 1, pressure: 0.5, …}
    VM324:1 mousedown MouseEvent {isTrusted: true, screenX: -1644, screenY: 153, clientX: 276, clientY: 60, …}
    VM324:1 pointermove PointerEvent {isTrusted: true, pointerId: 1, width: 1, height: 1, pressure: 0.5, …}
    VM324:1 mousemove MouseEvent {isTrusted: true, screenX: -1634, screenY: 205, clientX: 286, clientY: 112, …}
    VM324:1 pointerup PointerEvent {isTrusted: true, pointerId: 1, width: 1, height: 1, pressure: 0, …}
    VM324:1 mouseup MouseEvent {isTrusted: true, screenX: -1634, screenY: 205, clientX: 286, clientY: 112, …}
    
    

    VM324:1 click MouseEvent {isTrusted: true, screenX: -1634, screenY: 205, clientX: 286, clientY: 112, …} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    在本例中使用chrome,我单击了打印对话框UI中的一个按钮。这个mouseup事件导致焦点消失,显然选择最终被取消。Chrome可能会将打印对话框作为影子DOM对象插入,使其上的交互具有文档事件。

    我发现,如果使用escape键退出对话框,则此事件不会传输到全局事件侦听器,从而导致它没有任何效果,并使选择保持不变。

    因此,如果要打印该选项,可以使用下面的代码:

    +function() {
        // Create an iframe to make sure everything is clean and ordered.
        var iframe = document.createElement('iframe');
        // Give it enough dimension so you can visually check when modifying.
        iframe.width = document.width;
        iframe.height = document.height;
        // Add it to the current document to be sure it has the internal objects set up.
        document.body.append(iframe);
    
        // Get the node you wish to print.
        var origNode = document.querySelectorAll('.post-text .default.prettyprint.prettyprinted')[0];
    
        // Clone it and all it's children
        var node = origNode.cloneNode(true);
    
    
        /**
         * copied from  https://stackoverflow.com/questions/19784064/set-javascript-computed-style-from-one-element-to-another
         * @author Adi Darachi https://stackoverflow.com/users/2318881/adi-darachi
         */
        var copyComputedStyle = function(from,to){
            var computed_style_object = false;
            //trying to figure out which style object we need to use depense on the browser support
            //so we try until we have one
            computed_style_object = from.currentStyle || document.defaultView.getComputedStyle(from,null);
    
            //if the browser dose not support both methods we will return null
            if(!computed_style_object) return null;
    
                var stylePropertyValid = function(name,value){
                            //checking that the value is not a undefined
                    return typeof value !== 'undefined' &&
                            //checking that the value is not a object
                            typeof value !== 'object' &&
                            //checking that the value is not a function
                            typeof value !== 'function' &&
                            //checking that we dosent have empty string
                            value.length > 0 &&
                            //checking that the property is not int index ( happens on some browser
                            value != parseInt(value)
    
                };
    
            //we iterating the computed style object and compy the style props and the values
            for(property in computed_style_object)
            {
                //checking if the property and value we get are valid sinse browser have different implementations
                    if(stylePropertyValid(property,computed_style_object[property]))
                    {
                        //applying the style property to the target element
                            to.style[property] = computed_style_object[property];
    
                    }   
            }   
    
        };
        // Copy the base style.
        copyComputedStyle(origNode, node);
    
        // Copy over all relevant styles to preserve styling, work the way down the children tree.
        var buildChild = function(masterList, childList) {
            for(c=0; c<masterList.length; c++) {
               var master = masterList[c];
               var child = childList[c];
               copyComputedStyle(master, child);
               if(master.children && master.children.length > 0) {
                   buildChild(master.children, child.children);
               }
            }
        }
        if(origNode.children && origNode.children.length > 0) {
            buildChild(origNode.children, node.children);
        }
        // Add the styled clone to the iframe. using contentWindow.document since it seems the be the most widely supported version.
        iframe.contentWindow.document.body.append(node);
        // Print the window
        iframe.contentWindow.print();
        // Give the browser a second to gather the data then remove the iframe.
        window.setTimeout(function() {iframe.parentNode.removeChild(iframe)}, 1000);
    }();