5
I’m having a hard time (which is probably pretty silly) storing a value in a Javascript object property. I’ve done something similar recently using this.propriedade = valor
within the "constructor" function and had no problems reusing the value in a function defined as `Object.prototype.function_name".
But in this example (available on Jsfiddle) a property (this.m_oClickCallback
) is not visible in mouse click processing function (MyButton.prototype.handleClick
), generating the following exception when the button is clicked:
Uncaught Typeerror: Object [Object global] has no method 'm_oClickCallback'
I imagine that probably the mistake is due to something very silly, but I’m not able to see what it is.
Here is the html of the example I prepared:
<body onload="init();">
<canvas id="myCanvas" width="800" height="600">
O seu navegador não suporta HTML5. (<i>Your browser does not support HTML5.</i>)
</canvas>
</body>
And the Javascript code:
(function() {
// Objeto de botão customizado
var MyButton = function(sLabel, sColor, oClickCallback) {
// Chama o initialize do objeto protótipo (createjs.Container)
this.initialize();
// Armazena a referência para o callback do evento de click
this.m_oClickCallback = oClickCallback;
// Cria o conteúdo do botão
var oText = new createjs.Text(sLabel, "40px Arial", "#ffffff");
oText.textBaseline = "top";
oText.textAlign = "center";
var iWidth = oText.getMeasuredWidth() + 30;
var iHeight = oText.getMeasuredHeight() + 20;
var oBackground = new createjs.Shape();
oBackground.name = "Background";
oBackground.graphics.beginFill(sColor).drawRoundRect(0, 0, iWidth, iHeight, 10);
oText.x = iWidth / 2;
oText.y = 10;
this.addChild(oBackground, oText);
// Captura o evento de click
this.addEventListener("click", this.handleClick);
}
// Define o protótipo
MyButton.prototype = new createjs.Container();
// Função de tratamento do click no botão. Invoca o callback armazenado.
MyButton.prototype.handleClick = function(oEvent) {
this.m_oClickCallback(oEvent.target);
}
// Atribui o objeto ao escopo global de "window"
window.MyButton = MyButton;
}());
// Função de inicialização. Cria o botão no onload do corpo da página.
function init() {
g_oStage = new createjs.Stage("myCanvas");
var oButton = new MyButton("Olá mundo!", "red", function() { alert("Funciona!"); });
g_oStage.addChild(oButton);
g_oStage.update();
}
EDIT: the idea is to store the property so that it is differentiated between each new instance of the object (as if it were a private or public attribute of a class in other languages). Solutions in which the property is shared (as if it were static) are not the interest of the question.
EDIT2:
I found out that in createjs. Container there is a property called this.mouseChildren
that when disabled causes the object to target
sent on payload of the mouse events be directly the object MyButton
rather than its components (the text or the Shape background color). Using this property and the object target
I can solve the problem as follows (see this new example Jsfiddle, now with two instances of button):
//. . .
// Faz o target dos eventos ser diretamente o objeto MyButton, ao invés do texto
// ou do background nele inclusos
this.mouseChildren = false;
//. . .
// Função de tratamento do click no botão. Invoca o callback armazenado.
MyButton.prototype.handleClick = function(oEvent) {
oEvent.target.clickCallback(oEvent.target);
}
Logging into the this
on the console, I realized that if it is in fact the object window
. That’s why the code didn’t work. I did not add this conclusion as an answer because I still have to wonder why the mouse click handling function is not invoked in the scope of the button, but rather in the browser window. Does anyone know?
Okay, good answer. Thanks for the reference link. :)
– Luiz Vieira