1

I'm trying to make a jQuery modal dialog box that covers the entire webpage. It works fine on some sites but not on others. The problems I'm having are that the dialog box is underneath webpage content, like the google search bar and button, and the modal overlay does not cover the entire page. Here both the dialog box and overlay are covered by the upper Google banner

Here is my code. I'm using the dialog box like an alert in a chrome extension so everything has to be in a content script that background.js executes.

if (someEvent) {

   var NewDialog = $('<div id="MenuDialog"><p>This is dialog content.</p></div>');
   NewDialog.dialog({
    autoOpen: false,
    modal: true,
    title: "title",
    zIndex: 99999,
    buttons: [
    {text: "Submit", click: function() {doSomething()}},
    {text: "Cancel", click: function() {$(this).dialog("close")}}
    ]
   })
   NewDialog.dialog("open");
   });
}

I've looked all over for solutions including changing the z indices but nothing seems to work. What's the best way to do it?

Update

I'm trying the iframe approach suggested by Veritoanimus but I'm still stuck. I found code that creates an iframe over an entire page, so it works like a modal. But how do I add the dialog box to the iframe?

Code:

wrapperDiv = document.createElement("div");
wrapperDiv.setAttribute("style","position: absolute; left: 0px; top: 0px; background-color: rgb(255, 255, 255); opacity: 0.5; z-index: 2000; height: 1083px; width: 100%;");
iframeElement = document.createElement("iframe");
iframeElement.setAttribute("style","width: 100%; height: 100%;");
wrapperDiv.appendChild(iframeElement);
document.body.appendChild(wrapperDiv);

var newDiv = $(document.createElement('div')); 
newDiv.html('hello there');
newDiv.dialog({
  title: "title",
    zIndex: 99999,
    buttons: [
    {text: "Submit", click: function() {doSomething()}},
    {text: "Cancel", click: function() {$(this).dialog("close")}}
    ]
  })

This is what it looks like. I know it's the same issue because I'm not really doing anything different with the dialog, but I can't figure out how to work the two together.

Carsen
  • 31
  • 3
  • I think z-index is the way to go. If it's not working try setting the z-index on all the parent elements as well. If you could post a fiddle it'd be easier. – Jonathan Chaplin Jan 05 '18 at 00:52
  • Here's the fiddle, but it's not perfect: https://jsfiddle.net/Lgx8ojrg/3/ . I copied http://jsfiddle.net/westonruter/6mSuK/ for adding a website but it behaves weird. Everything works fine with the given wikipedia website, but it couldn't load nearly every other site I tried and I can't figure out why. Hopefully it helps somewhat at least. – Carsen Jan 05 '18 at 02:14

1 Answers1

0

I've had no end of problems with z-indexing in the past working on sites that go really deep. I find it best to do a mass z-index on the site so that I can define layer levels afterward as needed. If you start by setting your site to sit flat on the z index, it'll save headaches later and let you use more reasonable numbers for indexing because you end up explicitly defining each z layer. I ended up with 1 as the base layer, tooltips on 2, menus on 3, then modal backsplash for dialogs on 4, dialogs on 5, modal blocking backsplash (for page loading) on 6 and the status window on 7.

