Use objects method as callback - javascript

I've got another JavaScript/jQuery-Problem. A minimal example could be this: I've got a div, and want some JavaScript executed, when the mouse enters. But for some reasons (= in reality, there a many divs, and for each data needs to be kept) I want to use a object as handler for the callback. Here's a small example:
function handler($thediv)
{
this.somedata = 8;
$thediv.mouseenter(function() { this.callback(); });
}
handler.prototype.callback = function()
{
alert(somedata);
}
An object is created when the document is loaded:
$(document).ready( function() {
new handler($("div"));
});
Nothing happens - except that the constructor is executed. I've tried and searched for hours now, but I can't fix this... probably too trivial?
Edit: A complete example.
<html>
<script type="text/javascript" src="jquery-1.6.js"></script>
</head>
<body>
<div>
blah blahasdasdadsssssssssssssss
asddddddddddddddddddddddddddd
</div>
</body>
<script type="text/javascript">
$(document).ready(function() {
new handler($("div"));
});
function handler($thediv)
{
this.somedata = 8;
$thediv.mouseenter(this.callback);
}
handler.prototype.callback = function()
{
alert(somedata);
}
</script>
</html>

The biggest issue here is the use of this in various contexts. Within the mouseenter function, this refers to div, not the object.
This should work:
http://jsfiddle.net/Nx5c7/
function handler($thediv)
{
this.somedata = 8;
this.theID=$thediv.attr("id");
var obj=this;
$thediv.mouseenter(function() {
obj.callback();
});
}
handler.prototype.callback = function()
{
alert(this.theID + " : " + this.somedata);
}

Related

JS prototyping Cannot set property 'moveRight' of undefined

I've a problem with this simple prototyping:
Game = function (moduleConfig, gameConfig) {
this.moduleConfig = moduleConfig;
this.gameConfig = gameConfig;
// Game-Commands
this.keyCommands = {
moveLeft: false,
moveRight: false
};
this.catcher = null;
this.stage = null;
return this;
}
/**
* Left arrow down
*/
Game.prototype.onKeyboardLeftDown = function () {
this.keyCommands.moveLeft = true;
}
/**
* Left arrow up
*/
Game.prototype.onKeyboardLeftUp = function () {
this.keyCommands.moveLeft = false;
}
I always get the error message: Uncaught TypeError: Cannot set property 'moveRight' of undefined when calling onKeyboardLeftDown and onKeyboardLeftUp. But i have declared moveLeft in the constructor in the keyCommands object.
The two methods were called on key down and key up events:
Game.prototype.init = function () {
// ...
// =========================================================================
// Set keyboard
KeyboardJS.on('left', this.onKeyboardLeftDown, this.onKeyboardLeftUp);
KeyboardJS.on('right', this.onKeyboardRightDown, this.onKeyboardRightUp);
// =========================================================================
};
My index.html looks like this:
<!DOCTYPE html>
<html>
<head>
<title>pixi.js example 1</title>
<style>
body {
margin: 0;
padding: 0;
background-color: #000000;
}
</style>
<script src="js/pixi.dev.js"></script>
<script src="js/keyboard.js"></script>
<script src="js/moduleConfig.js"></script>
<script src="js/moduleResult.js"></script>
<script src="js/game.js"></script>
</head>
<body style="background-color: #EEEEEE">
<script>
var game = new Game(moduleConfig, {
screenWidth: (window.innerWidth - 10),
screenHeight: (window.innerHeight - 10),
bgColor: 0xEEEEEE
});
game.init();
</script>
</body>
</html>
Does some one see the failure? I have searched a lot, but i'm very confused (normally i develop only in c#...)
You're binding is wrong.
// Set keyboard
KeyboardJS.on('left', this.onKeyboardLeftDown, this.onKeyboardLeftUp);
this.onKeyboardLeftDown and this.onKeyboardLeftUp are called without the correct context
to fix this do something like:
KeyboardJS.on('left', this.onKeyboardLeftDown.bind(Game), this.onKeyboardLeftUp.bind(Game));
I would not recommend using bind() - for browser compatibility, but you can use something like lodash's bind or an bind "emulator" like:
function bind(fn, ctx) {
return function bound() {
return fn.apply(ctx, arguments);
};
}
Another way would be
var self = this;
KeyboardJS.on('left',
function(){self.onKeyboardLeftDown()},
function(){self.onKeyboardLeftUp()}
);
Your question is not complete, I do not see the relevant code where you try to define moveRight.
Possible problems:
you might have a typo, that keyCommands is spelled exactly
you might refer to keyCommands outside its scope
you might refer to keyCommands.moveRight before keyCommands is initialized
you might assign another value to keyCommands before referring to moveRight

page javascript onload can only use one function in a var?

I've written a basic page in html, putting this in the head:
<script type="text/javascript" src="scripts/main.js"></script>
and the contents of my main.js are extremely simple:
var main = {
onload : function() {
alert("HI");
}
showSurprise : function() {
alert("HI");
}
}
window.onload = main.onload;
however, it seems that having these two functions exist at the same time causes neither of them to work, whether I set window.onload to the onload or the showSurprise function. If I delete one of them, it works fine.
You have syntax error. It should be:
var main = {
onload: function() {
alert("HI");
},
showSurprise: function() {
alert("HI");
}
};
I hope this is what you are looking for
var main = {
onload: function() {
alert("HI");
},
showSurprise: function() {
alert("HI");
}
};
window.onload = main.onload();
You should pass it as a function.

