Switching backgrounds, while switching text - javascript

I was able to make the text loop infinitely and the body color change once:
<?php?>
<style type="text/css">
<!--
header{background-color:orange;}
#color1{background-color:red;}
#color2{background-color:green;}
#color3{background-color:blue;}
-->
</style>
<script type="text/javascript">
<!--
var flip = (function() {
var flip = ['_addText1','_addText2','_addText3'];
var count = -1;
return function() {
return flip[++count % flip.length];
}
}());
-->
</script>
<body id="color1">
<header onclick="document.getElementById('click').innerHTML = flip(); document.getElementById('color1').setAttribute('id', 'color2');">
<h1>StaticText<a id="click">_ThisWillChange</a></h1>
<p>Click anywhere in the header to change the text above.<br />
This will also change the body color.</p>
</header>
</body>
<?php?>
The first problem is; if I add more color changes to the 'onclick' attribute it stops working all together. Basically I want the color to loop with the text:
document.getElementById('color2').setAttribute('id', 'color3');
document.getElementById('color3').setAttribute('id', 'color1');
The second problem is that I'm not really 'fluent' in javascript. I'm actually lucky I figured out this much to be honest.
I'm sure there's a way to put it all into the javascript (to keep my HTML clean), but I don't know how.
Any help would be most appreciated! Thanks in advance...

Why do you want to change the id of the element if you are so keen to set the color.
You can just the class on the body element which should get the work done for you.
Secondly it's a bad practice to bind events inline. Use javascript to bind the events as well.
<body id="color1" class="color1">
This is one way of writing the code.
Code
var header = document.getElementsByTagName('header')[0];
header.addEventListener('click', function () {
var body = document.getElementById('color1');
document.getElementById('click').innerHTML = flip("text");
body.className = flip("color");
});
var flip = (function () {
var flip = ['_addText1', '_addText2', '_addText3'],
colors = ["color1", "color2", "color3"];
var count = -1,
colorCount = -1;
return function (arg) {
if(arg === 'text')
return flip[++count % flip.length];
if(arg === 'color')
return colors[++colorCount % colors.length];
}
})();
HTML
<body id="color1" class="color0">
<header>
<h1>StaticText<a id="click">_ThisWillChange</a></h1>
<p>Click anywhere in the header to change the text above.
<br />This will also change the body color.</p>
</header>
</body>
CSS
header {
background-color:orange;
}
.color0 {
background-color:yellow;
}
.color1 {
background-color:red;
}
.color2 {
background-color:green;
}
.color3 {
background-color:blue;
}
Check Fiddle

Related

Trouble with hover effect

to put it simply, I am trying to add a hover effect onto my cv.
I want when someone hovers over my linkedin icon, for it to display a text underneath saying "LinkedIn"
However I need this to be in Javascript.
html part <i class="icon-linkedin"></i>
<div id="popup">LinkedIn</div>
js part
var e = document.getElementById('liIcon');
e.onmouseover = function() {
document.getElementById('popup').style.display = 'block';
}
e.onmouseout = function() {
document.getElementById('popup').style.display = 'none';
}
and css part
#popup {
display:none;
}
Any idea why it isn't working?
Thanks.
I noticed a few semicolons missing after the onmouseovers. I'm not an expert on JS, but an unterminated statement looks weird.
Also, I added a LinkedIn text to the button, cause there's no image link visible in the following code. This is how your code should be structured for your code to work (assuming your browser doesn't have JavaScript disabled):
<!DOCTYPE html>
<html>
<head>
<style>
#popup {
display: none;
}
</style>
</head>
<body>
<i class="icon-linkedin">LinkedIn</i>
<div id="popup">LinkedIn</div>
<script>
var e = document.getElementById('liIcon');
e.onmouseover = function () {
document.getElementById('popup').style.display = 'block';
};
e.onmouseout = function () {
document.getElementById('popup').style.display = 'none';
};
</script>
</body>
</html>
No hover:
Hover:
Sometimes selectors can get fussy, I've run into issues with tags nested in other elements similar to what you have here.
Have you tried adding an event listener to the icon tag as well?
var icon = document.getElementById('liIcon').getElementsByClassName('icon-linkedin');
// assuming there is only one element of class: icon-linkedin, access element by index 0
icon[0].onmouseover = function () {
document.getElementById('popup').style.display = 'block';
};
icon[0].onmouseout = function () {
document.getElementById('popup').style.display = 'none';
};

Javascript code doesn't fire until the 2nd click for an html button?

