Javascript: Return original innerHTML on mouseout - javascript

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", "");
}

Related

JavaScript: Toggling Between 2 Images Not Working, Using setInterval

New to JS. I am trying to toggle between showing two images, dragon.svg, and dragon1.svg, every 1 second starting on page load, and running indefinitely. However, my image only changes once, and then keeps running every second but not following the rules of my if/else statement.
My suspicion is that the function is not changing the value of a global variable called dragonDiv each time it runs, so each time it runs, it is using the original value of the dragonDiv variable.
On the HTML, I have a div with the image inside, like this:
<body onload="changeDragon();">
<div id="dragonarea">
<img src="images/dragon.svg"/>
</div>
</body>
And then I have this JS, which should change the image to dragon1.svg if it is currently dragon.svg, and vice versa, every 1 second.
function changeDragon() {
changeInterval = setInterval(dragonColorChange, 1000);
}
let dragonDiv = document.getElementById('dragonarea');
console.log(dragonDiv.innerHTML); // Correctly logs <img src="images/dragon.svg"/>
function dragonColorChange() {
if (dragonDiv.innerHTML = '<img src="images/dragon.svg">') {
dragonDiv.innerHTML = '<img src="images/dragon1.svg">';
console.log(dragonDiv.innerHTML) // Correctly logs <img src="images/dragon1.svg"/>
} else {
dragonDiv.innerHTML = '<img src="images/dragon.svg">';
console.log(dragonDiv.innerHTML) // Never makes it to this point
}
}
As noted above, the console log tells me that it is correctly changing the image the first time, but after that, it seems like it is again taking the original value of dragonDiv (with the dragon.svg image) and running the function on that innerHTML again (so changing it to dragon1.svg again), rather than updating the innerHTML after running the function once as I'm telling it to do and forcing it to the else statement.
I tried putting the dragonDiv variable inside the dragonColorChange function as well as outside as a global variable. I tried using document.getElementById('dragonarea').src instead of replacing the entire innerHTML of the div tag. I tried using === instead of just =. I tried various other things for about 4 hours and I can't figure out how to get it to keep looping through the if/else statements.
Any mistakes I'm making in my code?
Apart from the typo (= is assignment, == or == is comparison) you have several improvements you can make
Use addEventListener
Change src, not innerHTML, waste of DOM rendering
I suggest a data-attribute
let changeInterval;
let dragonImage;
window.addEventListener("load", function() {
dragonImage = document.getElementById("dragonImage");
changeInterval = setInterval(dragonColorChange, 1000);
})
function dragonColorChange() {
const toggle = dragonImage.dataset.toggle
const src = toggle === "0" ? "images/dragon1.svg" : "images/dragon.svg";
dragonImage.src = src;
dragonImage.dataset.toggle = toggle === "0" ? "1" : "0";
}
<div id="dragonarea">
<img id="dragonImage" data-toggle="0" src="images/dragon.svg" />
</div>
Typo I guess, use === or == for comparison.
Also, onload function on body had different quotes [”] (when I copied and pasted on jsfiddle, it didn't work) instead of ["]
function changeDragon() {
changeInterval = setInterval(dragonColorChange, 1000);
}
let dragonDiv = document.getElementById('dragonarea');
/* console.log(dragonDiv.innerHTML); // Correctly logs <img src="images/dragon.svg"/> */
function dragonColorChange() {
if (dragonDiv.innerHTML === '<img src="images/dragon.svg">') {
dragonDiv.innerHTML = '<img src="images/dragon1.svg">';
console.log(dragonDiv.innerHTML) // Correctly logs <img src="images/dragon1.svg"/>
} else {
dragonDiv.innerHTML = '<img src="images/dragon.svg">';
console.log(dragonDiv.innerHTML) // Never makes it to this point
}
}
<body onload="changeDragon();">
<div id="dragonarea">
<img src="images/dragon.svg" />
</div>
</body>
Here I compare and change the image.src directly, instead of the div's innerHTML, as others have suggested already.
HTML:
<body onload="changeDragon();">
<div id="dragonarea">
<img id="dragon-image" src="images/dragon.svg"/>
</div>
</body>
JavaScript:
function changeDragon() {
changeInterval = setInterval(dragonColorChange, 1000);
}
let dragonImage = document.getElementById('dragon-image');
function dragonColorChange() {
if (dragonImage.src === 'images/dragon.svg') {
dragonImage.src = 'images/dragon1.svg';
} else {
dragonImage.src = 'images/dragon.svg';
}
}
As others have said you need the ===.
Here's one way to do it and keep the variable scoped to the function. I'm using .getAttribute("src") instead of just .src since it gets the relative url path.
Note that dragonColorChange isn't being passed into setInterval. It's the function returned by calling dragonColorChange.
const changeDragon = function () {
changeInterval = setInterval(dragonColorChange(), 1000);
};
function dragonColorChange() {
let dragonImg = document.querySelector('#dragonarea img');
return function () {
dragonImg.src = dragonImg.getAttribute("src") === "images/dragon.svg" ? "images/dragon1.svg" : "images/dragon.svg";
}
}
In the if condition there is a typo. Instead of comparison with == or === there is assignment operator which will assign rather than compare. Try changing that to comparison.

Extract innerHTML from a Javascript function

I apologise in advance if this has already been asked, but I couldn't find it. If it has, please direct me to the page and I won't bother you.
I've used a Javascript function to extract inner HTML. I'm able to console.log this, but I'd like to insert it in a new node/part of the HTML.
For example:
<h2>Example text id="article"</h2>
<p>'insert javascript text'</p>
<p>example</p>
<p>example</p>
<p>example id="pToExtract"</p> <--! this is the text i'd like to extract. I would like to feature it higher up in the html page, as well as here. -->
this is the function i've used to extract the text:
function printFirstLine(elem) {
let firstLine = document.getElementById(elem);
console.log(firstLine.innerHTML)
}
printFirstLine ("pToExtract")// this works. i can see the text in the console
the function i've used to place it where i'd like is:
let newText = '';
let menu = document.getElementById ('article');
let li = document.createElement('p');
li.textContent= newText;
menu.insertBefore(li, menu.firstElementChild.nextSibling);
this sort of works if i put text/a string on 'newText', and if I put the function name there it just returns the function, ie function () {} etc.
is there anyway to return the actual value/innerHTML of the function to say a new variable, so i can use it in the place of newtext or another way to accomplish this.
thank you
Not sure if I understand your question correctly but are you looking for this?
function printFirstLine(elem) {
const firstLine = document.getElementById(elem);
return firstLine.innerHTML; // here return the value
}
const newText = printFirstLine( 'pToExtract' );
Also I think you meant to write this:
<p id="pToExtract">example</p>
Instead of this:
<p>example id="pToExtract"</p>

How to set a JS variable from a CSS style

I've made a bunch of JavaScript functions to show, hide and populate various elements on a zooming menu. All seem to working except for one which I need the function to only run if a CSS setting is a specific value (width of 195%). I am very new to JavaScript so there may be more than one issue here.
<script>
function zoomShowF2() {
var widthNow = document.getElementById('svg1').style.width;
if widthNow = '195%' {
document.getElementById('zoomTitle').style.display = 'flex';
else
document.getElementById('zoomTitle').style.display = 'none';
}}</script>
You need to use comparison operators write the if statement as follows
if (widthNow == '195%') {
as the single = is assigning the value not comparing it
There are a few issues with your syntax:
function zoomShowF2() {
var widthNow = document.getElementById('svg1').style.width;
if (widthNow === '195%') {
document.getElementById('zoomTitle').style.display = 'flex';
} else {
document.getElementById('zoomTitle').style.display = 'none';
}
}
Thanks everyone. It works now with a combination of the changes suggested. I assume my curly braces are all in 'tidy' positions?
EDIT. I've adjusted the curly brace positions to as per Ed's layout.
Thanks all!
Your code does not called when the element changes it size or width. You must put all your code inside window.onresize event.
var displayOutput = document.getElementById("display-option");
function reportWindowSize() {
displayOutput.text = document.getElementById("element-to-check").style.width;
}
window.onresize = reportWindowSize;
<p id="element-to-check">Resize the browser window to fire the <code>resize</code> event.</p>
<p>Display: <span id="display-option"></span></p>

Class model for html backend [duplicate]

I'm working on a flexible menu, that does not need to jump from page to page when clicking 'links'.
The JavaScript I use for that is as follows:
var inbox = document.getElementById("u-content-inbox");
var friends = document.getElementById("u-content-friends");
var agenda = document.getElementById("u-content-agenda");
var list = document.getElementById("u-content-list");
var news = document.getElementById("u-content-news");
var notes = document.getElementById("u-content-notes");
function Inbox() {
inbox.style.visibility='visible';
}
function Friends() {
friends.style.visibility='visible';
}
function Agenda() {
agenda.style.visibility='visible';
}
function List() {
list.style.visibility='visible';
}
function News() {
news.style.visibility='visible';
}
function Notes() {
notes.style.visibility='visible';
}
The div elements are like this:
<div id="u-content-inbox" style="visibility:hidden;">
Inbox
</div>
<div id="u-content-friends" style="visibility:hidden;">
Friends
</div>
Each div has a "u-content-x".
However, when I try to change the style attribute "visibility" to visible. It gives me the following error: Uncaught TypeError: Cannot read property 'style' of null
I'm not seeing what I'm doing wrong. Could somebody please bring clearance to me why exactly JavaScript, or rather, I fail to make it work?
Whenever I run a check on
if(!inbox) {
alert("Inbox div has not been found);
}
does not show the alert message.
Make sure you call your javascript after the document is loaded! I'm nearly certain you are trying to get element references before they exist in the dom. The best practices is to put all scripts just before the closing of the body tag.
<script src="some/path/to/file.js"></script>
</body>
If your scripts appear in the document before the elements do, you can put your code inside of this load event function:
window.addEventListener('load', function() {
//your code here
});
Just as a note on your code architecture, you could attach a class to each element and then do this:
var toMakeVisible = document.getElementsByClassName('some-class');
for (var i=0; i<toMakeVisible; ++i) {
var elem = toMakeVisible[i];
elem.style.visibility = 'visible';
}

Passing a variable into a DOM function in Javascript

I took this example from w3schools and modify it to this. The code below is not working.
What I intend to do is hide the div with id "demo1". It is not working. What is the problem?
<!DOCTYPE html>
<html>
<head>
<script>
function myFunction(div_id)
{
//here the div_id variable seems to unparsable by the DOM event
document.getElementById(div_id).innerHTML = hello;
}
</script>
</head>
<body>
<p>Click the button to trigger a function.</p>
<button onclick="myFunction('demo1')">Click me</button>
<div id="demo1"></div>
<div id="demo2"></div>
</body>
</html>
The variable hello is not defined. You were probably looking to set the innerHTML as a String:
function myFunction(div_id) {
document.getElementById(div_id).innerHTML = "hello";
// -----------------------------------------^-----^
}
DEMO: http://jsfiddle.net/uzuKp/1/
Even though you took an example from W3Schools and modified it, I'd suggest binding events separate from the HTML and storing associated data in data-* attributes. In your example, it can be as something like this:
<p>Click the button to trigger a function.</p>
<button data-div-id="demo1">Click me</button>
<button data-div-id="demo2">Click me</button>
<button data-div-id="demo1">Click me</button>
<div id="demo1">demo1</div>
<div id="demo2">demo2</div>
And the JS:
function clickHandler() {
var targetDivId, targetDiv;
targetDivId = this.getAttribute("data-div-id");
targetDiv = document.getElementById(targetDivId);
targetDiv.innerHTML = "Hello" + new Date().getTime();
}
function loadHandler() {
var buttons, i, j, cur;
buttons = document.getElementsByTagName("button");
for (i = 0, j = buttons.length; i < j; i++) {
cur = buttons[i];
cur.onclick = clickHandler;
}
}
window.onload = loadHandler;
DEMO: http://jsfiddle.net/3K4RD/
Although I would also suggest looking at the following article to see different ways to bind events: addEventListener vs onclick
One final suggestion I have is to not set the innerHTML property. You may have a simple example here, but it's usually a better idea to use DOM methods like appendChild (to add a node) and document.createTextNode (to create text that can be appended). Of course, that would require the contents to be cleared out first, something like:
while (targetDiv.firstChild) {
targetDiv.removeChild(targetDiv.firstChild);
}
targetDiv.appendChild(document.createTextNode("Hello"));
DEMO: http://jsfiddle.net/52Kwe/
You could also store the specific string that needs to be set as the innerHTML as a data-* attribute (especially if it differs between buttons).
UPDATE:
Per your recent edit, the style property is a special property, which is actually a special object with style properties that you need to set. So for your example, you have to set the .style.display value, like:
document.getElementById(div_id).style.display = "none";
document.getElementById(div_id).style.display = 'none';
document.getElementById(div_id).style.visibility= 'hidden';

Categories

Resources