Returning Set of Styles - javascript

<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" type="text/css" href="practise.css"/>
<script type="text/javascript" src="practise.js"></script>
</head>
<body>
<div id="items"><p id="help">Hello World</p></div>
<script>
var para=document.getElementById('help');
var check=true;
//want to return these styles whenever mouse is clicked
function toggle(){
if(check){
para.style.color="#EEFFCC";
para.style.textAlign="center";
para.style.fontSize="1em";
}else{
para.style.color="#223311";
para.style.textAlign="center";
para.style.fontSize="4em";
}
check=!check;
}
para.onclick=toggle();
</script>
</body>
</html>
The code i want to make is that it toggles between two sets of Styles whenever mouse is licked on 'para' element. But i couldn't figure out how to return the styles to the 'para.onclick' call below the function.

Currently you are doing:
para.onclick = toggle();
which means that para.onclick will be the result of executing toggle().
What you want to do is assign toggle to para.onclick:
para.onclick = toggle;
The difference is this:
function result() {
return 2;
}
var res = result();
// res = 2
var fnRes = result;
// fnRes = function() { return 2; }

Just create a little function when you click the onClick it calls your toggle, like so para.onclick = function() {}.
var para = document.getElementById('help');
var check = true;
function toggle() {
if (check) {
para.style.color = "blue";
para.style.textAlign = "center";
para.style.fontSize = "1em";
} else {
para.style.color = "red";
para.style.textAlign = "center";
para.style.fontSize = "4em";
}
check = !check;
}
para.onclick = function() {
toggle()
};
<div id="items">
<p id="help">Hello World</p>
</div>

Related

How to make reusable button

I'm new to JavaScript and I want to create a button that, when clicked, will change the position of the object. But after clicking once, nothing else works. Below I have provided the code with the very essence of the problem, and my code where I want to apply it. Maybe someone will tell you how to make a restart button correctly, instead of constantly creating new divs.
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<style>
button {
position: relative;
}
</style>
</head>
<body>
<button>Add new position</button>
<script>
const btn = document.querySelector('button');
btn.addEventListener('click', () => {
btn.style.top = '50px';
});
</script>
</body>
</html>
MY PROJECT
const yes = document.getElementById('yes');
const no = document.getElementById('no');
const body = document.querySelector('.body');
const message = document.querySelector('.message');
const reset = document.querySelector('.panel__close')
const bodyMessage = document.querySelector('.body__message')
const randomNum = Math.floor(Math.random() *100) +1;
yes.addEventListener('click', () => {
body.innerHTML = '';
const paraLox = document.createElement('p');
paraLox.textContent = 'Congratulation, Jaba Loshara Ebaniy!';
paraLox.style.fontSize = '3rem';
paraLox.style.textAlign = 'center';
paraLox.style.fontWeight = '1000';
paraLox.style.color = 'red';
body.appendChild(paraLox);
reset.addEventListener('click', () => { // reset button
paraLox.parentNode.removeChild(paraLox);
const bodyError = document.createElement('div');
bodyError.setAttribute('class', 'body__error-image');
bodyMessage.appendChild(bodyError);
const bodyErrorImage = document.createElement('img');
bodyErrorImage.setAttribute('src', 'error.png')
bodyErrorImage.style.width = '50px';
bodyErrorImage.style.height = '50px';
bodyError.appendChild(bodyErrorImage);
const bodyText = document.createElement('div');
bodyText.setAttribute('class', 'body__text');
bodyText.textContent = 'Jaba Lox?';
bodyMessage.appendChild(bodyText);
const bodyButtons = document.createElement('div');
bodyButtons.setAttribute('class', 'body__buttons');
bodyMessage.appendChild(bodyButtons);
const bodyButton1 = document.createElement('div');
bodyButton1.setAttribute('class', 'body__button');
bodyButton1.setAttribute('id', 'yes');
bodyButton1.textContent = 'Yes';
bodyButtons.appendChild(bodyButton1);
const bodyButton = document.createElement('div');
bodyButton.setAttribute('class', 'body__button');
bodyButton.setAttribute('id', 'no');
bodyButton.textContent ='No';
bodyButtons.appendChild(bodyButton);
});
});
no.addEventListener('click', () => {
no.style.position = 'relative';
no.style.top = randomNum + 'px';
no.style.bottom = randomNum + 'px';
no.style.left = randomNum + 'px';
no.style.right = randomNum + 'px';
});
From what I understand, you want the button to keep moving down with each click. In that case, the callback currently keeps setting the distance from the top to 50px. All you need to do is have the function add 50 to the current value.
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<style>
button {
position: relative;
}
</style>
</head>
<body>
<button>Add new position</button>
<script>
const btn = document.querySelector('button');
btn.addEventListener('click', () => {
btn.style.top = ((parseInt(btn.style.top,10) || 0) + 50) + 'px';
});
</script>
</body>
</html>
Test it here
Things to note:
The value is saved as a string with a pixel suffix, i.e. "50px", so we'll use parseInt() to convert it to an int we can add to.
Before setting the style, AKA before the first click, its value is "" not 0, which doesn't work with parseInt(), hence the OR || operator.