jquery/javascript function work in the firebug console but not on page load

Long story short i need to edit a textarea after it was created by a wordpress plugin, i can set the id and default value, but i can't set events or anything else, i want the default value to disappear after the user clicks to enter the phone number.
I have tried several ways of doing this without luck, some are:
<script type="text/javascript">
$(document).ready(function(){
// Your code goes here
function clearOnInitialFocus ("telid01") {
var clearedOnce = false;
document.getElementById("telid01").onfocus = (function () {
if (clearedOnce == false) {
this.value = '';
clearedOnce = true;
}
})
}
window.onload = function() { clearOnInitialFocus('telid01');}
});
</script>
Also tried
<script type="text/javascript">
$(document).ready(function(){
document.getElementById('telid01').addEventListener('focus', function() {
this.value = "";
});
});
</script>
this works in the console but not on page load:
document.getElementById('telid01').addEventListener('focus', function() {
this.value = "";
Since you're using jQuery, you may as well use jQuery's event binding, like so:
$(document).ready(function(){
var clearedOnce = false;
$(this).on('focus', '#telid01', function () {
if (!clearedOnce) {
$(this).val('');
clearedOnce = true;
}
});
});
Edit: If you attach the event to 'document' then pass the id as a selector to on() it should work, and should be able to attach the event even without the field existing on the page yet. See: http://api.jquery.com/on/
You are using function parameters in a strange way.
I've tried the following code that is based on yours and it works fine.
<!doctype html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
// Your code goes here
var clearedOnce = false;
document.getElementById("myTest").onfocus =
function () {
if (clearedOnce == false) {
this.value = '';
clearedOnce = true;
}
};
});
</script>
</head>
<body>
<input id="myTest" value="placeholder" />
</body>
</html>

onscroll div in a JavaScript object

i want to build a div with scroll, that when you scroll this div, it will active anothe function.
i need to build this in a Object.
there is any way to do this?
i write here an example source (that not work) of what i want.
<script type="text/javascript">
function onsc(divName, divChange) {
this.play = function() {
window.onload = function() {
document.getElementById(divName).onscroll = function() {
this.scroll(n)
}
};
}
this.scroll = function(n) {
document.getElementById(divChange).innerHTML = "you scroll!";
}
}
c[1] = new onsc("div1", "div1_i").play();
</script>
<div id="div1_i">this div will change when you scroll</div>
<div id="div1" style="background:#C6E2FF; width:300px; height:200px; overflow-y:scroll;">
<p style="height:800px;">txt</p>
</div>
Your code was nearly there. I made a few changes and put into a JSFiddle for you.
I added comments at what you missed. Most importantly the context of this changes when you entered into that function on the onscroll event.
JavaScript
function onsc(divName, divChange) {
// First of all make `this` inherit to below functions
var self = this;
this.play = function () {
document.getElementById(divName).onscroll = function() {
// Changed this to call the parent and place the correct DIV
self.scroll(divChange)
}
}
this.scroll = function (n) {
document.getElementById(divChange).innerHTML = "you scroll!";
}
}
c = new onsc("div1", "div1_i").play();
Demo
Have a look at my JSFiddle: http://jsfiddle.net/bJD8w/2/

Calling Javascript Functions by name

If I have an element on the page like this ...
<span data-function="DoSomething">Click</span>
... and i put this in my page header ...
$(document).ready(function()
{
$('[data-function]').each(function()
{
var fName = $(this).attr('data-function');
$(this).click(fName);
});
});
... what goes in place of the comment produce the desired effect of executing the function called "DoSomething".
Note:
I no the code above wont work, my question is how to make this work (translate 'DoSomething' in to DoSomething();)
Any ideas guys?
The functions should be available. Try putting them in an Object, like this:
$(document).ready(function()
{
var fns = {
DoSomething: function() {/* ... */},
DoAnotherthing: function() {/* ... */}
};
$('[data-function]').each(function()
{
var fName = $(this).attr('data-function');
$(this).click(fns[fName]);
});
});
Here's a jsfiddle, demonstrating a way to keep everything local to one namespace and assigning handlers based on the data attribute of elements.
Try calling function with window object -
$(document).ready(function() {
$('[data-function]').each(function() {
var fName = $(this).attr('data-function');
if (typeof (window[fName]) === "function") {
$(this).click(window[fName]);
}
});
}
You can use something like
$(this).click(window[fName]);
Where window would be replaced by the appropriate expression if the function DoSomething is not defined in the global scope.
Maybe a little bit clean way:
http://jsfiddle.net/whsPG/
var myfuncs = {
alert : function() {
alert("An Alert");
},
changeName: function(obj) {
$(obj).text('Other Text');
}
};
$('[data-function]').on('click', function()
{
value = $(this).data('function');
if (myfuncs.hasOwnProperty(value)) {
myfuncs[value](this);
}
});
​

Categories