How do I close a frameless child window?


#1

In my index.html I have a text link id called screener so when I click on it a child window pops up.

Here is my main.js but I haven’t made any changes to it.

The renderer.js file I have click event listening where the window is created.

Inside my screener.html I’ve inserted the link to run the screenerRender.js file.

I’m not sure what exactly I’m doing wrong since my screenerExit.png image doesn’t work when it is clicked on in the created child window.

I’ve highlighted the code snippets in each of the files except for main.js


#2

You have not shared your popup window code, so we can’t tell you where to insert the event.


#3

Sorry, I’ve updated the post now.


#4

Do you have a JavaScript file associated with screener.html or do you want to embed the script in the HTML page?


#6

I do have a js file called screenerRenderer.js but it didn’t work when I put the window closing script inside it. So whichever way gets the code working is fine with me.


#7

You keep giving partial information. I would recommend uploading the whole project to a site and sharing a link so that anyone can see the totality of what you’ve done. Until that happens, it’s impossible to give you good advice.


#8

Fair enough. I’ve posted all the code in the original post to give better context.


#9
screenerExit.addEventListener( "click", e => {...} );

You’ve not defined screenerExit, presumably this line just errors


#10

I have it defined in my screener.html file under line 45. You are correct, it does error but I don’t know what is causing this.


#11

You don’t have it defined, and the error is because you’re trying to use a method on an object that doesn’t exist. The problem is that you’re assuming that the JavaScript knows anything at all about your HTML. It doesn’t unless you tell it what to look at. You do that with the Document API, which makes a request to your browser to give it access to the elements in the HTML. This code will work:

var screenerExit = document.getElementById("screenerExit")

screenerExit.addEventListener( "click", e => {
  var window = remote.getCurrentWindow()
  window.close()
 } )

There’s one more semi-issue with that code. As you can see from your own code, window is a pre-existing variable that accesses a browser API. I would not recommend using that name for one of your own variables, even if it’s inside a function and thus won’t mess up any window calls elsewhere in your code. The Electron docs use win for the same purpose, but the best solution would be to have all of your variables be as clearly named as possible. I think you should call it screenerWindow, if you call it anything at all. Alternatively, you could condense that whole code block down to one line:

screenerExit.addEventListener( "click", e => remote.getCurrentWindow().close() )

When an arrow function is all on one line, you don’t need braces. The JS interpreter parses the text after the arrow into an implicit return statement, which is probably technically important for some use cases, but when you’re calling another function it doesn’t do anything differently from having that function in the function body. To be honest, I can’t think of any case where it matters and it’s entirely possible that there’s no valid one-liner where the difference matters. JavaScript is not the most technically demanding language out there (it’s one of the most forgiving, in fact). You’ll note that my examples don’t include semicolons, because they aren’t actually needed. JS just doesn’t care about a lot of things.


#12

Thanks for taking the time to write detailed reply.

I inserted your code snippet in my screenerRenderer.js but it still didn’t work:

var screenerExit = document.getElementById("screenerExit")

screenerExit.addEventListener( "click", e => {
  var screenerWindow = remote.getCurrentWindow()
  screenerWindow.close()
 } )

Thanks for letting me know what the => meant since I’ve just been looking at similar examples to try to get the code working.

What I don’t understand is that I never defined exit which is the name of the id in my index.html file inside my renderer.js file and the code to close the main window works fine. I didn’t have to write var exit = document.getElementById("exit") inside renderer.js.

I’m curious to know why would exit work in my main window but not screenerExit for my child window if it is called the same way?


#13

I tried both your code examples but it still didn’t work.


#14

Sorry, the past few days have been busy for me and I haven’t had the bandwidth to fix my own approach and provide a working sample from my end. I’m not working tomorrow, so I can probably sit down and think through it then.


#15

I gave it a go in Electron Fiddle (just the screener bits) and it seems to work, and like you’re saying, without the document.getElementById(...)

I’m not sure why this works, but it does! I couldn’t say why it’s not working for you, but can you see that Bootstrap/jQuery are working properly and whether or not they’re erroring?


#16

Because the screener window is behaving as a parent window which works fine currently but when you create a child window inside the parent window it still doesn’t work.


#17

So I tried the whole lot, and it works for me. I took out the jQuery/Bootstrap stuff because I don’t have them here, but errors in require-ing them does break the rest of the JS (ie, your click listener), so I’d recommend opening up DevTools in the screener window to make sure everything’s running correctly.