I'm learning javascript, and this simple piece of code just won't work the way I need it to.
All I need is to display the main tag at the click of a button. HOWEVER, it doesn't want to display until the SECOND click.
So the first click doesn't display the main. The second click does.
I've tried moving my coding around the html document (before/after body closing tag, etc).
I've looked through stack overflow, and similar questions don't really help my case. Or at least I don't understand how they can help me as a beginner.
var aboutShow = document.getElementById("aboutLink");
aboutShow.addEventListener("click", displayMain);
function displayMain(){
var mainSection = document.getElementsByTagName("main")[0];
if (mainSection.style.display === "none"){
mainSection.style.display = "grid";
}
else{
mainSection.style.display = "none";
}
}
main{display:none;}
<main> ... </main>
<button type="button" id="aboutLink">About</button>
There has to be something I'm missing that prevents that 1st click from firing the code. I mean, it seems simple enough???
if (mainSection.style.display === "none") is looking for an inline style tag, so instead of setting display:none; in your CSS, just set it inline on the element:
var aboutShow = document.getElementById("aboutLink");
aboutShow.addEventListener("click", displayMain);
function displayMain(){
var mainSection = document.getElementsByTagName("main")[0];
if (mainSection.style.display === "none"){
mainSection.style.display = "grid";
}
else{
mainSection.style.display = "none";
}
}
<main style="display:none;"> ... </main>
<button type="button" id="aboutLink">About</button>
As has been answered, mainSection.style.display is empty. Another option is to get the computed style of the element:
var aboutShow = document.getElementById("aboutLink");
aboutShow.addEventListener("click", displayMain);
function displayMain() {
var mainSection = document.getElementsByTagName("main")[0];
if (window.getComputedStyle(mainSection).getPropertyValue('display') === "none") {
mainSection.style.display = "grid";
} else {
mainSection.style.display = "none";
}
}
main {
display: none;
}
<main> ... </main>
<button type="button" id="aboutLink">About</button>
var aboutShow = document.getElementById("aboutLink");
aboutShow.addEventListener("click", displayMain);
function displayMain(){
var mainSection = document.getElementsByTagName("main")[0];
if (mainSection.style.display || "none" === "none"){
mainSection.style.display = "grid";
}
else{
mainSection.style.display = "none";
}
}
main{display:none;}
<main>text</main>
<button type="button" id="aboutLink">About</button>
Initially mainSection.style.display is empty, so it falls on the else part of the if statement and changes the property to none.
On the second click, the property now has the value of none, that's why it works on the second click.
The HTMLElement.style property is used to get as well as set the inline style of an element.

How do I clear inner HTML

I've been fiddling with this for a while but it won't work and I can't figure out why. Please help. Here is what I have:
<html>
<head>
<title>lala</title>
</head>
<body>
<h1 onmouseover="go('The dog is in its shed')" onmouseout="clear()">lalala</h1>
<div id="goy"></div>
<script type="text/javascript">
function go(what) {
document.getElementById("goy").innerHTML = what;
}
function clear() {
document.getElementById("goy").innerHTML = "";
}
</script>
</body>
</html>
The mouseover works and displays the text in the div, but when I move the mouse out of the h1 tag, the text stays there and I don't know why, help would be appreciated.
The problem appears to be that the global symbol clear is already in use and your function doesn't succeed in overriding it. If you change that name to something else (I used blah), it works just fine:
Live: Version using clear which fails | Version using blah which works
<html>
<head>
<title>lala</title>
</head>
<body>
<h1 onmouseover="go('The dog is in its shed')" onmouseout="blah()">lalala</h1>
<div id="goy"></div>
<script type="text/javascript">
function go(what) {
document.getElementById("goy").innerHTML = what;
}
function blah() {
document.getElementById("goy").innerHTML = "";
}
</script>
</body>
</html>
This is a great illustration of the fundamental principal: Avoid global variables wherever possible. The global namespace in browsers is incredibly crowded, and when conflicts occur, you get weird bugs like this.
A corollary to that is to not use old-style onxyz=... attributes to hook up event handlers, because they require globals. Instead, at least use code to hook things up: Live Copy
<html>
<head>
<title>lala</title>
</head>
<body>
<h1 id="the-header">lalala</h1>
<div id="goy"></div>
<script type="text/javascript">
// Scoping function makes the declarations within
// it *not* globals
(function(){
var header = document.getElementById("the-header");
header.onmouseover = function() {
go('The dog is in its shed');
};
header.onmouseout = clear;
function go(what) {
document.getElementById("goy").innerHTML = what;
}
function clear() {
document.getElementById("goy").innerHTML = "";
}
})();
</script>
</body>
</html>
...and even better, use DOM2's addEventListener (or attachEvent on IE8 and earlier) so you can have multiple handlers for an event on an element.
const destroy = container => {
document.getElementById(container).innerHTML = '';
};
Faster previous
const destroyFast = container => {
const el = document.getElementById(container);
while (el.firstChild) el.removeChild(el.firstChild);
};
The h1 tags unfortunately do not receive the onmouseout events.
The simple Javascript snippet below will work for all elements and uses only 1 mouse event.
Note: "The borders in the snippet are applied to provide a visual demarcation of the elements."
document.body.onmousemove = function(){ move("The dog is in its shed"); };
document.body.style.border = "2px solid red";
document.getElementById("h1Tag").style.border = "2px solid blue";
function move(what) {
if(event.target.id == "h1Tag"){ document.getElementById("goy").innerHTML = "what"; } else { document.getElementById("goy").innerHTML = ""; }
}
<h1 id="h1Tag">lalala</h1>
<div id="goy"></div>
This can also be done in pure CSS by adding the hover selector css property to the h1 tag.
Take a look at this. a clean and simple solution using jQuery.
http://jsfiddle.net/ma2Yd/
<h1 onmouseover="go('The dog is in its shed')" onmouseout="clear()">lalala</h1>
<div id="goy"></div>
<script type="text/javascript">
$(function() {
$("h1").on('mouseover', function() {
$("#goy").text('The dog is in its shed');
}).on('mouseout', function() {
$("#goy").text("");
});
});

