【问题标题】:Hiding loading overlay when popup loses focus弹出窗口失去焦点时隐藏加载覆盖
【发布时间】:2013-01-09 19:51:54
【问题描述】:

我正在开发一个带有弹出窗口的 chrome 扩展程序,当您单击扩展程序图标时会显示该窗口。在弹出窗口中,我有一个按钮,一旦单击该按钮,就会在当前打开的标签页上显示加载框。

截图:

加载框会在一段时间后使用setTimeout 移除。但是,这仅在弹出窗口本身可见时才有效。如果我单击弹出窗口上的按钮,然后转到其他选项卡并返回或单击选项卡页面上的其他位置,弹出窗口隐藏但加载框仍然可见。

即使弹出窗口不可见/失焦,是否有人知道如何隐藏加载框?我认为它会消失,因为有 setTimeout 函数将其删除,但当弹出窗口失去焦点时它不起作用。

这里没有粘贴所有相关代码,here 是扩展程序的下载链接,这样你就可以明白我的意思了。

在实际扩展中,我有 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__'))"}
             );
         }
     });

感谢您的帮助

【问题讨论】:

标签: javascript html google-chrome google-chrome-extension


【解决方案1】:

步骤

  • 将此 AJAX 请求移至后台页面。
  • 点击按钮(对话框被注入到页面的位置)将消息传递到后台脚本以存储 tab.id(检查下一点)。
  • 使用从浏览器操作收到的 tab.id 执行您的删除对话框代码(需要标签 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 看起来像这样,您可以直接调用后台 Page 的函数

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[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 调用??
  • 是的,它在按钮点击时运行。
  • @dev02: 我已经添加了一个工作版本原型作为我的EDIT 1,希望这会有所帮助:)
  • 不幸的是,当我点击按钮时,我得到了Reference error: data is not defined,即使我像这样传递它:chrome.extension.getBackgroundPage().invokeAJAX(tab.id, $(this).closest('form').serialize());,然后通过像 invokeAJAX(tabid, data) 这样的函数使用它,但是在那个 ajax 函数里面,它说未定义:(
【解决方案2】:

弹出代码在未显示时停止执行。但是,注入的代码总是被执行。所以你应该在注入的代码中设置超时时间,像这样:

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

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

【讨论】:

  • 您好,谢谢。在实际扩展中,我有一个 ajax 请求而不是 setTimeout。在这种情况下,一旦 ajax 请求完成,我将如何隐藏加载消息?
  • @dev02: 你有没有尝试添加成功的ajax请求处理程序?
  • @Sudarshan:是的,我已经添加了成功以及完整的处理程序,我在其中放置了代码以隐藏加载框。这仅在弹出窗口处于焦点时才有效。您可以下载扩展程序并自己查看。
  • @dev02:我已经下载了你的扩展,但是里面没有AJAX请求?你链接正确的文件了吗..
  • @Sudarshan:我已经在问题中发布了实际的 ajax 请求
猜你喜欢
  • 2011-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-29
  • 2014-03-08
相关资源
最近更新 更多