Why does this function always return "true1" - javascript

This is a bit of a modified version of an example in the book 'Eloquent JavaScript'. Need to understand why it always returns "true1". The idea was to find a certain text in the DOM but somehow even if I give a text that does not exist in the html still get "true1" on console.
Please Help
My HTML File:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title> My first JS page</title>
<script src="script1.js"></script>
</head>
<body>
<h1>My first page</h1>
<p> Hello , I am Mehdi and this is my first page</p>
<p> And this is the second paragraph on this page and</p>
</body>
<script>console.log(talksAbout(document.body, "Tester123"));</script>
</html>
My Javascript File
function talksAbout(node, string){
if(node.nodeType == document.ELEMENT_NODE){
for(var i=0; i<node.childNodes.length; i++){
if(talksAbout(node.childNodes[i], string))
return "true1";
}
return "false1";
}else if(node.nodeType == document.TEXT_NODE){
return node.nodeValue.indexOf(string) > -1;
}
}

Your function uses the return value of the talksAbout() function as if it were a boolean value. However, the function may return a boolean or it may return one of those two string values, "true1" or "false1". Both of those will appear to be true when used in a boolean context like that if statement around the recursive call.

Pointy's answer describes one of the two key problems. The other is that your search string actually is in the document!
You include the script tag with the search string as part of the document. It will get checked as well as you walk the DOM, and so even after you fix the boolean values, you will still return true as long as you have lines like this in the document:
<script>console.log(talksAbout(document.body, "Tester123"));</script>
^^^^^^^^^
You could simply run a test from a web developers' console to see this running without such an issue.

Related

How do I remove functions from memory in Javascript after using Jquery .html() function to replace a <div> with a <script> included?

