See the code below:
var text=["yuppie", "kkkoseh", "watchdog"];
var messageIndex=0;
function looptext (){
var MessageElement= document.getElementById("happy").innerHTML
var Message=text[messageIndex];
MessageElement=Message;
messageIndex++;
if(messageIndex>=text.length){
messageIndex=0;
}
}
window.onload = function() {
setInterval(looptext, 1000);
};
It doesn't work.
But when I remove .innerhtml at variable MessageElement and set the MessageElement.innerHtml= Message , it works.
Why is it so?
Sorry, I am a newbie learning JavaScript.
Because that's how variables and values work in JavaScript. Imagine variables to be like containers. With
var MessageElement = document.getElementById("happy").innerHTML
the container MessageElement will contain a string. Later on, with
MessageElement = Message;
you simply put a new value in the container, overwriting the previous value/content the container had. But it doesn't have any effect on the location where the previous value was coming from.
But when I remove .innerhtml at variable MessageElement and set the MessageElement.innerHtml= Message , it works.
Now the variable contains a reference to the DOM element and
MessageElement.innerHtml = Message
doesn't assign a new value to the variable (doesn't put a new value in the container), it uses the value of the variable (container).
innerHTML return a string not e pointer to the document.getElementById("happy")'s text node.
try this
var text=["yuppie", "kkkoseh", "watchdog"];
var messageIndex=0;
function looptext (){
document.getElementById("happy").innerHTML = text[messageIndex];
messageIndex++;
if(messageIndex>=text.length){
messageIndex=0;
}
}
window.onload = function() {
setInterval(looptext, 1000);
};
#Felix King is correct.
To test how it is actually behaving I myself tried the below snippet on W3Schools.
And I found:
var MessageElement = document.getElementById("happy") - assigns the element (in my example - http://www.microsoft.com/)
alert(m) thus displays - http://www.microsoft.com/
m.innerHTML = "Atul" - assigns Atul to the element.
However, value of m was still http://www.microsoft.com/ as Felix rightly said - 'MessageElement.innerHtml = Message, doesn't assign a new value to the variable'.
<html>
<head>
<script>
function changeLink()
{
var m = document.getElementById("myAnchor"); //assigns http://www.microsoft.com/
alert(m); //
m.innerHTML = "Atul"
alert(document.getElementById("myAnchor").innerHTML + " new");
document.getElementById('myAnchor').innerHTML=m;
}
</script>
</head>
<body>
<a id="myAnchor" href="http://www.microsoft.com">Microsoft</a>
<input type="button" onclick="changeLink()" value="Change link">
</body>
</html>
Thanks Felix :)
Related
I would like to increase the font size of the paragraph as well as the font size of the number in the button.
I copied and pasted my sizer function from StackOverflow (a few alterations) and thought it would work and still can't get it to work. Can someone help?
Since I've spent so much time on just the first part, as a beginner programmer, I'm wondering what I am missing. Does anyone have any ideas from my code or their experience as to what I might be missing?
Thanks as always.
<html>
<button onclick='incrementer(); sizer()' id='count' value=0 />0</button>
<p id='test'>a</p>
<script>
clicks = 0
incrementer = function () {
clicks += 1
click = document.querySelector("#count").textContent = clicks;
click.innerHTML = document.getElementById("count").value = document.getElementById('test');
}
sizer = function changeFontSize() {
div = document.getElementById("test");
currentFont = div.style.fontSize.replace("pt", "");
div.style.fontSize = parseInt(currentFont) + parseInt(clicks) + "pt";
}
</script>
</html>
Some things here:
I woudn't append two functions to your onclick here. Just append one and call your second function from the first one that gets fired via onclick. That looks a lot more tidy
Don't forget to put var before every variable, without it's not valid JavaScript
I didn't quite understand what you tried with your currentFont variable, so I removed it. It's not necessary and causes the script to not working correctly
<html>
<button onclick='incrementer()' id='count' value=0 />0</button>
<p id='test'>a</p>
<script>
var clicks = 0;
var incrementer = function() {
clicks += 1;
var click = document.querySelector("#count").textContent = clicks;
click.innerHTML = document.getElementById("count").value = document.getElementById('test');
sizer();
}
var sizer = function changeFontSize() {
var div = document.getElementById("test");
div.style.fontSize = parseInt(clicks) + "pt";
}
</script>
</html>
Here's a from-scratch version that does what you're asking for. I'll point out a few things that I did to help you out.
https://codepen.io/anon/pen/VBPpZL?editors=1010
<html>
<body>
<button id="count">0</button>
<p id="test">
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
</p>
</body>
</html>
JS:
window.addEventListener('load', () => {
const button = document.querySelector('#count');
const paragraph = document.querySelector('#test');
const startingFontSize = window.getComputedStyle(document.body, null)
.getPropertyValue('font-size')
.slice(0, 2) * 1;
let clicks = 0;
button.addEventListener('click', () => {
clicks++;
// this is a template literal
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
const fontSize = `${startingFontSize + clicks}px`;
button.innerHTML = clicks;
button.style.fontSize = fontSize;
paragraph.style.fontSize = fontSize;
});
});
The code runs when the page is loaded, so we attach an event listener on the window object listening for the load event.
We then store references to the button and the paragraph elements. These are const variables because their values won't change. This also limits their scope to the containing function.
We get the initial font size for the body element, because in this example we aren't explicitly setting a base font in css so we're just using the one for the document. getComputedStyle is a somewhat expensive operation, and in this case we only need to get it in the beginning because it won't change, so we also store it as a const. The value is returned as a string like "16px" but we need the number, hence the slice and multiplying by one to cast the string into a number. parseInt would also do the same thing.
Notice that clicks is defined with let. This means that the variable can be changed. var still works of course, but in modern practices its best to use const and let when declaring variables. This is partly because it forces you to think about what kind of data you're working with.
We add an event listener to the button element and listen for the click event. First, we increment the clicks variable. Then we declare fontSize using a template literal which adds our new clicks count to the startingFontSize and "px" to get a string.
Finally, the innerHTML value of the button element is updated. Then we update the fontStyle property for both elements.
The issue here is that there is no initial value for the fontSize of your <p> tag so div.style.fontSize returns an empty string.
You can use window.getComputedStyle instead of div.style.fontSize and you will get the current fontSize.
There is already a post explaining this method
https://stackoverflow.com/a/15195345/7190518
You don't have an initial font-size style on your <p> tag, so it div.style.fontSize is always empty. Also, best practice is to always use var when introducing new variables in javascript.
One good trick to help debugging things like these is to use console.log() at various points, and see whats coming out in your browser console. I used console.log(div.style.fontSize) and the answer became clear.
Working below after adding <p style='font-size:12px'>a</p>:
<html>
<button style='font-size:12px;' onclick='incrementer(); sizer()' id='count' value=0 />0</button>
<p id='test' style='font-size:12px;'>a</p>
<script>
var clicks = 0
incrementer = function () {
clicks += 1
click = document.querySelector("#count").textContent = clicks;
click.innerHTML = document.getElementById("count").value = document.getElementById('test');
}
var sizer = function changeFontSize() {
var div = document.getElementById("test");
var btn = document.getElementById("count");
var newSize = parseInt(div.style.fontSize.replace("pt", "")) + parseInt(clicks);
div.style.fontSize = newSize + "pt";
btn.style.fontSize = newSize + "pt";
}
</script>
</html>
I don't understand the logic of this solution, but you can simplify it avoiding to use a lot of var (anyway always prefer let or const if you don't need to change), using a single function and writing less code.
function increment(e){
const ctrl = document.getElementById('test');
let current = parseInt(e.dataset.size);
current += 1;
e.innerHTML = current;
e.dataset.size = current;
ctrl.style.fontSize = current + 'pt';
}
<button onclick="increment(this);" data-size="20">20</button>
<p id='test' style="font-size:20pt;">A</p>
So I'm having troubles understanding what I'm doing wrong here.
The big picture I'm trying to implement is a page with an iframe that is controlled with buttons that change the source of the iframe when pressed. The buttons would be dynamically created from a data structure that I wouldn't know the size of, which means that I needed to implement it as a loop.
So far I just added a pre-populated object and tried to implement the dynamic creation of the buttons to the HTML page, but I'm unable to create the buttons.
The code I'm trying to run is
<HEAD>
<TITLE>Testing stuff</TITLE>
</HEAD>
<BODY onload="script();">
<FORM>
<H2>Dynamically add button to form.</H2>
<span id="fooBar"> </span>
</FORM>
</BODY>
<script>
var URLobj = {
url1 : "https://www.lipsum.com/",
url2 : "https://www.cnet.com/news/",
url3 : "https://stackoverflow.com/"
};
function add(name, URL) {
//Create an input type dynamically.
var element = document.createElement("BUTTON");
//Assign different attributes to the element.
element.setAttribute("type", "button");
element.setAttribute("value", URL);
element.setAttribute("name", name);
alert(name);
var foo = document.getElementById("foobar");
//Append the element in page (in span).
alert('i can reach here');
foo.appendChild(element);
alert('i can not reach here');
}
window.onload = function iterator()
{
for (var key in URLobj) {
if (URLobj.hasOwnProperty(key)) {
add(key, URLobj[key])
}
}
}
</script>
Also, does this seem like any good of an approach for this kind of a problem? (Trying to add buttons dynamically) or will my next step prove to be tricky with my current approach (making the buttons control an iframe in the page)?
The main issue here is this line:
var foo = document.getElementById("foobar");
As JS is case sensitive, it should be:
var foo = document.getElementById("fooBar");
Pay close attention to the console when debugging stuff like this. This is the error you should see with your original code:
Uncaught TypeError: Cannot read property 'appendChild' of null
Also, the element type should be input based on your usage, not button. See below.
var URLobj = {
url1: "https://www.lipsum.com/",
url2: "https://www.cnet.com/news/",
url3: "https://stackoverflow.com/"
};
function add(name, URL) {
//Create an input type dynamically.
var element = document.createElement("input");
//Assign different attributes to the element.
element.setAttribute("type", "button");
element.setAttribute("value", URL);
element.setAttribute("name", name);
var foo = document.getElementById("fooBar");
//Append the element in page (in span).
foo.appendChild(element);
}
window.onload = function iterator() {
for (var key in URLobj) {
if (URLobj.hasOwnProperty(key)) {
add(key, URLobj[key])
}
}
}
<HEAD>
<TITLE>Testing stuff</TITLE>
</HEAD>
<BODY onload="script();">
<FORM>
<H2>Dynamically add button to form.</H2>
<span id="fooBar"> </span>
</FORM>
</BODY>
Please check
var foo = document.getElementById("foobar");
To
var foo = document.getElementById("fooBar");
I am retrieving some information from an xml file ( movie information ) and I am creating dynamically some DOM elements according to each movie. I want, when I click on the test element, to get the value of the title of the movie. Right now, no matter which movie I click, it gets the title of the last movie that was introduced.
How can I get the title of each individual movie when I click on that div and not the last one introduced by the for-loop?
xmlDoc=xmlhttp.responseXML;
var x=xmlDoc.getElementsByTagName("movie");
for (i=0;i<x.length;i++)
{
var titlu = x[i].getElementsByTagName("title")[0].childNodes[0].nodeValue;
var description = x[i].getElementsByTagName("description")[0].childNodes[0].nodeValue;
var descriere = document.createElement('div');
descriere.className='expandedDescriere';
descriere.innerHTML = description;
var titlediv = document.createElement('div');
titlediv.className = 'title';
titlediv.id='title';
titlediv.innerHTML = title;
var test=document.createElement('div');
test.className='test';
test.onclick= function(){
var filmName= test.previousSibling.innerHTML;
alert(filmName);
}
placeholder.appendChild(titlediv);
placeholder.appendChild(test);
placeholder.appendChild(descriere);
}
I think your problem might be in the function you assigned to onclick:
test.onclick= function(){
var filmName= test.previousSibling.innerHTML; // <===
alert(filmName);
}
the marked line should be var filmName= this.previousSibling.innerHTML;
My guess is that the var test is hoisted out of the for loop, meaning that when the loop finished, all the onclick function are referencing the same test variable which is the last element you created.
Use this to reference the clicked element:
test.onclick = function() {
var filmName = this.previousSibling.innerHTML;
alert(filmName);
};
I am sorry for this very basic question. I am very new to javascript and learning it.
I am stuck with one easy problem-
This is what i am trying to do-
I have a header that has some innertext
<h1 id="bd" onmouseover="fun1()" onmouseout="fun2()"> sample</h1>
I am chaging innerHTML of this header on mouseover like this-
function fun1()
{
document.getElementById("bd").innerHTML="a";
}
well on mouseout i do the same but for getting original innerHTML for this header tag.
function fun2()
{
document.getElementById("bd").innerHTML=document.getElementById("bd").innerHTML;
}
But onmouseout function shows me changed innerHTML, that is a in this case.
How do i get original innerHTML sample again onmouseout?
I want this to be done in javascript.
I tried another way more
function fun1()
{
document.getElementById("bd").innerHTML="a";
}
function fun3()
{
var ds=document.getElementById("bd").innerHTML;
alert(ds);
}
function fun2()
{
document.getElementById("bd").innerHTML=fun3();
}
but it is not working also.
A very generic version would be the following:
First change your markup a bit:
<h1 id="bd" onmouseover="fun1(this)" onmouseout="fun2(this)"> sample</h1>
This way you don't need to look up your element again in your callback function. This works then for more than one element you mouse over. Then you go:
function fun1(elm) {
if (!fun1.cache) fun1.cache = {}; // extend your function with a cache
fun1.cache[elm.id] = elm.innerHTML; // write into cache -> fun1.cache.bd
elm.innerHTML = 'a';
}
function fun2(elm) {
if (fun1.cache && fun1.cache[elm.id]) { // see if cache exists and...
elm.innerHTML = fun1.cache[elm.id]; // read from it
}
}
This way you build a caching system that doesn't need an extra global variable but stays closer to your function.
The next step would be to use only one function and send the new value as a parameter. Create something like a toggle function:
<h1 id="bd" onmouseover="fun(this, 'a')" onmouseout="fun(this)"> sample</h1>
and then your function:
function fun(elm, newValue) {
if (!fun.cache) fun.cache = {};
var value = newValue || fun.cache[elm.id]; // no newValue means recover old value
fun.cache[elm.id] = elm.innerHTML; // alway save the old value
elm.innerHTML = value;
}
If you need more explanations about this and creating Objects just leave a comment to this answer and I'll come back with more details...
Good luck!!
Store the first innerHtml in a global variable ,and use this variable to backup the first innerHtml.
var oldInner = '';
function fun1()
{
oldInner = document.getElementById("bd").innerHTML;
document.getElementById("bd").innerHTML="a";
}
function fun2()
{
document.getElementById("bd").innerHTML=oldInner;
}
You'll need to store the original value somehow:
var originalInnerHTML = "";
function fun1()
{
originalInnerHTML = document.getElementById("bd").innerHTML;
document.getElementById("bd").innerHTML="a";
}
function fun2()
{
document.getElementById("bd").innerHTML=originalInnerHTML
}
Currently you just get the existing innerHTML and set it as the new innerHTML - it's always going to be the same. So this line never changes anything:
document.getElementById("bd").innerHTML=document.getElementById("bd").innerHTML;
once you have changed the innerhtml of an element, old data is gone
In order to get the old data you first need to have it store in some other place.
For ex : on mouseover you can first copy the original html to a hidden div, and upon mouseout you can again copy from the hidden div to the main div.
hope this helps.
A very easy implementation will be to have the two text you want to display in the div. so you have:
<h1 id="bd">
<span id='sample1'>sample1</span>
<span id='sample2' style='display: none'>a</span>
</h1>
var el = document.getElementById("bd");
el.onmouseover = function() {
document.getElementById("sample1").setAttribute("style", "display: none");
document.getElementById("sample2").setAttribute("style", "");
}
el.onmouseout = function() {
document.getElementById("sample2").setAttribute("style", "display: none");
document.getElementById("sample1").setAttribute("style", "");
}
I'm having problems doing this. I can't access the content area object. I need it to attach a click listener.
var oFCKeditor = new FCKeditor( editorName ) ;
oFCKeditor.BasePath = o.editorPath;
if (o.configPath) {
oFCKeditor.Config["CustomConfigurationsPath"] = o.configPath +"?" + ( new Date() * 1 ) ;
}
oFCKeditor.Width = '100%';
oFCKeditor.Height = '100%';
oFCKeditor.ReplaceTextarea();
oFCKeditor.setEnabled(true);
alert(oFCKeditor.EditorDocument);
alert(oFCKeditor.EditorWindow);
alert(FCK);
I also tried accessing there objects from different parts inside FCKEditor's code, but no luck.
What am I doing wrong? What is the usual way to do this?
Thanks
Edit: when I do this:
var oEditor = FCKeditorAPI.GetInstance(editorName) ;
alert(oEditor.EditorDocument);
after creating the editor it works, but only when I'm stepping through it with a debugger, otherwise it's undefined. So it's probably a timing issue. But where am I supposed to get that then?
http://docs.cksource.com/FCKeditor_2.x/Developers_Guide/JavaScript_API#Events
<script type="text/javascript">
var object;
function FCKeditor_OnComplete(editorInstance)
{
object = editorInstance;
}
function Display()
{
alert( object.GetHTML());
}
</script>