Getting value of a CSS element - javascript

Can anyone tell me what the problem with this snippet of JS is? I am trying to assign the value of 'container's margin-top to the m variable.
function test()
{
var e = document.getElementById('container');
var m = e.style.getPropertyValue("marginTop");
alert (m);
}
edit: the alert was meant to display the value of m

You can try using this simple function:
function test()
{
var e = document.getElementById('container');
var m = getStyle(e, "marginTop");
alert ('hi ' + m);
}
function getStyle(el,styleProp)
{
if (el.currentStyle)
var y = el.currentStyle[styleProp];
else if (window.getComputedStyle)
var y = document.defaultView.getComputedStyle(el,null).getPropertyValue(styleProp);
else
var y = el.style[styleProp];
return y;
}

Try this:
function getStyle(elment, style) {
var x = document.getElementById(element);
if (x.currentStyle) {
var y = x.currentStyle[style];
} else if (window.getComputedStyle) {
var y = document.defaultView.getComputedStyle(x, null).getPropertyValue(style);
}
return y;
}
function test() {
var m = getStyle('container', 'margin-top');
alert(m);
}
Also, be careful with your variable scope. m won't be defined outside of test().

Related

How do I make a function use a variable that was declared on another function JavaScript/jQuery

So, I have a var named inimigo that is declared in function of a setInterval() but on another function named checkcolisions I want to get the positions of the inimigo so I can check the collision with him and bala where i can get the position of bala by declaring the function after the animate as you can see. After many tries, the ckeckcolision always says inimigo is not defined". How can I get the position of inimigo and check the collision with bala's position? If you have better ways to check the collision between the two please let me know, I will really accept them. Thanks for your time.
$(document).ready(function() {
"use strict";
$(document).on('keydown', function(e) {
var kp = e.keyCode;
var carro = $("#carro");
var bala = $("#bala");
e.preventDefault();
if (kp === 37 && carro.position().left > -500) {
carro.css("left", (carro.position().left - 7) + "px");
}
if (kp === 39 && carro.position().left < 350) {
carro.css("left", (carro.position().left + 7) + "px");
}
if (kp === 32) {
bala.show();
bala.css('left', (carro.offset().left + 67) + "px");
bala.css('top', (carro.offset().top - 20) + "px");
bala.animate({
"top": "-=100px"
}, "fast", checkCollisions);
}
});
var counter2 = 0;
var j = setInterval(function() {
var inimigo = $(".inimigo").clone();
$('.jogo2').html(inimigo);
inimigo.css('left', (Math.floor(Math.random() * 200) + 550));
inimigo.css('top', "150px");
}, 2000);
function getPositions(disparo) {
var $disparo = $(disparo);
var pos = $disparo.position();
var width = $disparo.width();
var height = $disparo.height();
return [
[pos.left, pos.left + width],
[pos.top, pos.top + height]
];
}
function comparePositions(p1, p2) {
var x1 = p1[0] < p2[0] ? p1 : p2;
var x2 = p1[0] < p2[0] ? p2 : p1;
return x1[1] > x2[0] || x1[0] === x2[0] ? true : false;
}
function checkCollisions() {
var disparo = inimigo;
var pos = getPositions(disparo);
var pos2 = getPositions(this);
var horizontalMatch = comparePositions(pos[0], pos2[0]);
var verticalMatch = comparePositions(pos[1], pos2[1]);
var match = horizontalMatch && verticalMatch;
if (match) {
alert("score +1");
}
}
});
You need to declare a variable in an outer context that is accessible by both functions:
var inimigo = null;
var counter2 = 0;
var j = setInterval(function() {
inimigo = $(".inimigo").clone();
$('.jogo2').html(inimigo);
inimigo.css('left', (Math.floor(Math.random() * 200) + 550));
inimigo.css('top', "150px");
}, 2000);
You can define inimigo variable globally so that you can access it any of the function. Whenever any function will access that variable, the recently changed value will be taken in consideration.
You can have global variables. If you want to access method specific variable you can try this example e.g.`
function y(){
var x = 10;
return {
get : function(){
return x;
}
}
}
`
and you can access like
y().get();

JS Need to add value every 1.5 sec

