JavaScript variable scopes - javascript

I found a bunch of other questions about this topic, but for some reason they did not solve my "problem".
I have this little script I made of pure interest - and it works just fine, but something is bothering me. The script clears a text field onFocus and types "Write here" if nothing is entered onBlur. The script is as follows:
<html>
<head>
<title>JavaScript</title>
<!--Scripts-->
<script type="text/javascript">
<!--
function noValue() {
var _value = document.getElementById('input').value;
if (_value == "Write here") {
document.getElementById('input').value='';
}
}
function changeValue() {
var _value = document.getElementById('input').value;
if (_value == "") {
document.getElementById('input').value='Write here';
}
}
function dontLeave() {
var c_box = confirm("Do you want to leave?");
if (c_box == true) {
die;
}
else {
history.back;
}
}
//-->
</script>
</head>
<body onUnload="dontLeave()">
<form>
<input id="input" type="text" value="Write here" onFocus="noValue()" onBlur="changeValue()">
</form>
</body>
</html>
As you can see the variable _value is used twice - in "noValue()" and "changeValue()". This is what I want to change.
I thought that you could access a global variable from inside a function by not declaring it inside the function fx:
var i = 1;
function foo(){
i++;
return;
}
and the output would be 2 if you call the function. But when I declare and initialize the variable outside the function, the variable does not work from inside the functions - how come?? Have I misunderstood something here? :)
I also have another question:
As you can see I added a confirm box when you leave the page (I know this is annoying, I do not intend to use it, this is just an experiment) but I don't know how to not leave the page if the client presses "Cancel". How do I do so? :)
EDIT The first part of my problem is now solved - thanks!
But theres still the last part about the annoying confirm-box; does any of you know how to stop the client from leaving, so to speak?

To answer your first question, your problem with initializing _value is probably one of timing. By placing _value outside of a function, that line of javascript will be executed immediately. Since the javascript is in the head section, it will be executed before the input element has been loaded into the document. You can put that one line of javascript at the end of the document, after the input element has been loaded, such as this:
<body onUnload="dontLeave()">
<form>
<input id="input" type="text" value="Write here" onFocus="noValue()" onBlur="changeValue()">
</form>
<script type="text/javascript">
var _value = document.getElementById('input').value;
</script>
</body>
Now the javascript variable "_value" will be set properly and available to all of your javascript functions "globally".

Well, you can declare it outside the functions, but you need to update the value upon each function call (that is, each event). If you don't, then how will your event handlers know what it is?

If you put this line...
var _value = document.getElementById('input').value;
... outside of the functions, it will be in scope within the functions. I think the problem you're having though is that placing it there will cause it to be executed before the DOM is ready, and hence your 'input' element doesn't exist yet. Try either waiting for a dom load event, or place that script at the very bottom of the page (just inside the </body> tag).

Related

Basic HTML JavaScript function not working as intended