Below is an example of a problem I am having. I am using $(locator).html(data) to replace a DIV after an ajax call. The issue is that the DIV also have a SCRIPT tag inside it, and those functions in that SCRIPT tag are remaining in memory after I .empty() that DIV.
Is there a way to remove/de-register/undefine all functions in the SCRIPT tag automatically/programmatically? I guess I thought the Jquery .empty() would do that, but I guess not. I think I could do something manual like test1 = undefined but I don't want to have to explicitly do that for all the functions.
Thanks.
EDIT: I am working on a legacy product, so there are dozens of html files with dozens of functions that could be loaded for the newString variable. So my goal is not to change any of those, but to solve this lingering-function issue at the time of .empty() and .html() when replacing the div contents.
EDIT 2: And I can't just "delete" the function, because I don't always know what the function(s) will be. I need to do this programmatically. (seems I keep getting flagged as a duplicate question, but again, I can't delete what I don't know yet)
function change () {
// this newString is mock html data coming back from an ajax call
let newString = "<p>Reloaded page</p>";
console.log("#emptyme HTML before empty():")
console.log($("#emptyme").html());
$("#emptyme").empty();
console.log("#emptyme HTML AFTER empty():")
console.log($("#emptyme").html());
$("#emptyme").html(newString);
if (typeof test1 !== "undefined") {
$("#error").html("test1() WAS STILL FOUND!!");
console.log("test1() WAS STILL FOUND!! Function definition from memory is:");
console.log(test1);
}
console.log("finished change function.");
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="emptyme">
<p>
Initial page
</p>
<script>
function test1 () {
console.log("this is test1 function.");
}
</script>
</div>
<button onclick="change()">
load change
</button>
<div id="error">
</div>
</body>
</html>
JavaScrip has an internal garbage collection and your code does not have to destroy things like you would do in C++
However, at Certain times we would want to "destroy a function" where it is resources expensive
Because js runs from top to bottom you can overwrite that function if you have called it in a variable later in the program to free up those resources. Or even do it later in the logic of the program
var ExpensiveFunction =( function () {
//..code
function getRidOfthis1(){ console.log("foo1"); }
function getRidOfthis2(){ console.log("foo2"); }
function getRidOfthis3(){ console.log("foo3"); }
function getRidOfthis4(){ console.log("foo4"); }
//initiate an internal reference to them
ExpensiveFunction.getRidOfthis1 = getRidOfthis1;
ExpensiveFunction.getRidOfthis2 = getRidOfthis2;
ExpensiveFunction.getRidOfthis3 = getRidOfthis3;
ExpensiveFunction.getRidOfthis4 = getRidOfthis4;
} );
//Functions available outside of the nesting
ExpensiveFunction()
ExpensiveFunction.getRidOfthis1();
ExpensiveFunction.getRidOfthis2();
// overidding it
ExpensiveFunction =0

Properly declaring a variable

I don't know how to declare a variable here in javascript. I have an example situation that if the paragraph is equals to a, the alert will popup.
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<p id="sample">a</p>
</body>
</html>
<script type="text/javascript">
var sample = getElementById('sample');
if (sample == "a") {
alert("Correct")
};
</script>
You're declaring your variable just fine, however if you want the text within the element, you also need to use the innerHTML property. And when you use the getElementById method, you need to use it on the document object like document.getElementById:
var sample = document.getElementById('sample');
if (sample.innerHTML == "a") {
alert("Correct")
};
<p id="sample">a</p>
sample is a variable and you are correct but it is storing a reference to a DOM Element with id sample. To get the inner html of that you need
var sample = getElementById('sample').innerHTML;
Also, use === over == for no casting etc. Refer here
I will recommend you to have a quick look at JS from w3schools and then move to MDN. Nobody will report you here if you show your efforts, so relax :).
Your declaration is fine, but the assignment part is missing document as the object which has the .getElementById method. Then, once you have the reference to the element, you then need to access its content with .textContent (you can't compare the entire element to a value that the element might contain). As a side note on this, when the string you wish to set/get doesn't contain any HTML, you should use .textContent so that the browser doesn't parse the string for HTML unnecessarily. Often, people will suggest that the content of an element should be gotten/set using .innerHTML and, while that will work, it's wasteful if the string doesn't contain any HTML.
Also, the <script> must be located within the head or the body, not outside of them. I would suggest placing it just prior to the closing body tag so that by the time the processing reaches the script, all of the HTML elements have been parsed into memory and are available.
Lastly (and this is really just a side point), an HTML page also needs the title element to have something in it, otherwise it won't be valid. While browsers don't actually do HTML validation, it's important to strive for valid HTML so that you can be sure that your pages will work consistently across all devices. You can validate your HTML at: http://validator.w3.org.
<!DOCTYPE html>
<html>
<head>
<title>Something Here</title>
</head>
<body>
<p id="sample">a</p>
<script type="text/javascript">
var sample = document.getElementById('sample');
if (sample.textContent == "a") {
alert("Correct")
};
</script>
</body>
</html>

HTML will not execute JavaScript functions

I am trying to get a very simple javascript project going, but I cannot get any function to execute. Here is a simple example. It is obviously just an example. I have tried everything I can think of to get the browser to recognize that I am trying to call a function that has been defined, but it never does anything but just display the text, rather than call anything. In the below example, I simply get a page with the text: "varTimesTwo(3);"
<!DOCtype html>
<html>
<body>
<script>
function varTimesTwo(oneVar){
return (oneVar * 2)
}
</script>
varTimesTwo(3);
</body>
</html>
your code is wrong, you have to place varTimesTwo(3); inside the script tag, like this:
<!DOCtype html>
<html>
<body>
<script>
function varTimesTwo(oneVar){
return (oneVar * 2)
}
varTimesTwo(3);
</script>
</body>
</html>
Keep all JavaScript code in the script tags, or better yet, in a file
separate from the html file using <script src="myjsfile.js"></script>
You can use document.write(string) to write a string to the document.
This string is treated as HTML so you need to use <p>text</p> or <br> to get line breaks.
<!DOCtype html>
<html>
<body>
<script>
function varTimesTwo(oneVar){
return (oneVar * 2)
}
document.write("3 times two is "+varTimesTwo(3));
</script>
</body>
</html>
Alternatively, you can use window.alert(string) or simply alert(string) to pop up an alert box. But if you have turned off pop-ups in the browser, these will not pop up.
<!DOCtype html>
<html>
<body>
<script>
function varTimesTwo(oneVar){
return (oneVar * 2)
}
alert("3 times two is "+varTimesTwo(3));
</script>
</body>
</html>
console.log(string) writes to the debugging console, which you can see on many browsers with either control-shift-J or F12.
The javascript debugging console is also useful for learning javascript without messing with input and output. Anything you type in the JS console is immediately executed, so you can define functions there and play with them without having to write additional code to write the output or read input.
Finally, these techniques are insufficient for most websites as they are actually used. Instead, what is done is to define an html container element and change the text or html that is inside. jQuery provides a browser-independent method of manipulating the document to change items on the page.

Changing images periodically in JavaScript

So basically I want to change image in every 5 second, so I wrote the following Javascript code and tag it to html. But the console keep saying that "No javaScript on this page" and the code does not apply
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JavaScript for Programmers</title>
</head>
<body>
<h2>Mood Change</h2>
<p>The mood of this web page changes every 5 seconds.</p>
<p><img id="mood" src="frown.gif" alt="mood"></p>
<script async src="../scripts/moody.js"></scripts>
</body>
</html>
var images=[]
images[0]="smile.gif";
images[1]="frown.gif";
var myMood= document.getElementById("mood");
function change(){
if(myMood==images[0]){
myMood.src=images[1];
}
else if(myMood.src==imgaes[1]){
myMood.src=images[0];
}
}
setInterval(change,5000);
</scripts> should be </script>
Also your JS could look like this: http://jsbin.com/nawono/2/edit
var myMood= document.getElementById("mood");
var images=[
"smile.gif",
"frown.gif"
];
function change(){
myMood.src= images.reverse()[0];
}
setInterval(change,5000);
Ahh, to explain images.reverse()[0];, it reverses the array order and we always take out the 0 indexed key. Quite nice
The reason your code didn't work is you comparison is in appropriate. Where you have:
var images=[]
images[0]="smile.gif";
images[1]="frown.gif";
var myMood= document.getElementById("mood");
function change(){
if (myMood == images[0]) {
then myMood is a DOM element and images[0] is a string. Those two will never almost never be equal (unless the DOM element's toString methods produces exactly the same string).
You probably meant:
if (myMood.src == images[0]) {
so that you compare two strings that are more likely to be the same.

Using getElementByID.innerHTML from within a switch statements case?

Alright so first off, total Newbie here, so my questions answer might be extreemley simple because i have missed some thing critical.
I am trying to have a switch statement, switch out the innerHTML of an h1 tag with an id="bbref". I set the userName Variable to "Lister" and created my switch statement to write a different line into the h1 tag base don what name was input for userName.
for some reason however my code is just not working... any thoughts.. or noticeable brain-farts on my end?
here is the code:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Javascript Learning</title>
<script type="text/javascript">
var userName = "Lister";
switch (userName) {
case "Lister" :
document.write.getElementById("bbref").innerHTML = "Lister Is the Man!";
break;
case "Rimmer":
document.write.getElementById("bbref").innerHTML = "Rimmer is a Smeg head...";
break;
default :
doacument.write.getElementById("bbref").innerHTML = "It's all about \"The Cat\""
}
</script>
</head>
<body>
<header></header>
<section>
<article>
<h1 id="bbref">Test Title</h1>
</article>
</section>
<footer></footer>
</body>
</html>
You're messing up your functions a little there, change:
document.write.getElementById("bbref").innerHTML = "Lister Is the Man!";
to:
document.getElementById("bbref").innerHTML = "Lister Is the Man!";
And so on for the rest.
document.getElementById("bbref") will fetch the element and .innerHTML will be the HTML inside the element, changing it will directly change the visible HTML. So there's no need to write anything.
Fiddle:
http://jsfiddle.net/H4hzE/
window.onload/$(document).ready()
The other issue you would be having here is that your javascript code is executing before your HTML is rendering. Bind your code to window.onload or $(document).ready() (if using jQuery) to run the code after the page loads.
window.onload Examples:https://developer.mozilla.org/en-US/docs/DOM/window.onload
jQuery's $(document).ready():http://api.jquery.com/ready/
Fiddle (using window.onload):
http://jsfiddle.net/H4hzE/1/
Since you say you're new to JavaScript, it's probably worthwhile sharing some info regarding document.write() as I think you may have misunderstood it's functionality a little bit. :)
http://www.w3schools.com/jsref/met_doc_write.asp
http://javascript.info/tutorial/document-write
https://developer.mozilla.org/en-US/docs/DOM/document.write
document.write() and document.getElementById() are two different methods. In this case you just want to use getElementById, so omit the .write in all 3 cases, e.g.:
document.getElementById("bbref").innerHTML = "Lister Is the Man!";

Categories

Resources