span, div, label, a, table, tbody, tr, td, th, thead, tfoot, 
    input, textarea, select, ul, li, ol, p, h1, h2, h3, h4, h5, h6, 
    iframe, hr, b, i, img, object, body  {

    z-index: 1;
}
Veritoanimus
  • 319
  • 3
  • 10
  • Thanks, but this is for a chrome extension that adds a modal dialog box to webpages after a certain event, so I can't control the z indices of the webpage's elements themselves. – Carsen Jan 05 '18 at 02:09
  • injecting onto an existing page can cause a lot of problems. Have you tried taking advantage of the default layering and iframes? you could put the content in an iframe at the end of the body with a high z-index and it should prevent anything covering. Even then you could run into issues since some sites may have additional protocols to prevent xss injection. – Veritoanimus Jan 05 '18 at 02:14
  • 1
    @Carsen You can change pretty much everything on a web page with a Chrome Extension including z-indexes, but I don't think you would need all this to just display a simple dialog across the whole page. Also is it absolutely necessary for all this to go through a popup instead of using a [content script](https://developer.chrome.com/extensions/content_scripts)? – Luka Čelebić Jan 05 '18 at 02:20
  • I was able to add an iframe that covers the entire page, but I couldn't figure out how to pair the dialog with the frame so it also appeared above all other content. This is my first time working with javascript so I'm not familiar with how it all works. Is there no simple way to have a modal dialog appear on the entirety of a website? I'm essentially trying to recreate alert() with more functionality that is triggered on certain websites – Carsen Jan 05 '18 at 02:22
  • @PredatorIWD My mistake, this isn't in popup.js (I'll edit that). It's in a content script that background.js executes. In fact I initially tried creating the dialog in popup.js but it appeared in the popup and not on the actual webpage. Here's my question on that, which led me to where I am now: https://stackoverflow.com/questions/48087589/change-jquery-dialog-location-chrome-extension?noredirect=1#comment83150239_48087589 – Carsen Jan 05 '18 at 02:28
  • As someone who has to regularly deal with web security issues, I get very suspect of injecting anything arbitrarily into a website. While you do get an amount of freedom working in an extension, beware of how and what you attempt to inject because you could put users at risk and encourage sites to tighten security because it is an xss threat. The iframe is probably your best bet because it gives your code a safe place to run that also leaves it somewhat separated from the site it displays on and, at least slightly, reduces the xss behavior. – Veritoanimus Jan 05 '18 at 02:28
  • 1
    @Veritoanimus First I really doubt he is building something of a size that can influence any site to " to tighten their security" or something that will have a larger user base, since he is new to Javascript (like he said in his earlier question), and second, injection of Javascript into any site is common and to be expected and if any site relies on users not meddling with client side Javascript to be secure then I really fear for their "security". – Luka Čelebić Jan 05 '18 at 02:37
  • xss injection is a client threat rather than a server threat, but businesses still worry about it because anything that can affect customers reflects on the business regardless of how it got there. I can't count the number of times customers complained about ads on a site due to adware on their computer and not the site itself. In fairness though, plugins get access that are at your own risk anyways. That said, many sites do work to prevent xss, so you're going to have a very difficult time getting a plugin like this to work consistently. The iframe is going to be your best bet. – Veritoanimus Jan 05 '18 at 02:46
  • @Veritoanimus He wants to show a dialog across the whole page on every site. I can see a content script or a background script with filtering URLs working a lot more consistently than loading every site as a iframe, from which a lot more sites have a problem with than client injected code, like for example stackoverflow itself, which then won't load. Also loading them as a iframe doesn't really help much, if at all since most of the time attacks are very specialized to a specific site or extension which can easily know that. – Luka Čelebić Jan 05 '18 at 03:01
  • I was thinking he should load his content in the iframe, not the site. A lot of sites other than stack check that they're the top frame. But by loading his own in an iframe he'll get better render control and be less intrusive. Pretty much all sites will allow this behavior since it's common for marketing tags and social media. – Veritoanimus Jan 05 '18 at 03:17
  • I appreciate the discussion, thanks for the help. @Veritoanimus I'm able to create an iframe that covers the whole page, but I'm having trouble loading the dialog content within it. See the question's update for details. – Carsen Jan 05 '18 at 17:06
  • There's more on that in another thread here: https://stackoverflow.com/questions/10418644/creating-an-iframe-with-given-html-dynamically. basically, you're going to load everything into a completely new page that you can work in, so you'll have to load your scripts and everything into the html for that page. This will also help prevent script and style collision. Since you end up in your own page, you wont be competing with existing scripts and styles for the site you're rendering into. – Veritoanimus Jan 05 '18 at 17:08