I want to inject a JavaScript function into DOM and call it at a later time.
Something like this
var funcCode = 'function test() { alert("test"); }';
function callFunc(functionName){
functionName();
}
callFunc('test');
How can I do this?
Update
Contextual problem
I have actions and function in the database.
Functions are based on actions.
I retrieve both actions and functions, and show actions on UI but I need to inject the JS function for each action shown. If an action is dismissed so the function should be.
DOM functions needed
var name1 = function () {
return {
run : function() {
// code for action 1
}
}
}
var name2 = function () {
return {
run : function() {
// code for action 2
}
}
}
...
Manager for actions (and want something like this)
Manager.Use(funcName) => to call run
If you're needing to inject a function as a string into the DOM, and then execute it, you're probably doing something wrong.
That said, here's one way you could do it. I can't make a fiddle 'cos they (rightly) don't let you inject script tags into the HTML.
var funcCode = 'function test() { alert("test"); }';
$('body').append('<script type="text/javascript">'+funcCode+'</script>');
function callFunc(functionName){
eval(functionName)();
}
callFunc('test');
Note - the code above will do what you ask, but I implore you to revisit your deisgn, and look at why you're trying to do this. It's probably not right.
var dynamicCode = "var name1 = function () {return {run: function () {alert('1')}}}; var name2 = function () {return {run: function () {alert(2)}}};";
eval(dynamicCode);
function use (funcName) {
eval(funcName + "()['run']()");
}
use("name2");
Related
I am creating AngularJS Javascript application in which i have 500/600 function in a single Directive,
Many functions are Inter connected with each other,
flow starts from the On load Event,
I want to know when i run the project,
which functions are being called on Onload Event
and i want to print the same on console,
I google it but i am not able to get anything,
is there any way to find out the functions which is being executed?
Call console.trace('calling on-load') to find stack-trace on on-load function. It would be better to call trace on the last function you expect to be executed to find all other function which has been called before.
You can wrap all your functions into "log wrapper":
var self = this;
function LogWrapper(action){
return function(){
console.log(action.name);
return action.apply(self, arguments);
}
}
//usage:
function ActualFunctionInner(arg1, arg2){
//some logic
}
var ActualFunction = LogWrapper(ActualFunctionInner);
var result = ActualFunction(1, 2);//console: ActualFunctionInner
Second solution is via Proxy:
let handler = {
get(target, propKey) {
var inner = target[propKey];
return function () {
console.log(inner.name);
return inner.apply(this, arguments);
};
}
};
var loggedSelf = new Proxy(self, handler);
var result = loggedSelf.ActualFunction(1, 2);//console: ActualFunction
I have some ambiguity in Javascript callback functions.
The first code is structured as follows:
function firstFunction()
{
var message = "something";
secondFunction(message);
}
function secondFunction(message)
{
var myButton = document.getElementById("my-button");
myButton.addEventListener('click',thirdFunction(message));
}
function thirdFunction(message)
{
console.log("the messages is: "+message);
}
When I run the script above, the thirdFunction gets executed without clicking the button.
After some research, I read about the closure in Javascript. Then I changed the code to the following structure:
function firstFunction()
{
var message = "something";
secondFunction(message);
}
function secondFunction(message)
{
var myButton = document.getElementById("my-button");
myButton.addEventListener('click',thirdFunction);
}
function thirdFunction(message)
{
return function(){
console.log("the messages is: "+message);
}
}
I got the expected result. The thirdFunction is executed only when the button is clicked.
I am not sure if I my second code structure is correct? I am not sure if I'm getting the closure concept correctly as I never returned a function in conventional programming before. This is a new concept to me. Please, correct me if I'm wrong.
EDIT:
Some of the solutions suggest writing it like this:
myButton.addEventListener('click', function() { thirdFunction(message) });
For code readability, I am trying to avoid this. I prefer to place the code for the thirdFunction outside the secondFunction.
Use an anonymous function to make the closure in the correct environment:
function secondFunction(message)
{
var myButton = document.getElementById("my-button");
myButton.addEventListener('click', function() {
thirdFunction(message)
});
}
I just can't reach the function inside function using only HTML.
How to call setLayout() using only HTML or is it able to call only in Javascript?
<button onclick="customize.setLayout('b.html');">Click Please</button>
Javascript:
function customize() {
function setLayout(text) {
var selectedLayout = text;
layout += selectedLayout;
$.get(layout, function (data) {
$("#layout-grid").html(data);
});
}
}
It isn't possible to call setLayout at all.
Functions defined in other functions are scoped to that function. They can only be called by other code from within that scope.
If you want to to be able to call customize.setLayout then you must first create customize (which can be a function, but doesn't need to be) then you need to make setLayout a property of that object.
customize.setLayout = function setLayout(text) { /* yada yada */ };
Multiple ways to call a function within a function. First of all, the inner function isn't visible to the outside until you explicitly expose it Just one way would be:
function outerobj() {
this.innerfunc = function () { alert("hello world"); }
}
This defines an object but currently has no instance. You need to create one first:
var o = new outerobj();
o.innerfunc();
Another approach:
var outerobj = {
innerfunc : function () { alert("hello world"); }
};
This would define an object outerobj which can be used immediately:
outerobj.innerfunc();
if you insist to do it this way, maybe define setLayout and then call it,
something like this:
<script>
function customize(text, CallSetLayout) {
if (CallSetLayout) {
(function setLayout(text) {
//do something
alert(text);
})(text);
}
}
</script>
<button onclick="customize('sometext',true);">Click Please</button>
then you can decide if you even want to define and call setLayout from outside
Simple answer: You can't call setLayout() with this setup anywhere!
The reason being, setLayout() will not be visible outside of customize() not even from other JavaScript code because it is defined locally inside customize() so it has local scope which is only available inside customize(). Like others have mentioned there are other ways possible... (^__^)
You can return the response of setLayout() by returning it as a method of customize() and use it in your HTML like customize().setLayout('b.html'); e.g.
<button onclick="customize().setLayout('b.html');">Click Please</button>
JavaScript:
function customize() {
var setLayout = function (text) {
var selectedLayout = text;
layout += selectedLayout;
$.get(layout, function (data) {
$("#layout-grid").html(data);
});
};
return {
setLayout: setLayout
};
}
Another Approach
You can also define your main function i.e. customize as Immediately-Invoked Function Expression (IIFE). This way you can omit the parenthesis while calling its method in HTML section.
<button onclick="customize.setLayout('b.html');">Click Please</button>
JavaScript
var customize = (function () {
var setLayout = function (text) {
var selectedLayout = text;
layout += selectedLayout;
$.get(layout, function (data) {
$("#layout-grid").html(data);
});
};
return {
setLayout: setLayout
};
})();
You need to treat it as object and method
<button onclick="customize().setLayout('b.html');">Click Please</button>
Sorry I had to edit this code for more clarification
function customize() {
this.setLayout = function setLayout(text) {
var selectedLayout = text;
layout += selectedLayout;
$.get(layout, function (data) {
$("#layout-grid").html(data);
});
}
return this;
}
Just like in the PHP I need a variable variable.
I`m getting a data-type from the html and that variable is actually a function in the js code.
And I get it I need to call it.
Every time its different, so I don`t know which one exactly is.
if (e.which == 114 || e.which == 116) {
var action = $('.active').data("action");
action();
}
function testing() {
alert('yes');
}
Here the function name is testing.And the variable action is holding it.
How I`m suppose to call it ?!
I remember that there was a easy syntax for that,but I cant find it.
Thanks
You could extract the value and use eval().
<div id="something" data-action="alert('test')">SOME DIV</div>
$(document).ready(function() {
var $myObject = $("#something");
var action = $myObject.data('action');
$myObject.click(function() {
eval(action);
});
});
Try it yourself on jsfiddle
However, eval is evil
It depends on the object which holds the function. For the global scope use : window[action](). Otherwise, replace window with the name of your object : myObject[action](). However, this solution is not suitable for functions declared inside a private scope :
function f(fnName) {
function a() { alert('a') };
function b() { alert('b') };
fnName(); // error
}
In this case, you could use eval like this (⚠ keep control over inputs ⚠) :
function f(fnName) {
function a() { alert('a') };
function b() { alert('b') };
eval(fnName)();
}
Otherwise you could wrap them inside an object like so :
function f(fnName) {
var wrapper = {};
wrapper.a = function () { alert('a') };
wrapper.b = function () { alert('b') };
wrapper[fnName]();
}
f('a'); // alerts "a"
f('b'); // alerts "b"
I would like to be able to pass a parameter in a callback, but from the original calling function, and with the stipulation below, e.g. given:
function foo() {
var p = 5;
getDataFromServer(callBackFunction);
}
function callBackFunction(data) {
// I need value of 'p' here
...
}
function getDataFromServer(callback) {
// gets data from server
callback.call();
}
The catch is that I don't want to change the function getDataFromServer(), (i.e. allowing it to accept another parameter.)
Is this possible? Thanks.
Yes, and this is good to know.
function foo() {
var p = 5;
getDataFromServer(function(){
callBackFunction(p)
});
}
Yes, you could use a closure to do this.
However, it's hard to give code for this because your example isn't clear.
My guess is that you want something like this:
function foo() {
var p = 5;
getDataFromServer(callBackFunction(p));
}
function callBackFunction(p) {
var closureOverP = function(data) {... something with p ...};
return closureOverP;
}
So a simple anon function won't do?
function foo()
{
var p = 5;
getDataFromServer( function()
{
callBackFunction( p );
} );
}
It's Definitely possible and I would say good practice with functional programming languages. But you call the function like this:
function getDataFromServer(callback) {
// gets data from server
callback();
}