I am trying to create a small javascript plugin like this:
function TextShadow(host){
this.host_id=host;
this.welcome=function(){alert('welcome to earth')};
$(function(){
this.welcome();
$(this.host_id).html("<p>hello world</p>");
});
}
I then call it from an other script like this:
var test=new TextShadow("#sample");
but i get this.welcome is not a function.However if i change the previous code to the following one everything works fine:
function TextShadow(host){
this.host_id=host;
this.welcome=function(){alert('welcome to earth')};
var gen=this;
$(function(){
gen.welcome();
$(gen.host_id).html("<p>hello world</p>");
});
}
Can someone explain me why the first piece of code doesn't work while the second does?
Because the scope changes within JavaScript functions. You can bind the function to set this to the desired value.
function TextShadow(host){
this.host_id=host;
this.welcome=function(){alert('welcome to earth')};
$(function(){
this.welcome();
$(this.host_id).html("<p>hello world</p>");
}.bind(this));
}
It is even cleaner in ES6 where you can use arrow functions:
$(() => {
this.welcome();
$(this.host_id).html("<p>hello world</p>");
});
MDN Scope
Because your this changes once you go into the anonymous function. By assigning this to something else: gen, you can still use it in a different function.
You can use bind to set this
function TextShadow(host){
this.host_id=host;
this.welcome=function(){alert('welcome to earth')};
$(function(){
this.welcome();
$(this.host_id).html("<p>hello world</p>");
}.bind(this));
}
OR
Use selfor any variable to store this and use self in place of this
function TextShadow(host){
var self=this;
self.host_id=host;
self.welcome=function(){alert('welcome to earth')};
$(function(){
self.welcome();
$(self.host_id).html("<p>hello world</p>");
});
}
In your first Function Welcome Function Can't be seeing because this Binding of the current execution context .anonymous Function is the current execution context and you try tho access function form anther context
Related
We have this tag with a javascript function in our HTML,
<select name="My_Saved_Billing" onchange="Choose_My_Saved_Billing(this.selectedIndex)" >
<option>Select</option>
<option value="1714">Address line 1, QC</option>
</select>
<script type="text/javascript">
function Choose_My_Saved_Billing(arg_index) {
switch(arg_index) {
// some commands here
}
}
</script>
And I also added a jQuery to it which is below so that on windows load, it will automatically select the second option.
<script type="text/javascript">
$(window).load(function(){
$("select").val($("select option:eq(1)").val());
});
</script>
But is it possible to call javascript function using jQuery? If so, how should I call this one?
Should I use Choose_My_Saved_Billing(this.selectedIndex)or Choose_My_Saved_Billing(arg_index)or you might know something. I've tried these two but none are working. Please let me know. Just a beginner here.
The way to call a JavaScript function from a JQuery file is the same as calling a JavaScript function from a JavaScript file :) This is so because JQuery is a library based from JavaScript. Say, you want to call function foo from a JavaScript file, when the window loads.
JQuery:
$(window).on('load', function() {
foo();
});
And JavaScript:
function foo() {
alert('This works!');
}
I hope this helps!
Yes, it's possible to call functions inside a jQuery ready block. Since you've defined the function at global scope (should probably move this into the jQuery ready block or, if you want to go to the trouble, into a module), it can be called from anywhere. So inside your ready block:
$(function () {
// do stuff
Choose_My_Saved_Billing(args);
});
jQuery is JavaScript. It's just a library for JavaScript. The main jQuery global $ is a JavaScript function that takes a valid selector as an argument and provides several methods on the return value of that function.
So calling a JavaScript function inside the callback function to .load is not an issue.
It is not clear what the Choose_My_Saved_Billing function actually does.
Think about what's happening here. In your onchange event you're calling the function with the index of the selected option passed as an argument. Since JQuery is just a library of shortcuts for things you can do in JavaScript, we should easily be able to do the same thing.
So let's get the element for which we want the selected index:
// maybe think about adding an ID here for better selection
var select = $('select[name^="My_Saved_"]');
Then let's get the index with a change event, then call the function:
var index = 0;
select.change(function(){
index = select.selectedIndex || 2; // set the index to default to 2
Choose_My_Saved_billing(index);
});
Instead of using onchange="...", just use jQuery to attach a change listener:
$(window).load(function() {
$('.colors_backgroundneutral select').on('change', function () {
Choose_My_Saved_Billing(this.value);
});
});
$(document).ready(function() {
$("#Submit1").click(function() {
$("#id1").hide();
Raise1();
});
$("#Raise").click(function() {
$("#id1").show();
});
});
function Raise1() {
var value1;
alert("hi");
value1 = document.getElementById("amount").value;
alert(value1);
alert("done");
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.1/jquery.min.js"></script>
As jQuery is a more simple and advanced JavaScript solution, my guessing is you can call you JS function like this:
$(window).load(function(){
my_js_function(arg1, arg2);
});
Now, what you want is to call the JS function named Choose_My_Saved_Billing() with argument arg_index
So, your jQuery will look like this:
$(window).load(function(){
Choose_My_Saved_Billing(arg_index);
});
This only works if the function is already declared through raw code, on via the <script type="text/javascript" src="path/to/my_file.js"> head tag.
It should work like a charm, if not, feel free to share the errors returned by your browser.
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>
I wonder if somebody could please help me understand something that seems odd with JS?
The below code works. The function inlineEditEvent.init() is called, and then t.copy() is called correctly (where var t = this;).
However, if I was to replace that with this.copy(), I get the error this.copy is not a function.
What's the difference here? Why does the below work, but not the way as described in the last paragraph? Thanks.
jQuery(function($){
$(document).ready(function(){inlineEditEvent.init();});
inlineEditEvent = {
init : function(){
var t = this;
/** Copy the row on click */
$('#the-list').on('click', '.row-actions a.single-copy', function(){
return t.copy();
});
}, // init
copy : function(){
// Do stuff here
}
} // inlineEditEvent
});
You're setting t as a context variable of this (of your init function). Once inside your click handler, this is now referring to the click handler, no longer the init function. Therefore, this.copy() is not a function.
this refers to this within the functions scope. That's why you need to set a self variable, so it's accessible within the scope of the function. Considering you're using jQuery, you could use $.proxy:
$.proxy(function(){
return this.copy();
},this)
t.copy(); appears in a different function to var t = this;. The value of this changes inside each function.
When you say var t= this; it refers to what this meant in that context. Later on when you are trying to refer to this, it is referring to a.single-copy instead since that is the new context it is in.
In and external JS file I have
$(document).ready(function() {
var example = function(){ alert("hello") }
});
and I want to call that function from my html, how would I do that?
<img src="..." ondblclick="example()" />
n.b. I'm aware of jquery dblclick() but curious about how to correctly do the above.
$(document).ready(function() {
window.example = function() {
alert("hello")
}
});
Or define it outside, if possible. It doesn't look like it has to be defined inside document ready at all.
The other solutions here will work, but structurally in your project, the best solution is to remove the event handling code from the HTML and hook up the event entirely via javascript (separate the HTML/JS). Since you already have jQuery in your project, this is very easy. To do that, all you need to do is to put some sort of identification on the image:
<img id="example" src="..." />
Then, in you can just hook up the event code in your ready() function like this
$(document).ready(function() {
$("#example").dblclick(function() {
alert("Hello");
});
});
This has the following advantages:
It creates no global variables - reducing the global namespace pollution.
It separates the HTML from the javascript which keeps all code governing the behavior in one compact spot and is usually a good thing
Using event listeners is a bit more scalable than using .ondblclick - allowing multiple different parts of code to use non-conflicting event handlers on the same object
Your function should be global (in fact, property of window object) if you want to access it from HTML. But best practice is to avoid global variables and functions, using namespace instead:
// let's publish our namespace to window object
if (!window.myNamespace){
// creating an empty global object
var myNamespace = {};
}
// and add our function to it
$(document).ready(function() {
myNamespace.example = function(){ alert("hello"); }
});
We can use it in HTML like this:
<img src="..." ondblclick="myNamespace.example()" />
The best option would be to simply define the function outside document.ready(). There is no reason defining the function within the $(document).ready() event is necessary, as if you call the function within the $(document).ready() function, the document is guarenteed to be ready.
However, you can also define the function on the global window object, like so:
$(document).ready(function() {
window.example = function(){ alert("hello") }
});
You can either move the function declaration outside of the DOM-ready handler:
function example(){ alert("hello") }
$(document).ready(function() {
// code
});
But the better solution is to keep JavaScript in your .js files and avoid the inline event handlers. Give your element an id and fetch it:
<img src="..." id="imgid" />
$(document).ready(function() {
document.getElementById("imgid").ondblclick = function(){ alert("hello") }
});
#Esailija has answered it correctly but if you want to keep it as it is then simply remove var and make it global.
var example;
$(document).ready(function() {
example = function() {
alert("hello")
}
});
If you do not put var the variable/function/object becomes global. Using var you were setting its context within document.ready function.
Here are two samples of code. The first one does not work and the second one does, though I'm completely at a loss as to why. Can someone explain this?
[I'm writing a simple game using a bit of jQuery to be played in a webkit browser (packaged with Titanium later).]
In the first example, Firebug tells me that "this.checkCloud" is not a function.
function Cloud(){
this.checkCloud = function(){
alert('test');
}
$("#"+this.cloudName).click(function(){
this.checkCloud();
});
}
...but then this works:
function Cloud(){
this.checkCloud = function(){
alert('test');
}
var _this = this;
$("#"+this.cloudName).click(function(){
_this.checkCloud();
});
}
This one works perfect.
Why does the first one not work? Is it because "this.checkCloud" is inside of the anonymous function?
in this example:
$("#"+this.cloudName).click(function(){
this.checkCloud();
});
this referrers to the element selected(jquery object).
what you can do is use private functions
var checkCloud = function(){
alert('test');
}
this way you can simply call it inside your anonymous function
$("#"+this.cloudName).click(function(){
checkCloud();
});
That is because the meaning of this can potentially change each time you create a new scope via a function. The meaning of this depends on how the function is invoked (and the rules can be insanely complicated). As you discovered, the easy solution is to create a second variable to which you save this in the scope where this has the expected/desired value, and then reuse the variable rather than this to refer to the same object in new function scopes where this could be different.
Try this:
function Cloud(){
this.checkCloud = function(){
alert('test');
}
var func = this.checkCloud;
$("#" + this.cloudName).click(function(){
func();
});
}
When you assign an even listener to an element, jQuery makes sure that this will refer to the element. But when you create the _this variable, you're creating a closure that jQuery couldn't mess with, even if it wanted to.