Call two different functions on same onclick event in javascript one after another

I have one div content whose height should be 300px when i click on another div name button.
But how can i reset the height, when again clicked on button div?
Here is the javascript code for reference:
function chk()
{
var x = document.getElementById('content').style.height = '300px';
}
This is the HTML code
<div id="content">
This is dummy text.
</div>
<div id="button" onclick="chk()">
click to read
</div>
When button div is click content height increases, but how can i reduce the height by clicking on same div with same onclick event?
Use CSS:
#content {
height: auto;
}
#content.expand {
height: 300px;
}
In your script:
function chk()
{
var node = document.getElementById('content');
node.classList.toggle('expand');
}
This keeps the state local to the element you're working on, which makes for more flexible code.
See also: classList API
You could use a flag:
var isSet = false:
function chk(){
if(!isSet) {
var x = document.getElementById('content').style.height = '300px';
isSet = true;
}
else {
// some other computation
isSet = false;
}
}
Either a flag
var flag;
function chk() {
var height = flag ? '0px' : '300px';
document.getElementById('content').style.height = height;
flag = !flag;
}
or by checking the current height
function chk() {
var currHeight = document.getElementById('content').style.height;
var setHeight = height == '300px' ? '0px' : '300px';
document.getElementById('content').style.height = setHeight;
}
If you are just learning HTML, CSS, and JavaScript you should start by making your code more clear.
// HTML should look more like
<!DOCTYPE html>
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
<head>
<meta http-equiv='content-type' content='text/html;charset=utf-8' />
<style type='text/css'>
#import 'common.css'; #import 'page.css';
</style>
</head>
<body>
<div id='content'>
This is dummy text.
</div>
<input type='button' value='click to read' id='button' />
<script type='text/javascript' src='common.js'></script>
<script type='text/javascript' src='page.js'></script>
</body>
</html>
Notice, your button should be a button, not a div. XHTML is more expandable for scraping and XSLT, and will work on HTML pages, but not the other way around.
// learn to keep your JavaScript separate pages for caching - common.js
//<![CDATA[
// reduce objects to smaller variables and never use `document.getElementById()`
var doc = document, bod = doc.body;
function E(e){
return doc.getElementById(e);
}
//]]>
// page.js
//<![CDATA[
var button = E('button');
/* The self-executing Anonymous Function below creates scope for `var test` and
returns an unexecuted function you can call later. Note that a function is
basically a variable that if you add `()` to will execute. */
var changeHeight = (function(){
var test = false;
return function(id, before, after){
E(id).style.height = test ? before : after;
test = !test;
}
})();
/* This is a backward compatible way of creating an `onclick` function, unlike
`.addEventListener()` and `attachEvent()`, this is assignment, so it will
write over your last `onclick` assiged to this specific Element */
button.onclick = function(){
changeHeight('content', '20px', '300px');
}
// To combat the comment above you could do something like this:
/*
button.onclick = function(){
changeHeight('content', '20px', '300px');
}
function anotherFunction(){
console.log('wow');
}
var before = button.onclick;
button.onclick = function(){
if(before)before();
anotherFunction();
}
*/
/* An executed function, would execute before the event is handled. The only
thing that is automatically passed to your variable function or Anonymous
Function is the Event Object. In this case it is not necessary, because we
are not accessing the Event Object. */
//]]>