This is my code that is unfortunately not working.
It is taking value from html (600) and then dividing it (var f = 600/20). It should start onclick button (which already has onclick function).
function enemy() {
var iFrequency = 2500;
var myInterval = 0;
var e = document.getElementById('stre').innerHTML;
var f = e / 20;
function startLoop() {
if (myInterval > 0) clearInterval(myInterval); // stop
myInterval = setInterval("doSomething()", iFrequency);
}
function doSomething() {
var label = document.getElementById('wallvalue');
label.innerHTML = parseInt(label.innerHTML) + f;
document.getElementById('wallvalue').style.color = 'red';
document.getElementById('resultr').innerHTML = f;
document.getElementById('resultr').style.color = 'red';
document.getElementById('resultrc').innerHTML = f;
document.getElementById('resultrc').style.color = 'red';
}
<BUTTON class="doit" onclick="damagec(); iFrequency+=1000; startLoop(); return false;"><b>FIGHT</b></BUTTON>
Looks like youve tried to do some inheritance, but your code is not working in any way. You may do this:
function enemy(name) { // a constructor for our enemy
this.name=name;
this.iFrequency = 2500;
this.myInterval = false;
this.el=document.createElement("div");
document.body.appendChild(this.el);
this.f = 1;
}
enemy.prototype={ //functions for all enemys
startLoop:function() {
if (this.myInterval) clearInterval(this.myInterval); // stop
this.myInterval = setInterval(this.doSomething.bind(this), this.iFrequency);
},
doSomething:function () {
this.el.innerHTML = this.name+":"+(++this.f);
this.el.style.color = 'red';
}
};
var Monster=new enemy("Monster");//create a new Enemey
var button=document.createElement("button");
button.textContent="Start Monster";
document.body.appendChild(button);
button.onclick=Monster.startLoop.bind(Monster);
I managed to get it done. Thank you all for the answers!
function enemy(){
var e=600;
var f=600/20;
document.getElementById('resultr').innerHTML = f;
document.getElementById('resultr').style.color = 'red';
document.getElementById('resultrc').innerHTML = f;
document.getElementById('resultrc').style.color = 'red';
var intervalID = window.setInterval(myCallback, 3000);
function myCallback() {
var label = document.getElementById('wallvalue');
label.innerHTML = parseInt(label.innerHTML) + f;
document.getElementById('wallvalue').style.color = 'red';
}
}

Function Call Hierarchy in JavaScript

My case it this:
function s () {
this.funcs = [];
this.funcs.addF = function (str) {
/* this will push a function to the funcs array, which uses getCoordX() and getPixelY() */
this.push (Function("pixelX", "var x = getCoordX(pixelX); var f = " + str + "; return getPixelY(f);"));
}
function getCoordX(a){
return 0;
}
function getPixelY(a){
return 0;
}
}
As you can see, in that array I'm adding functions that are created from strings, and those functions need do use getCoordX() and getPixelY(), which are in the s() object. When I try to access them it gives this error: Uncaught ReferenceError: getCoordX is not defined.
What should I do to make it work? Please help.
Edit 2
How i would use this code:
function s () {
this.funcs = [];
this.funcs.addF = function (str) {
/* this will push a function to the funcs array, which uses getCoordX() and getPixelY() */
this.push (Function("pixelX", "var x = getCoordX(pixelX); var f = " + str + "; return getPixelY(f);"));
}
this.drawCanvas = function() {
//some code goes here
this.drawGraph(c);
}
this.drawGraph = function (c) {
c.lineWidth = 2;
var cnt = 0; //count how many pixels have been rendered
for(var i = this.limitLeft; i < this.limitRight; i+= this.pixelwidth) {
for(var u = 0; u < this.funcs.length; u++) {
var f = this.funcs[u];
//some if statements go here
}
}
}
function getCoordX(a){
return 0;
}
function getPixelY(a){
return 0;
}
}
var canvas = document.createElement("canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
canvas.id = "canvas";
document.body.appendChild(canvas);
var c = new Canvas("canvas");
c.funcs.addF("2*x");
c.drawCanvas();
You might do this:
function s () {
this.funcs = [];
this.funcs.addF = function (str) {
/* this will push a function to the funcs array, which uses getCoordX() and getPixelY() */
this.push (Function("pixelX", "getCoordX", "getPixelY", "var x = getCoordX(pixelX); var f = " + str + "; return getPixelY(f);"));
}
this.drawCanvas = function() {
//some code goes here
this.drawGraph(c);
}
this.drawGraph = function (c) {
c.lineWidth = 2;
var cnt = 0; //count how many pixels have been rendered
for(var i = this.limitLeft; i < this.limitRight; i+= this.pixelwidth) {
for(var u = 0; u < this.funcs.length; u++) {
var f = this.funcs[u];
var currvalue = f(i, getCoordX, getPixelY);
var lastvalue = f(i-1, getCoordX, getPixelY);
//some if statements go here
}
}
}
function getCoordX(a){
return 0;
}
function getPixelY(a){
return 0;
}
}
var canvas = document.createElement("canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
canvas.id = "canvas";
document.body.appendChild(canvas);
var c = new Canvas("canvas");
c.funcs.addF("2*x");
c.drawCanvas();
This will do it. Hope this helps ;)
this isn't implicit in JavaScript, you must precise it.
Also don't use a string to create a function, just use
this.funcs.addF = function (str) {
var obj = this;
/* this will push a function to the funcs array, which uses getCoordX() and getPixelY() */
this.push (function(pixelX){
var x = obj.getCoordX(pixelX);
return obj.getPixelY(str);
});
}
The problem is that the Function constructor creates functions which run in the global scope. So your function can't access your getCoordX in the closure.
You could make getCoordX and getPixelY global functions:
function getCoordX(a) {
return a;
}
function getPixelY(a) {
return a;
}
function s() {
this.funcs = [];
this.funcs.addF = function (str) {
this.push(new Function("pixelX",
"var x = getCoordX(pixelX);" +
"var f = " + str + ";" +
"return getPixelY(f);"
));
};
}
var obj = new s();
obj.funcs.addF('x*3 + 5');
console.log(obj.funcs[0](1)); // 8
Alternatively, you could use the Function constructor only to evaluate str, and move the other code outside.
function s() {
this.funcs = [];
this.funcs.addF = function (str) {
var f = new Function('x', 'return ' + str);
this.push(function(pixelX) {
var x = getCoordX(pixelX);
return getPixelY(f(x));
});
};
function getCoordX(a) {
return a;
}
function getPixelY(a) {
return a;
}
}
var obj = new s();
obj.funcs.addF('x*3 + 5');
console.log(obj.funcs[0](1)); // 8
Here you have a full example with canvas:
function s() {
this.funcs = [];
this.funcs.addF = function (str) {
var f = new Function('x', 'return ' + str);
this.push(function(pixelX) {
var x = getCoordX(pixelX);
return getPixelY(f(x));
});
};
this.drawGraph = function(c) {
c.lineWidth = 2;
for(var u = 0; u < this.funcs.length; u++) {
var f = this.funcs[u];
c.beginPath();
c.moveTo(0, 200-f(0));
for(var x=1; x<400; ++x) c.lineTo(x, 200-f(x));
c.stroke();
}
};
function getCoordX(a) {
return a;
}
function getPixelY(a) {
return a;
}
}
var canvas = document.createElement("canvas");
canvas.width = 400;
canvas.height = 200;
document.body.appendChild(canvas);
var c = new s("canvas");
c.funcs.addF(".5*x");
c.funcs.addF("x + 50");
c.funcs.addF("3*x + 100");
c.drawGraph(canvas.getContext('2d'));

IFFE vs. function that returns a function

Consider the following:
var x = (function(){
var _private = 'start';
var _x = function(text){
if(text){
_private = text;
}
else{
return _private;
}
}
return _x;
})();
console.log(x()); //start
x('end');
console.log(x()); //end
var y = function(){
var _private = 'start';
var _y = function(text){
if(text){
_private = text;
}
else{
return _private;
}
}
return _y;
}
console.log(y()); //toString of function
y();//invoked function, should return _y?
y('end')
console.log(y()); //toString of function
I need some clarity as to why the y function does not behave the same as the x function after it has been invoked. Why does the y function behave differently, and what overarching concept about IFFEs am I not getting?
fiddle: http://jsfiddle.net/xmmddcgn/
In the first example:
var x = (function(){
var _private = 'start';
var _x = function(text){
if(text){
_private = text;
}
else{
return _private;
}
}
return _x;
})();
var x is the inner function since the outer function was invoked.
In the second example var y is the outer function after you invoke it like this:
var y = function () {
var _private = 'start';
var _y = function (text) {
if (text) {
_private = text;
} else {
return _private;
}
}
return _y;
}
y(); // nothing happens and nobody keep _y's ref.
var p = y(); //p is _y
console.log(p()); //start
p('end')
console.log(p()); //end
Then p will be exactly the var x above.

Anonymous self-invoking JavaScript function - returning multiple objects

If I have original function (as an example):
var x = function() { alert('tadaaa'); return 1; }
var y = function() { alert('tadaaa'); return 1; }
and I've gone ahead and made this into a self-invoking anonymous JS function, as such:
(function() {
var x = function() { alert('tadaaa'); return 1; }
var y = function() { alert('tadaaa'); return 1; }
})()
am I doing something paradoxical? I'd like to access x and y as global variables, but the self-invoking anonymous function is useful in other areas that I'm not going into detail right now - I just want to keep it.
Should I be doing something like:
var x= (function() {
var x = function() { alert('tadaaa'); return 1; }
var y = function() { alert('tadaaa'); return 1; }
// Should I be doing something like
return x
})()
or
var x= (function() {
var x = function() { alert('tadaaa'); return 1; }
return x
})()
var y = (function() {
var x = function() { alert('tadaaa'); return 1; }
return y
})()
seems somewhat redundant?
I'm not sure what the goal of al this is, but maybe you could return both functions in an object, like so:
var funcs = (function() {
var x = function() { alert('tadaaa'); return 1; };
var y = function() { alert('tadaaa'); return 1; };
return {x: x, y: y};
})();
funcs.x();
funcs.y();
This is basically what the Module Pattern is about (see for example http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth).
It's good! Depending on what you need, of course.
You can:
var x, y;
(function() {
x = function() { alert('tadaaa'); return 1; }
y = function() { alert('tadaaa'); return 1; }
})();

Categories