Javascript -Automatically loop through and execute functions in an array

I am trying to loop through and execute the functions in my array however i am having trouble doing so, here is the code:
<p id="demo" >I will change colour automatically.</p>
<script>
var i = 0;
var array_of_functions = [
function first_function(){
document.getElementById("demo").style.color = "red";
},
function second_function(){
document.getElementById("demo").style.color = "blue";
},
function third_function(){
document.getElementById("demo").style.color = "green";
},
function forth_function(){
document.getElementById("demo").style.color = "white";
}
];
var time = 1000;
function change(){
for(var i=0, len=array_of_functions.length; i < len; i++){
}
window.onload = change;
</script>
Please tell me what i am doing wrong.)
You need to run the functions inside the loop using array_of_functions[i](), but if you want to put a delay between each iteration you will need to use setTimeout.
In modern JavaScript, you can use async and await to maintain the imperative style of your code. Since each of the functions in your array are almost identical, you can change the array so that it only stores what changes: the color.
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function change() {
for (const color of ['red', 'blue', 'green', 'white']) {
document.getElementById('demo').style.color = color;
await delay(1000);
}
}
window.onload = change;
<p id="demo">I will change colour automatically.</p>
You never execute your functions inside the for loop. Change
for(var i=0, len=array_of_functions.length; i < len; i++){
}
to:
for(var i=0, len=array_of_functions.length; i < len; i++){
array_of_functions[i]();
}
var i = 0;
var array_of_functions = [
function first_function(){
document.getElementById("demo").style.color = "red";
},
function second_function(){
document.getElementById("demo").style.color = "blue";
},
function third_function(){
document.getElementById("demo").style.color = "green";
},
function forth_function(){
document.getElementById("demo").style.color = "brown";
}
];
var time = 1000;
function change(){
for(var i=0, len=array_of_functions.length; i < len; i++){
array_of_functions[i]();
}
}
window.onload = change;
<p id="demo">I will change colour automatically.</p>
for(var i=0, len=array_of_functions.length; i < len; i++){
}
to:
for(var i=0, len=array_of_functions.length; i < len; i++){
array_of_functions[i]();
}
If you want a time delay of 1000ms in between each call (as indicated by the variable time), you can chain promises together using .reduce():
const array_of_functions = [
'red', 'blue', 'green', 'white'
].map(function (color) {
return function () {
document.getElementById('demo').style.color = color;
};
});
var time = 1000;
function sleep(ms) {
return function () {
return new Promise(function (resolve) {
setTimeout(resolve, ms);
});
};
}
function change() {
array_of_functions.reduce(function (promise, func) {
return promise.then(sleep(time)).then(func);
}, Promise.resolve());
}
window.onload = change;
<p id="demo">I will change colour automatically.</p>
Using ES6 arrow functions, you can simplify it to this:
const array_of_functions = [
'red', 'blue', 'green', 'white'
].map(
color => () => document.getElementById('demo').style.color = color
);
const time = 1000;
const sleep = ms => () => new Promise(resolve => {
setTimeout(resolve, ms);
});
function change() {
array_of_functions.reduce(
(promise, func) => promise.then(sleep(time)).then(func),
Promise.resolve()
);
}
window.onload = change;
<p id="demo">I will change colour automatically.</p>
Finally, using ES2017 async / await, you can further simplify it:
const array_of_functions = [
'red', 'blue', 'green', 'white'
].map(
color => () => document.getElementById('demo').style.color = color
);
const time = 1000;
const sleep = ms => new Promise(resolve => {
setTimeout(resolve, ms);
});
async function change() {
for (const func of array_of_functions) {
await sleep(time);
func();
}
}
window.onload = change;
<p id="demo">I will change colour automatically.</p>
My guess is, you're really trying to do this:
//<![CDATA[
/* external.js */
var doc, bod, htm, M, I, S, Q, rand, old = onload; // for use on other pages
onload = function(){ // load not indented to save space
if(old)old(); // change old var name if using technique on other pages
doc = document; bod = doc.body; htm = doc.documentElement;
M = function(tag){
return doc.createElement(tag);
}
I = function(id){
return doc.getElementById(id);
}
S = function(selector, within){
var w = within || doc;
return w.querySelector(selector);
}
Q = function(selector, within){
var w = within || doc;
return w.querySelectorAll(selector);
}
rand = function(array){
return array[Math.floor(Math.random()*array.length)];
}
var colors = ['red', 'green', 'blue', 'yellow', 'purple', 'orange', 'aqua'];
var demo = I('demo'), dS = demo.style;
setInterval(function(){
dS.color = rand(colors);
}, 300);
} // end load
//]]>
/* external.css */
html,body{
padding:0; margin:0;
}
body{
background:#000; overflow-y:scroll;
}
.main{
width:940px; background:#fff; padding:20px; margin:0 auto;
}
#demo{
color:purple;
}
<!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' />
<meta name='viewport' content='width=device-width' />
<title>Test Template</title>
<link type='text/css' rel='stylesheet' href='external.css' />
<script type='text/javascript' src='external.js'></script>
</head>
<body>
<div class='main'>
<p id='demo'>I will change color automatically.</p>
</div>
</body>
</html>
Change the colors Array and interval as needed.
Here is an example:
var i = 0;
var demo = document.getElementById("demo");
var array_of_colors = ["red","blue","green","white"];
var time = 1000;
window.onload = function(){
setInterval(function(){
demo.style.color = array_of_colors[i++%4];
}, time)
};
<p id="demo" >I will change colour automatically.</p>

