失去焦点时隐藏弹出窗口加载覆盖层

3
我正在开发一个Chrome扩展程序,它包含一个弹出窗口,当您点击该扩展图标时会出现。在弹出窗口上,我有一个按钮,一旦点击,就会在当前打开的选项卡页上显示加载框。
截图: enter image description here 使用setTimeout函数,加载框会在一段时间后被移除。然而,这仅在弹出窗口本身可见时起作用。如果我在弹出窗口上点击按钮,然后转到其他选项卡并返回或单击选项卡页面的其他位置,则弹出窗口隐藏但加载框仍然可见。
是否有人知道如何隐藏加载框,即使弹出窗口变得不可见/失去焦点?我认为它会消失,因为有一个setTimeout函数将其删除,但是当弹出窗口失去焦点时,它不起作用。
与此处粘贴所有相关代码不同, 这里 是扩展程序的下载链接,以便您可以看到我具体的意思。
在实际扩展程序中,我使用ajax请求,而不是setTimeout:
 $.ajax({
         url : 'localhost url here....',
         data : data, // this is searialized form data
         dataType : 'json',
         method : 'post',
         success : function (r) {
             if (r.success) {
                 window.close();

                 var notification = webkitNotifications.createNotification(
                    'img/48.png',
                    'Done!',
                    'The page has been saved successfully :)'
                 );

                 notification.show();

                 setTimeout(function () {
                     notification.cancel();
                 }, 5000);

             }
             else {
                 if (r.error) {
                     $ediv.text(r.error).fadeIn('fast');
                 }
             }
         },
         error : function (r) {
             $ediv.text('Unknown error, please try again later.').fadeIn('fast');
         },
         complete : function (r) {
             chrome.tabs.executeScript(
                null, {code : "document.body.removeChild(document.getElementById('__wnoverlay__'))"}
             );
         }
     });

感谢您的帮助。

演示问题的屏幕录像:http://www.screenr.com/S2r7 - dev02
2个回答

2

步骤

  • 将此AJAX请求移动到后台页面。
  • 在单击按钮(您的对话框注入到页面的位置)时,向后台脚本传递消息以存储tab.id(请参见下一个要点)。
  • 使用从浏览器操作接收到的tab.id执行删除对话框代码(需要Tab id,因为用户可以随时切换他的活动选项卡\窗口)。

参考资料

编辑1

在清单文件中添加以下内容,确保您在后台页面中注册了背景和jquery。

"background":{
    "scripts":["js/jquery.js","background.js"]
},

请在background.js中添加以下代码:

此代码将 AJAX 调用迁移到后台页面,并在 5 秒阈值后执行对话框框的删除。

function invokeAJAX(tabid) {

    $.ajax({
        url: 'localhost url here....',
        data: data, // this is searialized form data
        dataType: 'json',
        method: 'post',
        success: function (r) {
            if (r.success) {
                window.close();

                var notification = webkitNotifications.createNotification(
                    'img/48.png',
                    'Done!',
                    'The page has been saved successfully :)');

                notification.show();

                setTimeout(function () {
                    notification.cancel();
                }, 5000);

            } else {
                if (r.error) {
                    $ediv.text(r.error).fadeIn('fast');
                }
            }
        },
        error: function (r) {
            $ediv.text('Unknown error, please try again later.').fadeIn('fast');
        },
        complete: function (r) {
            chrome.tabs.executeScript(
            tabid, {
                code: "document.body.removeChild(document.getElementById('__wnoverlay__'))"
            });
        }
    });

}

您的popup.js文件看起来像是直接调用背景页面函数的样子

document.addEventListener("DOMContentLoaded", function () {

    $('#btn').click(function () {

        // show loading message

        // chrome.extension.sendRequest({}, function(response) {});

        chrome.tabs.executeScript(null, {
            "code": 'var __a=document.createElement("DIV");__a.id="__wnoverlay__";__a.style.width="300px";__a.style.height="80px";__a.style.position="fixed";__a.style.top="50%";__a.style.left="50%";__a.style.color="#fff";__a.style.zIndex=9999999;__a.style.opacity=0.8;__a.style.textAlign="center";__a.style.padding="10px";__a.style.border="12px solid #cccccc";__a.style.marginLeft="-150px";__a.style.marginTop="-40px";__a.style.fontWeight="bold";__a.style.fontSize="17px";__a.style.borderRadius="10px";__a.innerHTML="Working, please wait...";document.body.appendChild(__a);'
        });
        chrome.tabs.query({}, function (tab) {//Get current tab 

            chrome.extension.getBackgroundPage().invokeAJAX(tab.id);//DO Ajax call and delete div added after 5 sec to current tab only
        });


    });
});

编辑 2

popup.js

popup.js 的更改如下:

  • 修改了 tabs.query,仅获取 当前活动的浏览正常窗口
  • 回调函数返回 Tab 数组所以使用了 tab[0] 索引。

这些更改后,它会发送正确的消息。

