Passing argument to the function inside the object in Javascript - javascript

I'm quite sure this question has been asked before, but I couldn't find anything related to my case.
Here's my function
function change(prop) {
document
.querySelector("img")
.style.setProperty(`--${prop}`, `${this.value}px`);
}
spacing.onchange = change;
blur.onchange = change;
I'm struggling with passing argument to change function, because if I do spacing.onchange = change("prop") the function will be executed immediately. I want to avoid using addEventListener. So here's the question, how can I pass an argument to my function?

You can solve that by using high order function feature
function change(prop) {
return function() {
document
.querySelector("img")
.style.setProperty(`--${prop}`, `${this.value}px`);
}
}
// for example
spacing.onchange = change(/*Your prop*/);
blur.onchange = change(/*Your prop*/);

spacing.onchange = change.bind(spacing, 'prop');

Try setting the variable equal to the function definition.
spacing.onchange = function change(prop) {
document
.querySelector("img")
.style.setProperty(`--${prop}`, `${this.value}px`);
}
spacing.onchange(arg);

Try this:
function onChanges (variables,props) {
variables.forEach((variable, index) => {
variable.onChange=function(event){
return change(props[index]);
}
});
}
onChanges([spacing,blur],[prop1,prop2]);

Related

Array value as condition of if else- JS

I've been trying to understand why whenever value of the array I click, it always add the class "foo".
Example: I clicked on London (cities[1], right?) and it added the class foo.
var cities = [
document.getElementById('Paris'),
document.getElementById('London'),
document.getElementById('Berlin')
];
for (var i = 0; i < cities.length; i++) {
cities[i].onclick = test;
function test(){
if(cities[i] === cities[0]) {
el.classList.add("foo");
}
}
}
EDIT: my original answer was incorrect, this updated one is right. addEventListener returns nothing. Instead, you should use some kind of wrapper to add and remove your listeners, again so that you don't waste resources on listeners that you aren't using:
function on (element, eventName, callback) {
element.addEventListener(eventName, callback);
return function unregister () {
element.removeEventListener(callback);
}
}
function test (event) {
if (event.currentTarget===cities[0]) {
event.target.classList.add('foo');
}
}
var listenerRemovers = cities.map(function (city) {
return on(city, 'click', test);
});
Now you can remove any of these listeners by calling the corresponding function in your listenerRemovers array:
listenerRemovers.forEach(function (unRegisterFunc) { unRegisterFunc(); });
ORIGINAL WRONG ANSWER:
For what it's worth, you're probably better off using .map in a case like this, since best practice is to keep a reference to the event listeners so you can cancel them if needed.
function test (event) {
if (event.currentTarget===cities[0]) {
event.target.classList.add('foo');
}
}
var listenerHandlers = cities.map(function (city) {
return city.addEventListener('click', test);
});
This is happening because you are setting the event functions inside a loop. Each function is using the same value of i.
Try to use this instead of trying to cities[i] inside the function.
function test(){
if(this === cities[0]) {
el.classList.add("foo");
}
}
The easiest approach to achieve this functionality is to use jQuery, here is the idea:
In html tags, give those cities a common class, e.g. class="city"
$('.city').click(function(){$('.city').addClass('foo')});
jQuery saves you more time and coding efforts.
The problem is you are trying to assign a function to a DOM attribute. You are not registering a listener but modifying the DOM. If you wish to do it this way, you must assign the onclick as cities[i].onclick = 'test()'
Also, you should move the function test outside of the for loop to look like the following. The problem is the function test is being declared many times, each with a different 'i' value.
for (var i = 0; i < cities.length; i++) {
cities[i].onclick = 'test(this)';
}
function test(el){
if(cities[i] === cities[0]) {
el.classList.add("foo");
}
}

Calling a custom function in JQuery