subscribers counter in pure javascript without jquery

adding counter to my page in pure javascript by the following code:
window.onload = function () {
var subs = 663965;
setInterval(function() {
var ftr = getElementById('subscribers');
subs++;
ftr.innerHTML(subs);
}, 3000);
}
<footer id = "subscribers">663965</footer>
You forgot the document in document.getElementById('subscribers'); and also setting the text content of ftr using ftr.textContent = subs;
<html>
<head></head>
<body>
<script>
window.onload = function () {
var subs = 663965;
setInterval(function() {
var ftr = document.getElementById('subscribers');
subs++;
ftr.textContent = subs;
}, 3000);
}
</script>
<footer id="subscribers">663965</footer>
</body>
</html>

Function with if-else doesn't work properly

I made a function which should disable a button if a variable isn't greater than or equal to another one. This function is run every second on a setInterval(), and the first variable to compare is also incremented by one on the setInterval(). But, the function (evitarNegs()), isn't working properly, and the button is always disabled. Sorry that part of the code is in spanish.
Javascript:
var GmB = {cantidad: 0, perSec: 1};
function Upgrade (pb, ps) {
this.precioBase = pb;
this.perSec = ps;
this.cantidad = 0;
this.precio = pb;
}
Upgrade.prototype.comprar = function() {
GmB.cantidad = GmB.cantidad - this.precio;
GmB.perSec = GmB.perSec + this.perSec;
this.cantidad++;
document.getElementById("gmb").innerHTML = GmB.cantidad;
this.precio = Math.ceil(this.precioBase*Math.pow(1.15, this.cantidad));
evitarNegs();
};
function loop() {
GmB.cantidad = GmB.cantidad + GmB.perSec;
document.getElementById("gmb").innerHTML = GmB.cantidad;
evitarNegs();
}
var upg = new Upgrade(10, 1);
var boton1 = document.getElementById("boton1");
boton1.disabled = true;
window.setInterval(loop, 1000);
//Problematic function
function evitarNegs() {
if (!(GmB >= upg.precio)) {
boton1.disabled = true;
}else {
boton1.disabled = false;
}
}
boton1.onclick = function() {
upg.comprar();
};
HTML:
<html>
<head>
<title>Gummy Bears</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
</head>
<body>
<p id="gmb">0</p>
<button id="boton1" type="button">Upgrade 1</button>
<script src="main.js"></script>
</body>
</html>
You are comparing GmB to upg.precio, but GmB is an object. So you want
function evitarNegs() {
if (!(GmB.cantidad >= upg.precio)) {
boton1.disabled = true;
} else {
boton1.disabled = false;
}
}
However, this can be written much easier as
function evitarNegs() {
boton1.disabled = GmB.cantidad < upg.precio;
}
Fiddle: http://jsfiddle.net/4rRmp/
It seems that you are comparing an object to an integer in GmB >= upg.precio. You probably have to replace it by GmB.cantidad >= upg.precio.

Strange behaviour of included JS file in node.js