Set entire page's css on click?

Does anyone know how I can change the entire document's CSS file on click? I've searched around but only found a few results on setting a class/ID's CSS, not the entire document. My website has two themes, light/dark, and I want to load up "light.css" or "dark.css" from two links.
Thanks.
You need to change the src of the the link tag, which controls the styles. For example, you probably have this in your head tag:
<link rel="stylesheet" href="light.css">
You need to change the href attribute of the link tag to "dark.css" when you click something. You can do that like this:
document.getElementById('id-of-element').addEventListener('click',function(){
document.getElementsByTagName('link')[0].setAttribute('href',isDark?'light.css':'dark.css');
isDark=isDark?false:true;
}
IMPORTANT: you need to set isDark to false or true before this code, depending on whether the page is supposed to be dark or light in the beginning. You also need to change id-of-element to the id of the element that should be clicked to toggle the state of the page.
I think this is better than the other answers because it is simpler and uses no jquery.
EDIT: I accidentally had the src attribute instead of the href one before. I now updated it to be correct.
Yeah, you can do using theming. But the changing of CSS is limited to the <body> tag.
$("a.theme").click(function(){
$("body").addClass("dark");
});
I have used jQuery library to make the coding easier. And it is not a good idea to switch CSS rather, you can change the classes.
Demo
You can check out the working demo in jsBin.
Check out this answer for more details: Selecting a web page look and feel without reloading, with one CSS.
Try something like this:
Light
Dark
<script type="text/javascript" charset="utf-8">
$('a#light, a#dark').click(function(){
$('style').remove();
$.ajax({
url:'http://www.example.com/' + $this.attr('id') + '.css',
success:function(data){
$('<style></style>').appendTo('head').html(data);
}
})
})
</script>
Of course, you need to load jQuery first.
There's 2 ways that come immediately to mind.
1) Add a style tag to the page's head, ensuring that the style tag has a unique id. You can then set the innerHTML of that element. (somewhat messy)
2) Add a link tag to the page's head, also ensuring that it has a unique id. You set the type='text/css' and the rel='stylesheet' attributes. You the set the src of this link element to the appropriate css file.
Here's an example of each type. Just supply css files for theme3() and theme4() functions.
Example:
<!DOCTYPE html>
<html>
<head>
<script>
function byId(e){return document.getElementById(e);}
function newEl(tag){return document.createElement(tag);}
function newTxt(txt){return document.createTextNode(txt);}
function toggleClass(element, newStr)
{
index=element.className.indexOf(newStr);
if ( index == -1)
element.className += ' '+newStr;
else
{
if (index != 0)
newStr = ' '+newStr;
element.className = element.className.replace(newStr, '');
}
}
function forEachNode(nodeList, func)
{
var i, n = nodeList.length;
for (i=0; i<n; i++)
{
func(nodeList[i], i, nodeList);
}
}
window.addEventListener('load', mInit, false);
function mInit()
{
var style = newEl('style');
style.setAttribute('id', 'dynCss');
document.head.appendChild(style);
var style2 = newEl('link');
style2.setAttribute('type', 'text/css');
style2.setAttribute('rel', 'stylesheet');
style2.setAttribute('id', 'dynCss2');
document.head.appendChild(style2);
}
function theme1()
{
var style = byId('dynCss');
style.innerHTML = "h1{color: red;}";
var style2 = byId('dynCss2');
style2.setAttribute('href', '');
}
function theme2()
{
var style = byId('dynCss');
style.innerHTML = "h1{color: blue;}";
var style2 = byId('dynCss2');
style2.setAttribute('href', '');
}
function theme3()
{
var style = byId('dynCss');
style.innerHTML = "";
var style2 = byId('dynCss2');
style2.setAttribute('href', 'style3.css');
}
function theme4()
{
var style = byId('dynCss');
style.innerHTML = "";
var style2 = byId('dynCss2');
style2.setAttribute('href', 'style4.css');
}
</script>
<style>
</style>
</head>
<body>
<h1>This is the heading</h1>
<input type='button' onclick='theme1();' value='Theme 1'/>
<input type='button' onclick='theme2();' value='Theme 2'/>
<input type='button' onclick='theme3();' value='Theme 3'/>
<input type='button' onclick='theme4();' value='Theme 4'/>
</body>
</html>

Categories

Resources