0

I think it is an easy questions but I am new in JavaScript

Why button "but2" not work when I try close a new window?

HTML code

<input type="button" value="New window" id="but1" onclick="createwin()" />
<input type="button" value="close window" id="but2" onclick="closewin()" />

JavaScript code

function createwin(){
    var win1 = window.open('http://www.google.com','google','width=500,height=500');
}

function closewin(){
    win1.close();
}
Brettski
  • 19,351
  • 15
  • 74
  • 97
Tarek Saied
  • 6,482
  • 20
  • 67
  • 111

4 Answers4

6

Its a scope issue win1 varaible is out of scope. Since you are declaring win1 inside the createwin() function, the closewin() function has no reference, it is out of scope. You need set win1 as a global variable like this:

var win1;

function createwin(){
    win1 = window.open('http://www.google.com','google','width=500,height=500');
}

function closewin(){
    win1.close();
}
John Hartsock
  • 85,422
  • 23
  • 131
  • 146
  • Does declaring the global `var win1` actually matter? (See my answer for what I suggest instead.) – Jared Farrish Apr 20 '11 at 03:02
  • Oops, I forgot the remove the global `var win1` from my answer. I don't think it's necessary, but I'll entertain convincing arguments. :) – Jared Farrish Apr 20 '11 at 03:04
  • @Jared Farrish... Yes and No. No it doesnt technically matter as undeclared variables will be treated as global variables. But Yes it is important for readability. Sometimes you can get yourself in trouble trying to read code where variables are not declared. You may find yourself asking the questions "Where was this declared? Was this variable passed into the function? Where did it come from?" – John Hartsock Apr 20 '11 at 03:07
  • @John Hartsock - I can see that. I like to stay away from global variables when I can, but that can be impossible or impractical sometimes. I do add them globally by practice, however, so I can have an index of which variables I've declared in the variable scope, for reference. And I don't know that the simple var declaration actually by itself accomplishing everything you're suggesting, but comments might. :) – Jared Farrish Apr 20 '11 at 03:12
  • @Jared Farrish You just answered your own question and validated my answer to your question. Readability is important. It is important to keep your code in a readable state such that other developers can understand easily. – John Hartsock Apr 20 '11 at 03:14
  • @John - I just don't think simply sticking `var win1` somewhere not in a function *by itself* matters. It needs to be commented. That's the meaningful step, IMO. – Jared Farrish Apr 20 '11 at 03:17
  • @John - All I'm saying when I declare them is I don't want to step on the variables I do have globally. – Jared Farrish Apr 20 '11 at 03:18
  • @Jared Farrish... I completely agree. Inline comments are a wonderful practice and I wish more developers would use them more frequently. – John Hartsock Apr 20 '11 at 03:19
6

Your variable scoping is off:

// Note I don't use var here to declare
// the win1, which makes it globally available
// instead of just function-scope available.
function createwin(){
    win1 = window.open('http://www.google.com','google','width=500,height=500');
}

function closewin(){
    // Do this to prevent Javascript errors.
    if (win1 && win1.close && typeof win1.close == 'function') {
        win1.close();
    }
}

http://jsfiddle.net/userdude/h7VjC/2/

When you declare variables in Javascript, you have to be aware of how you declare them.

See here for an excellent demonstration: What is the scope of variables in JavaScript?

Community
  • 1
  • 1
Jared Farrish
  • 48,585
  • 17
  • 95
  • 104
  • @Jared but why you use --> if (win1 && win1.close) { win1.close(); } // how it work without global var – Tarek Saied Apr 20 '11 at 03:11
  • The first text is "does the `win1` variable exist", the second "does the `win1.close` object member exist". The first one prevents things like `undefined` errors on nonexistent objects, the second makes sure you call `.close()` on an object that has that as an object member. – Jared Farrish Apr 20 '11 at 03:16
  • @tarek11011 - I got to thinking about it and it also really needs a third test: "is the typeof win1.close equal to function". For more on the `typeof` keyword, see https://developer.mozilla.org/en/JavaScript/Reference/Operators/Special/typeof. – Jared Farrish Apr 20 '11 at 03:31
  • @Jared in fact i am new in javascript and your answer is Very useful for me .. but why used typeof test ? What will change ? – Tarek Saied Apr 20 '11 at 03:45
  • @tarke11011 - It doesn't change anything, it returns a value. For instance, just testing that an object member exists doesn't check that you can call a function on that member. An example here: http://jsfiddle.net/userdude/mQQR6/ – Jared Farrish Apr 20 '11 at 03:53
  • @tarek11011 - What it'll change, I suppose, is that it will not allow you to call an object function `win1.close()` on a non-function. If you did this and had code that ran after it, that code would not run if `win1.close` was a string or number instead of a window handle object (or, I suppose, an object with a `.close()` function defined), which abstractly shouldn't throw an error. – Jared Farrish Apr 20 '11 at 04:09
  • @Jared Yes, I understood very well thank you very much i make another qus http://stackoverflow.com/questions/5725512/why-moveby-and-moveto-not-working-in-my-code :) – Tarek Saied Apr 20 '11 at 04:32
3

the function closewin() can't see the variable win1 because it was declared inside the function createwin(). you should be able to fix this by declaring win1 outside of the functions:

var win1;

function createwin(){
    win1 = window.open('http://www.google.com','google','width=500,height=500');
}

function closewin(){
    win1.close();
}
user716340
  • 81
  • 2
0

Because the variable win1 is local to the createwin() function

Brettski
  • 19,351
  • 15
  • 74
  • 97