JavaScript: calling a function by name on hashchange - javascript

I'm trying to call a function given the function name in the hash string. I have the following code:
$(window).on('hashchange', function() {
//alert(location.hash.substring(1, location.hash.length));
window[location.hash.substring(1, location.hash.length)];
});
function test() {
alert('123!');
}
The funny thing is, when I uncomment the alert call, everything works as expected. When the alert is commented, however, it doesn't work.
Any ideas?

window[location.hash.substring(1, location.hash.length)];
doesn't call a function.
If you want to call the function whose name is location.hash.substring(1, location.hash.length), you may do
window[location.hash.substring(1, location.hash.length)]();
Side note :
location.hash.substring(1, location.hash.length)
can be shortened in
location.hash.slice(1)

Related

How do I use a function as a variable in JavaScript?

I want to be able to put the code in one place and call it from several different events.
Currently I have a selector and an event:
$("input[type='checkbox']").on('click', function () {
// code works here //
});
I use the same code elsewhere in the file, however using a different selector.
$(".product_table").on('change', '.edit_quantity', function () {
// code works here //
});
I have tried following the advice given elsewhere on StackOverflow, to simply give my function a name and then call the named function but that is not working for me. The code simply does not run.
$(".product_table").on('change', '.edit_quantity', function () {
calculateTotals() {
// code does not work //
}
});
So, I tried putting the code into it's own function separate from the event and call it inside the event, and that is not working for me as well.
calculateTotals() {
// code does not work //
}
So what am I doing wrong ?
You could pass your function as a variable.
You want to add listeners for events after the DOM has loaded, JQuery helps with $(document).ready(fn); (ref).
To fix your code:
$(document).ready(function() {
$("input[type='checkbox']").on('click', calculateTotalsEvent)
$(".product_table").on('change', '.edit_quantity', calculateTotalsEvent)
});
function calculateTotalsEvent(evt) {
//do something
alert('fired');
}
Update:
Vince asked:
This worked for me - thank you, however one question: you say, "pass your function as a variable" ... I don't see where you are doing this. Can you explain ? tks. – Vince
Response:
In JavaScript you can assign functions to variables.
You probably do this all the time when doing:
function hello() {
//
}
You define window.hello.
You are adding to Global Namespace.
JavaScript window object
This generally leads to ambiguous JavaScript architecture/spaghetti code.
I organise with a Namespace Structure.
A small example of this would be:
app.js
var app = {
controllers: {}
};
You are defining window.app (just a json object) with a key of controllers with a value of an object.
something-ctlr.js
app.controllers.somethingCtlr.eventName = function(evt) {
//evt.preventDefault?
//check origin of evt? switch? throw if no evt? test using instanceof?
alert('hi');
}
You are defining a new key on the previously defined app.controllers.somethingCtlrcalled eventName.
You can invoke the function with ();.
app.controllers.somethingCtlr.eventName();
This will go to the key in the object, and then invoke it.
You can pass the function as a variable like so.
anotherFunction(app.controllers.somethingCtlr.eventName);
You can then invoke it in the function like so
function anotherFunction(someFn) { someFn();}
The javascript files would be structured like so:
+-html
+-stylesheets
+-javascript-+
+-app-+
+-app.js
+-controllers-+
+-something-ctlr.js
Invoke via chrome developer tools with:
app.controllers.somethingCtlr.eventName();
You can pass it as a variable like so:
$(document).ready(function() {
$('button').click(app.controllers.somethingCtlr.eventName);
});
JQuery (ref).
I hope this helps,
Rhys
It looks like you were on the right track but had some incorrect syntax. No need for { } when calling a function. This code should behave properly once you add code inside of the calculateTotals function.
$(".product_table").on('change', '.edit_quantity', function () {
calculateTotals();
});
$("input[type='checkbox']").on('click',function() {
calculateTotals();
});
function calculateTotals() {
//your code...
}
You could just condense it all into a single function. The onchange event works for both the check box and the text input (no need for a click handler). And jQuery allows you to add multiple selectors.
$('input[type=checkbox], .product_table .edit_quantity').on('change', function() {
console.log('do some calculation...');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="product_table">
<input type="checkbox">
<input class="edit_quantity">
</div>

Passing a function with parameter to event handler

Let's say I have the following code:
$('#from').focus(listExpand(1));
$('#to').focus(listExpand(3));
It's not working as I expected. I think that it works wrong due to the fact that I'm passing a function result but not the function itself.
So the right syntax would be:
$('#from').focus(listExpand); // no brackets and no parameters
But in this case I can not pass any parameters to a function :(
How can I implement the subject?
Wrap the call to listExpand in a separate function definition:
$('#from').focus(function(){ listExpand(1); });
$('#to').focus(function(){ listExpand(3); })
below will work. use this.
$('#from').focus(function() {listExpand(1) });
$('#to').focus(function(){listExpand(3);})
I found other cool way also that #sudher mentioned. You can check it working in http://jsfiddle.net/kvHDA/
Sample Code
$('#from').focus({x: 1},myfunc);
function myfunc( e){
alert(e.data.x);
}
If a data argument is provided to .on() and is not null or undefined,
it is passed to the handler in the event.data property each time
an event is triggered.
$('#from').on("focus" , {id:1} , listExpand);
$('#to').on("focus" , {id:3} , listExpand);
function listExpand(event){
console.log(event.data.id);
}

Jquery and javascript namepsace

In trying to namespace my js/jquery code, I have come up against the following problem.
Basically, I used to write all my JS code in each html/php file, and I want to abstract that away to a single js file with namespaces.
So, in my html file I have:
<script type="text/javascript">
$(document).ready(productActions.init());
</script>
And in my js file I have:
var productActions = {
init: function() {
alert('initialsed');
$('#field_id').change(function() {
alert('ok!');
});
}
The productActions init function is definitely running, because I get the first alert (initialised). However, it seems that none of the jquery binding functions do anything at all. Stepping through the init function shows that the above change function is being registered, but actually changing the value in the field does absolutely nothing.
Am I missing something obvious here?
$(document).ready(productActions.init());
This code calls init() immediately and passes its return value to ready(...). (just like any other function call)
Instead, you can write
$(document).ready(productActions.init);
To pass the function itself. Howeverm this will call it with the wrong this; if you need this, write
$(document).ready(function() { productActions.init() });

Unable to re-define a function in my javascript object

I have an object defined using literal notation as follows (example code used). This is in an external script file.
if (RF == null) var RF = {};
RF.Example= {
onDoSomething: function () { alert('Original Definition');} ,
method1 : function(){ RF.Example.onDoSomething(); }
}
In my .aspx page I have the following ..
$(document).ready(function () {
RF.Example.onDoSomething = function(){ alert('New Definition'); };
RF.Example.method1();
});
When the page loads the document.ready is called but the alert('Original Definition'); is only ever shown. Can someone point me in the right direction. I basically want to redefine the onDoSomething function. Thanks, Ben.
Edit
Thanks for the comments, I can see that is working. Would it matter that method1 is actually calling another method that takes the onDoSomething() function as a callback parameter? e.g.
method1 : function(){
RF.Example2.callbackFunction(function() {RF.Example.onDoSomething();});
}
Your code as quoted should work (and does: http://jsbin.com/uguva4), so something other than what's in your question is causing this behavior. For instance, if you're using any kind of JavaScript compiler (like Closure) or minifier or something, the names may be being changed, which case you're adding a new onDoSomething when the old one has been renamed. Alternately, perhaps the alert is being triggered by something else, not what you think is triggering it. Or something else may have grabbed a reference to the old onDoSomething (elsewhere in the external script, perhaps) and be using it directly, like this: http://jsbin.com/uguva4/2.
Thanks for the response .. in the end the answer was unrelated to the code posted. Cheers for verifying I wasn't going bonkers.

Dynamically changing javascript variable

I am making an AJAX calling using JQuery. I get back a JSON object containing HTML and Javascript. Within the javascript, there is a function Initialize(). This returned javascript from the AJAX call should replace the initial definition of Initialize() which was there before the AJAX call was made. So basically, I'm trying to dynamically change the code of the javascript function to code I get back from an AJAX call. Help? Thanks in advance.
I think you might be looking for something like this:
init = function() { alert("init"); };
hash = { "newInit" : function() { alert("newInit"); }};
init(); // alerts "init"
init = hash.newInit;
init(); // alerts "newInit"

Categories