I am making a node app that is in it current state very simple, but I get an issue I can't figure out.
The generated html of my express app looks like this:
<html style="" class=" js no-touch svg inlinesvg svgclippaths no-ie8compat">
<head>
...
<script type="text/javascript" src="/javascripts/mouse.js"></script>
...
</head>
<body class="antialiased" style=""><div class="row"><div class="row">
<script>
var mouse;
var X = 0;
var Y = 0;
window.onload = function()
{
alert(Mouse());//=> undefined
mouse = Mouse();
mouse.setMouseMoveCallback(function(e){ //THIS LINE FAILS: "Cannot call method 'setMouseMoveCallback' of undefined"
X = e.x;
Y = e.y;
alert("move");
});
}
...
</html>
The include script tag in the header adds this javascript file:
function Mouse(onObject){
var mouseDown = [0, 0, 0, 0, 0, 0, 0, 0, 0],
mouseDownCount = 0;
var mouseDownCallbacks = [0, 0, 0, 0, 0, 0, 0, 0, 0];
var mouseTracer = 0;
var tracePosArray;
var target = onObject;
if(!onObject){
onObject = document;
}
onObject.onmousedown = function(evt) {
mouseDown[evt.button] = 1;
mouseDownCount--;
if(mouseDownCallbacks[evt.button] != 0){
mouseDownCallbacks[evt.button](evt);
}
}
onObject.onmouseup = function(evt) {
mouseDown[evt.button] = 0;
mouseDownCount--;
}
var mousemoveCallback;
onObject.onmousemove = function(evt){
//Tracing mouse here:
if(mouseTracer){
tracePosArray.push([evt.pageX,evt.pageY]);
}
if(mousemoveCallback){
mousemoveCallback(evt);
}
}
var mouseWheelCallback;
onObject.onmousewheel = function(evt){
if(mouseWheelCallback){
mouseWheelCallback(evt);
}
}
var mouseOverCallback;
onObject.onmouseover = function(evt){
if(mouseOverCallback){
mouseOverCallback(evt);
}
}
var mouseOutCallback;
onObject.onmouseout = function(evt){
if(mouseOutCallback){
mouseOutCallback(evt);
}
}
//TODO: There is a bug when you move the mouse out while you are pressing a button. The key is still counted as "pressed" even though you release it outside of the intended area
//NOTE: might have fixed the bug. Do some further investigation by making a smaller element.
this.anyDown = function(){
if(mouseDownCount){
for(p in mouseDown){
if(mouseDown[p]){
return true;
}
}
}
}
this.setLeftDownCallbackFunction = function(fun){
mouseDownCallbacks[0] = fun;
}
this.setRightDownCallbackFunction = function(fun){
mouseDownCallbacks[2] = fun;
}
this.setMiddleDownCallbackFunction = function(fun){
mouseDownCallbacks[4] = fun;
}
this.setSpcifiedDownCallbackFunction = function(num, fun){
mouseDownCallbacks[num] = fun;
}
this.leftDown = function(){
if(mouseDownCount){
return mouseDown[0] != 0;
}
}
this.rightDown = function(){
if(mouseDownCount){
return mouseDown[2] != 0;
}
}
this.middleDown = function(){
if(mouseDownCount){
return mouseDown[4] != 0;
}
}
this.setMouseMoveCallback = function (callback){
mousemoveCallback = callback;
}
this.setMouseWheelCallback = function (callback){
mouseWheelCallback = callback;
}
this.setMouseOverCallback = function (callback){
mouseOverCallback = callback;
}
this.setMouseOutCallback = function (callback){
mouseOutCallback = callback;
}
this.enableTracer = function(){
tracePosArray = new Array();
mouseTracer = 1;
}
this.getMouseTracerData = function() {
return tracePosArray;
}
}
So: I have assured that the JS file is loaded. But none the less I am not able to access the Mouse() method in my window.onload function in the body, it shows up as undefined. This is very strange to me because if I create a HTML file that does exactly the same thing I am able to access it.
What is going on here? Is there some magic trickery in node.js / express that disables this kind of interaction?
Additional notes:
I am using Jade as the template engine.
The "mouse.js" file works. I have used it several times before.
I am using socket.io for communication between the client and server.
Complete header:
<head><title>My awesome title</title><link rel="stylesheet" href="/stylesheets/foundation.min.css"><link rel="stylesheet" href="/stylesheets/normalize.css"><link rel="stylesheet" href="/stylesheets/style.css"><script type="text/javascript" src="/socket.io/socket.io.js"></script><style type="text/css"></style><script type="text/javascript" src="/javascripts/jquery.min.js"></script><script type="text/javascript" src="/javascripts/vendor/custom.modernizr.js"></script><script type="text/javascript" src="/javascripts/vendor/zepto.js"></script><script type="text/javascript" src="/javascripts/mouse.js"></script><meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport"><meta name="viewport" content="width=device-width"></head>
That would throw an error if the Mouse function is undefined. The reason alert shows 'undefined' is that the Mouse function doesn't return anything, hence undefined. It should be used as a constructor, as in 'new Mouse()'

Categories

Resources