I dinamically add divs with onlick event, but clicking got an error (Mozilla Firefox): "ReferenceError: myfoo is not defined". If I change onclick event to alert, it works fine, but non with mysefl written functions.
Here is jsfiddle
http://jsfiddle.net/UJ85S/5/
function myfoo(x)
{
alert(x);
}
$("#some").html('<div id="cool_div" onclick="myfoo('+"'xwe'"+');"></div>');
Can you, please, explain what is wrong?
(I understant that can assign.click event, but is it possible through onclick?).
What you really need to do is not let jsFiddle wrap it inside the onload event as this uses a function which creates new scope. Your function is then not accessible outside this new scope. Learn what's happening not learn how to get around it (i.e. not just hack your code to the window Object):
http://jsfiddle.net/UJ85S/12/
No wrap - in <body>
This is happening because you define myfoo inside of $(window).load(function () {...}) function (JSFIDDLE does this):
You need to declare a global function. You can do window.myfoo to declare your function instead.
window.myfoo = function (x)
{
alert(x);
}
JSFIDDLE
But yeah, it's not a good practice to polute the global scope, that's why it's better to use $(...).on("click", function () { alert(...) }) handlers.
I discourage using on... attributes in HTML because it's also another bad practice.
Your code becomes:
function myfoo (x)
{
alert(x);
}
var $divToAppend = $("<div id='cool_div'>")
$divToAppend.on("click", function () {
myfoo("hello");
});
$("#some").html($divToAppend);
And here a DEMO.
Related
Can you help me please?
During a test, I did not understand this question:
Given the following code, write two lines of JavaScript to call the
print() function in a way that prints the Window global object in the
JavaScript console?
Your code must not use the variable window. Feel free to comment.
Printer = function(){
this.print = function() {
console.log(this);
}
}
var printer = new Printer();
Answer:
printer.print.call(this);
//or
printer.print.bind(this)();
Why this is usefull:
Example: adding an event listener in an object:
function person(){
this.clicker=0;
document.body.addEventListener("click",function(){
this.clicker++;
});
}
So this should work, shouldnt it? Nope it doesnt, cause the eventlistener automatically binds this as the clicked element. So this will be body, wich hasnt a clicker property. So in that situation its usefull to override this...
document.body.addEventListener("click",function(){
this.clicker++;
}.bind(this))
Or in newer browsers (see arrow funcs):
document.onclick=()=>{
this.clicker++;
};
Thats what the tutorial wants to tell you. Hope it helps...
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>
Please see this fiddle:
http://jsfiddle.net/GSHsH/9/
HTML:
<div id="papa" onclick="anything(this);">Blabla</div>
JS:
function anything(theObj){
window.alert(theObj.innerHTML);
}
I do not understand why the function "anything" gets as not reconized. (using prototype)
It is not that it doesnt recognide this - it does not recognise the method anything because of a setting you've made in jsfiddle - to scope the javascript into onLoad. If you would have chosen no wrap (head) it would work fine: http://jsfiddle.net/GSHsH/11/
A bit more detail. The way you set it up, this is what gets injected into the output frame in jsfiddle:
Event.observe(window, "load", function(){
function anything(theObj){
window.alert(theObj.innerHTML);
}
});
Note that the method anything is not in global (window) scope, it is in the scope of a particular function. This means its not visible to the element on the page.
The way I set it up you get this:
function anything(theObj){
window.alert(theObj.innerHTML);
}
Which is just a plain old function defined in the head of the page - now accesible from an element on the page.
Its because jsfiddle generates your code like this:
Event.observe(window, "load", function(){
function anything (theObj){
window.alert(theObj.innerHTML);
}
});
so your "anything" function is not in global scope. this will work:
window.anything = function (theObj){
window.alert(theObj.innerHTML);
}
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.