I want to call a JavaScript function that I made after a JQuery event has been called. I defined a function called scrambleDot earlier like this var scrambleDot = new function()
{ //my code }. Here's the code that I tried to use:
$('#reveal').click(function() {
$('.cover').css({'visibility':'hidden'});
$('#under').css({'visibility':'visible'});
})
$('#conceal').click(function() {
$('scrambleDot');
})
})
You have to call it just like:
scrambleDot();
To define a function, you don't need the new operator, so you should have:
var scrambleDot = function() { //my code }
If it still throws an error, it means it was defined in other scope. To make it globally accesible, do this when defining it:
window.scrambleDot = function() { //my code }
Cheers
We have to use new keyword, only when the function is used as a constructor for new Objects. So, the definition should not use new.
var scrambleDot = function() { //my code }
If the function need not be created dynamically, I would recommend
function scrambleDot() {
...
}
To invoke the function, simply do
scrambleDot();
For that call the function instead of selecting an element as:
$('#reveal').click(function() {
$('.cover').css({'visibility':'hidden'});
$('#under').css({'visibility':'visible'});
})
$('#conceal').click(function() {
scrambleDot();
});
And also, you write functions as:
function scrambleDot () {
// your code
}
It is a better practice than the variable one.

Javascript Object Jquery callback

In an object I have a method where I want to get some information from a server(JSON format). I want to add this data to my object where the function is (By using a setter).
The problem is that this isn't my object but the jquery callback. How could/should I solve this?
function anObject() {
$.get(URL, doTheCallback);
function setExample(example) {
this.example = example;
}
function doTheCallback(data) {
this.setExample(data.results[0].example);
}
}
You can use bind:
$.get(URL,doTheCallback.bind(this));
The bind() method creates a new function that, when called, has its
this keyword set to the provided value, with a given sequence of
arguments preceding any provided when the new function is called.
Or assign your scope in a variable like:
function anObject() {
var that = this;
$.get(URL, doTheCallback);
function setExample(example) {
that.example = example;
}
function doTheCallback(data) {
that.setExample(data.results[0].example);
}
}
If you switched to $.ajax, you can use the context option.
function anObject() {
$.ajax(URL, {context: this}).done(doTheCallback);
function setExample(example) {
this.example = example;
}
function doTheCallback(data) {
this.setExample(data.results[0].example);
}
}

Uncaught typeerror: Object #<object> has no method 'method'

So here's the object 'playerTurnObj'
function playerTurnObj(set_turn) {
this.playerTurn=set_turn;
function setTurn(turnToSet) {
this.playerTurn=turnToSet;
}
function getTurn() {
return this.playerTurn;
}
}
and here is what I'm doing with it
var turn = new playerTurnObj();
turn.setTurn(1);
so I try to make the script do the setTurn() method in playerTurnObj() to save a 'turn' in a game I'm making. The problem is, it does not do the turn.setTurn(1); part because I keep getting the error above
what am I doing wrong? I searched, but I could not find an exact answer to my question.
This is not the way JavaScript works. Your "constructor" function contains inline functions that are not visible outside of the scope of playerTurnObj. So your variable turn does not have a method setTurn defined, as the error message states correctly. Probably you want something like this:
function playerTurnObj(set_turn) {
this.playerTurn=set_turn;
}
playerTurnObj.prototype = {
setTurn: function(turnToSet) {
this.playerTurn=turnToSet;
},
getTurn: function() {
return this.playerTurn;
}
};
Now your variable turn has two methods setTurn and getTurn that operate on the instance you created with new.
The setTurn and getTurn functions are private so they return undefined rather than invoking the function. You can do:
function playerTurnObj(set_turn) {
this.playerTurn=set_turn;
this.setTurn = setTurn;
this.getTurn = getTurn;
function setTurn(turnToSet) {
this.playerTurn=turnToSet;
}
function getTurn() {
return this.playerTurn;
}
}
You then have public setTurn and getTurn methods and can invoke them as follows:
var turn = new playerTurnObj();
turn.setTurn(1);
http://jsfiddle.net/Ht688/
What I make out of it is you need to return the object this in function playerTurnObj(). So your new code will look something like:
function playerTurnObj(set_turn) {
this.playerTurn=set_turn;
function setTurn(turnToSet) {
this.playerTurn=turnToSet;
}
function getTurn() {
return this.playerTurn;
}
return this;
}

javascript function modification

I am trying to write a logger object which logs messages to screen. here is my code.
http://github.com/huseyinyilmaz/javascript-logger
in every function that needs to log something, I am writing loggerstart and loggerEnd functions at start and end of my functions. But I want to run thos codes automaticalls for every function. is there a way to modify Function prototype so every function call can run automatically.
(I am not using any javascript framework.)
EDIT: Rewritten the function to make it more modular
Well, this is a creepy way to do it, but I use this way sometimes when I need overriding some functions. It works well, allows any kind of customization and easy to understand (still creepy).
However, you will need to have all your functions stored in some kind of global object. See the example for details.
function dynamic_call_params(func, fp) {
return func(fp[0],fp[1],fp[2],fp[3],fp[4],fp[5],fp[6],fp[7],fp[8],fp[9],fp[10],fp[11],fp[12],fp[13],fp[14],fp[15],fp[16],fp[17],fp[18],fp[19]);
}
function attachWrapperToFunc(object, funcName, wrapperFunction) {
object["_original_function_"+funcName] = object[funcName];
object[funcName] = function() {
return wrapperFunction(object, object["_original_function_"+funcName], funcName, arguments);
}
}
function attachWrapperToObject(object, wrapperFunction) {
for (varname in object) {
if (typeof(object[varname]) == "function") {
attachWrapperToFunc(object, varname, wrapperFunction);
}
}
}
And some usage example:
var myProgram = new Object();
myProgram.function_one = function(a,b,c,d) {
alert(a+b+c+d);
}
myProgram.function_two = function(a,b) {
alert(a*b);
}
myProgram.function_three = function(a) {
alert(a);
}
function loggerWrapperFunction(functionObject, origFunction, origFunctionName, origParams) {
alert("start: "+origFunctionName);
var result = dynamic_call_params(origFunction, origParams);
alert("end: "+origFunctionName);
return result;
}
attachWrapperToObject(myProgram,loggerWrapperFunction);
myProgram.function_one(1,2,3,4);
myProgram.function_two(2,3);
myProgram.function_three(5);
Output will be:
start,10,end,start,6,end,start,5,end
So generally it allows you to wrap each function in some object automatically with a custom written wrapper function.
You could call every function with a wrapper function.
function wrapper(callback) {
loggerstart();
callback();
loggerend();
}
And call it with wrapper(yourfunction);

Categories

Resources