I'm wandering if anyone can help. Im doing some rather basic JS for a project but I'm an idiot and not sure how to do this element.
I've used an opensource word highlighting program i've found online which works when i input a string to be highlighted, but when i input "input_id.value" which is a working (tested) value of an input box, The highlighter doesnt work. I thought it could be that it's not updating i.e it only runs once so it will try to highlight no value as nothing has been inputted.
This is the code snippet:
<script type="text/javascript" src="../Resources/hilitor.js"></script>
<script type="text/javascript">
var input = document.getElementById("input_id").value;
// global variable
var myHilitor;
document.addEventListener("DOMContentLoaded", function() {
myHilitor = new Hilitor();
myHilitor.apply("fox");
}, false);
</script>
This works correctly and higlights "fox" as shown in this image.
However when i change
myHilitor.apply("fox");
to
myHilitor.apply(input_id.value);
nothing is highlighted at all. I tried putting the whole thing into a function like an idiot but that also doesnt work
<script type="text/javascript" src="../Resources/hilitor.js"></script>
<script type="text/javascript">
function searchFunction(){
var input = document.getElementById("input_id").value;
// global variable
var myHilitor;
document.addEventListener("DOMContentLoaded", function() {
myHilitor = new Hilitor();
myHilitor.apply("fox");
}, false);
}
</script>
The function is called by
<button onclick="searchFunction()" class="button"></button>
I'm truly dumbfounded, any help would be very appreciated. Thankyou :)
Thanks all for the helpful contributions, Problem is solved I'm waiting to be able to accept answer
document.addEventListener("DOMContentLoaded", function() { causes a function to run when the DOMContentLoaded event happens (which is about when </html> is parsed as the document loads).
You haven't shown how searchFunction is called, but odds are that it is when a button is clicked.
That will happen after the DOMContentLoaded event has occurred so the condition for the function running never happens.
Don't include that condition.
Your variable is called var input but you're using input_id here myHilitor.apply(input_id.value) ;
You have declared var input = document.getElementById("input_id").value;.
But while calling myHilitor.apply(input_id.value); you are passing input_id.value. You should pass just input.
Like myHilitor.apply(input);

OnChange Event foriFrame on HTML with Onload Event

I have SAP system where I can integrate HTML page. This HTML page is launched on Button Click.
Button click changes the value of Iframe source every time.
As I understand the basic, I wrote the below code which is working fine on the first click. The HTML page gets loaded.
<!DOCTYPE html>
<html>
<body onLoad="myFunction()">
<iframe id="myFrame" src="http://www.w3schools.com/" height="1000" width="2000" frameborder="0"></iframe>
<script>
function myFunction() {
document.getElementById("myFrame").src = sap.byd.ui.mashup.context.inport.FirstName;
}
</script>
</body>
</html>
When I click second time the value for sap.byd.ui.mashup.context.inport.FirstName changes, but there is no change in the Iframe.
I saw there is something called onChange event, but I am not able to write use it correctly. Can anyone help me to do this?
An ugly solution would be to constantly check if the value of the FirstName, in order to check for changes.
<script>
var _firstname;
function myFunction() {
document.getElementById("myFrame").src = sap.byd.ui.mashup.context.inport.FirstName;
_firstname = sap.byd.ui.mashup.context.inport.FirstName;
}
setInterval(function() {
if (_firstname != sap.byd.ui.mashup.context.inport.FirstName)
myFunction();
}, 1000) //check every second to see if FirstName value changed
</script>
But I would definitely recommend calling myFunction() from wherever you change sap.byd.ui.mashup.context.inport.FirstName to avoid the use of setInterval. If you can change the value of a javascript object, you should be able to make a function call too. I suggest you research how to call a javascript function and just call myFunction() right after you change FirstName. Then you will not need the setInterval.

Javascript window.onLoad element content not changing

Im having a problem with changing an elements content
HTML Code:
<script type="text/javascript">
// Javascript
function promptLogin()
{
var person=prompt("Please enter your name","User");
if (person!=null)
{
x="Hello " + person + ", welcome to JBA Limited";
document.getElementById("topBar_message").innerHTML=x;
}
}
</script>
</head>
<body>
<script>window.onLoad = promptLogin()</script>
<header>
<div class="bul_header_topBar">
<p id="topBar_message">Welcome to JBA Limited</p>
</div>
I am unsure of the problem but I fear the problem is with the function being called before the webpage is loaded and therefore no id is present. Either that or have spelt/defined something wrong.
Bull
You need to strip the () from promptLogin
edit: oh yeah, and it's onload, not onLoad
bigger edit:
window.onload waits until your DOM is loaded, so there's no way it's not there. This is just a case where you are trying to pass a method that has already been run. The () at the end of promptLogin means "window.onLoad is equal to the return value of this function", not what you are looking for ("window.onLoad equals this function").
Also, once upon a time browsers were less case-sensitive when it came to these callbacks, but now they are. it's window.onload.
My guess is that your dom is not loaded yet, so when you try to "get" your element its not loaded/there yet.
You can either add what I suggest below, or leave everything as it is, except remove the onload etc.. and put that call (with the script tag) at the very bottom of your page.
//at the bottom of your page within script tags
<script>promptLogin()</script>
Put this code at the bottom (under) your dom.
add the code below to your page, at bottom within script tags.
remove this window.onLoad = promptLogin()
(function()
{
var person=prompt("Please enter your name","User");
if (person!=null)
{
x="Hello " + person + ", welcome to JBA Limited";
document.getElementById("topBar_message").innerHTML=x;
}
})()
What el_bob says is correct, however rather than just stripping () I would use the anonymous function syntax because it is more common thus more readable:
window.onload = function(){
promptLogin();
}
The main advantage of this syntax is that you can make multiple calls:
window.onload = function(){
promptLogin();
anotherFunction();
thirdFunction();
}

Can I put a script at the bottom of a web page, but call it from the top?

Could this cause potential problems:
<HTML>
<BODY>
...
<INPUT name="xyz" onchange="myFunction();">
...
<SCRIPT>
function myFunction()
{
...
}
</SCRIPT>
</BODY>
</HTML>
What happens if the page loads slowly and the form renders before the script portion at the bottom is loaded? Will a JavaScript error occur if the user enters some text into the INPUT box?
You need to load the script before you can call it. Why don't you change it to something like this:
<input name="xyz" id="myInput">
...
<script>
function myFunction
{
...
}
window.onload = function() {
var myInput = document.getElementById('myInput');
myInput.onchange = myFunction;
}
</script>
This approach allows you to separate your markup and scripting and have all of your js in one place.
JavaScript development has changed over the years.
Not only is your original question being debated, but to go back to the theme of your original question, so is your methodology itself.
I highly recommend reading this short bit on some JavaScript best practices:
http://www.catswhocode.com/blog/best-practices-for-modern-javascript-development.
It works, though it may be a problem if you loaded more HTML and it took longer for the browser to parse your JavaScript at the end. In that case, your function won't be defined and you will get...
myFunction() is not defined
Note you need to add open and closing parenthesis (( & )) after myFunction.
Whilst functions declarations are hoisted, they are only hoisted in their containing script block.
Also, you should really use lowercase tags, it isn't 1998 anymore :) And a doctype also helps, and finally, you should try and remove your event handlers from inline attributes.
The script needs to be defined in the DOM prior to it being executed. If script is at the bottom it needs to be loaded prior to use.

Javascript problem solved, don't understand what the problem was

In the HTML head section:
<script type="text/javascript" src="Scripts/editScripts.js"></script>
Just above the </body> tag(closing tag, bottom of the html page). Also: this is the old code, this is how it was when it was not working:
<script type="text/javascript">if(document.getElementById)initialize();loadEvents();</script>
</body>
</html>
In the editScripts.js file:
/*global document,addFileInput*/
function loadEvents() {
var a = document.getElementById('addField');
a.onclick = addFileInput;
}
var upload_number = 2;
function addFileInput() {
var d = document.createElement("div");
var file = document.createElement("input");
file.setAttribute("type", "file");
file.setAttribute("name", "addFile[]");
file.setAttribute("size", "35");
file.setAttribute("class", "file");
file.setAttribute("id", "addFile"+upload_number);
d.appendChild(file);
document.getElementById("moreUploads").appendChild(d);
upload_number++;
}
This would not work. I replace the javascript in the footer with this.This is the new code, which does work as I expect it to.:
<script type="text/javascript">if (document.getElementById)loadEvents();</script>
And now it does work... I don't see how leaving out that function call, even though it the function it was referring to doesn't exist, would mess things up so royally.
In an unbracketed if statement, only the first statement is conditional. Every statement following it is unconditional regardless of indentation.
Thus, in the first example, loadevents() executed unconditionally.
The browser would have reported an error when attempting to call the "initialize" function since there was no such function. Therefore, the very next line where you call "loadEvents" wouldn't run. See this example:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>JS Error Test</title>
</head>
<body>
<script type="text/javascript">
if(document.getElementById) {
initialize();
alert("You shouldn't see me!");
}
</script>
</body>
</html>
In that example, the alert box shouldn't appear because I haven't declared an "initialize" function and the browser will report a JS error. Removing the "initialize" function, however, will cause the alert box to appear.
So that's how by removing the cause of the Javascript error you fixed your problem.
probably because you arent calling your scripts on document load event. so when you called your scripts in the header before your dom fully loaded, none of it worked, but now when you are calling it after the dom loads, it works.
The correct fix for all of this should be calling your scripts after the document fully loads, or at least from the body onload event:
<body onload="initScripts()">
And then add all of the scripts you want to run on page load in the initScripts function.
also, there are much better ways of doing this, for example using jquery, and/or reading this: http://onlinetools.org/articles/unobtrusivejavascript/chapter4.html
You say: "I don't see how leaving out that function call, even though it the function it was referring to doesn't exist, would mess things up so royally." That's inconsistent with the rest of your question, which implies that adding the call messed things up. But I think the text I'm quoting is the correct description.
Here's the real answer. The old code:
if(document.getElementById)loadEvents();
does not call loadEvents if getElementsById is not defined. It's not defined in all browsers.
The new code, instead, you not only leave out the function call: the semantics change as well.
if(document.getElementById)initialize();loadEvents();
always calls loadEvents, so what you want to happen always does.

Categories