document.addEventListener("DOMContentLoaded", function () {

    $('#btn').click(function () {
        var $this = $(this);

        chrome.tabs.executeScript(
        null, {
            "code": 'var __a=document.createElement("DIV");__a.id="__wnoverlay__";__a.style.width="300px";__a.style.height="80px";__a.style.position="fixed";__a.style.top="50%";__a.style.left="50%";__a.style.color="#fff";__a.style.background="url(http://groot.com/WebNote_HTML/ChromeExtension/img/spinner.gif) center no-repeat #999999";__a.style.zIndex=9999999;__a.style.opacity=0.8;__a.style.textAlign="center";__a.style.padding="10px";__a.style.border="12px solid #cccccc";__a.style.marginLeft="-150px";__a.style.marginTop="-40px";__a.style.fontWeight="bold";__a.style.fontSize="17px";__a.style.borderRadius="10px";__a.innerHTML="Working, please wait...";document.body.appendChild(__a);'
        });
        //Proper Query Formation    
        chrome.tabs.query({
            "active": true,
            "status": "complete",
            "currentWindow": true,
            "windowType": "normal"
        }, function (tab) { //Get current tab
            //DO Ajax call
            //tab is an array so we need to access its first index
            chrome.extension.getBackgroundPage().invokeAJAX(tab[0].id, $this.closest('form').serialize());
        });

    });

});

background.js

background.js 进行的更改:

  • 删除了$ediv.text代码引用,因为在后台页面中未定义。

经过这些更改,以下是最终代码。

 function invokeAJAX(tabid, data) {

     data = data || '';

     $.ajax({
         url: 'http://groot.com/WebNote_HTML/ChromeExtension/savePage.php',
         data: data,
         dataType: 'json',
         method: 'post',
         success: function (r) {
             if (r.success) {
                 // window.close();

                 var notification = webkitNotifications.createNotification(
                     'img/48.png',
                     'Done!',
                     'The page has been saved successfully :)');

                 notification.show();

                 setTimeout(function () {
                     notification.cancel();
                 }, 5000);

             } else {
                 if (r.error) {
                     //$ediv.text(r.error).fadeIn('fast');
                     console.log("Error .." + r);
                 }
             }
         },
         error: function (r) {
             //$ediv.text('Unknown error, please try again later.').fadeIn('fast');
             console.log("Error .." + r);
         },
         complete: function (r) {
             chrome.tabs.executeScript(
             tabid, {
                 code: "document.body.removeChild(document.getElementById('__wnoverlay__'))"
             });
         }
     });

 }

编辑 3

$('#btn').click(function () {
    var $this = $(this);
    //Proper Query Formation    
    chrome.tabs.query({
        "active": true,
        "status": "complete",
        "currentWindow": true,
        "windowType": "normal"
    }, function (tab) { //Get current tab
        //DO Ajax call
        //tab is an array so we need to access its first index
        chrome.tabs.executeScript(
        tab[0].id, {
            "code": 'var __a=document.createElement("DIV");__a.id="__wnoverlay__";__a.style.width="300px";__a.style.height="80px";__a.style.position="fixed";__a.style.top="50%";__a.style.left="50%";__a.style.color="#fff";__a.style.background="url(http://groot.com/WebNote_HTML/ChromeExtension/img/spinner.gif) center no-repeat #999999";__a.style.zIndex=9999999;__a.style.opacity=0.8;__a.style.textAlign="center";__a.style.padding="10px";__a.style.border="12px solid #cccccc";__a.style.marginLeft="-150px";__a.style.marginTop="-40px";__a.style.fontWeight="bold";__a.style.fontSize="17px";__a.style.borderRadius="10px";__a.innerHTML="Working, please wait...";document.body.appendChild(__a);'
        });
        $('#url').val(tab[0].url);
        $('#title').val(tab[0].title);
        $loader.hide();
        chrome.extension.getBackgroundPage().invokeAJAX(tab[0].id, $this.closest('form').serialize());
    });

});

@dev02:你是在点击按钮时执行这个ajax调用吗? - Sudarshan
@dev02:我已经添加了一个可工作的原型版本,作为我的EDIT 1,希望这可以帮到你 :) - Sudarshan
我猜你需要等待 $(this).closest('form').serialize() 完成,并在处理完成后将其传递给 chrome.extension.getBackgroundPage().invokeAJAX - Sudarshan
@dev02:发布您的代码现状,我会尝试帮助您 :) - Sudarshan
@dev02:你能放一个屏幕录像吗?我很惊讶看到你的前端出现了错误。顺便说一下,我的时区已经过了凌晨2点了,我会在今天早上检查的 :) :) - Sudarshan
显示剩余15条评论

0

当弹出窗口未显示时,弹出代码将停止执行。然而,注入的代码总是会被执行。因此,您应该在注入的代码中设置超时,就像这样:

chrome.tabs.executeScript(null, {"code": 'setTimeout(function(){ document.body.removeChild(document.getElementById("__wnoverlay__")); }, 5000)'});

将第13-15行的代码替换为上面的代码,它应该可以工作。


嗨,谢谢。在实际的扩展中,我使用了一个 ajax 请求,而不是 setTimeout。在这种情况下,一旦 ajax 请求完成,我该如何隐藏加载消息? - dev02
@dev02:你尝试过在ajax请求的成功处理程序中添加代码吗? - Sudarshan
@Sudarshan:我已经在问题中发布了实际的Ajax请求。 - dev02
@dev02:请检查一下我对这个问题的答案。 - Sudarshan
@dev2 你应该看到Sudarshan的答案,它应该解决你的问题。 - Uzair Farooq
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接