Javascript, design function to reference itself
Given:
myChart = new ganttC开发者_高级运维hart("chart1");
function ganttChart(gContainerID) {
this.variable1 = "lol";
this.variable2 = "hai dere";
this.variable3 = "cometishian";
....
this.gContainer = document.getElementById(gContainerID);
this.gContainer.innerHTML += "<div id=\"gBar" + i +
"\" class=\"gBar\" onmousedown=\"gInitBarDrag(this)\">Hello</div>";
....
}
How would I make the function gInitBarDrag() defined inside the ganttChart class? I don't want an exterior standalone function as it needs to reference things inside the object.
So for example, the function would be able to reference variable1/2/3 which are defined in a specific instance of the ganttChart object (you can have multiple chart objects).
Hope that makes sense! EG:
function ganttChart(gContainerID) {
this.variable1 = "lol";
this.variable2 = "hai dere";
this.variable3 = "cometishian";
....
this.gContainer.innerHTML += "<div id=\"gBar" + i +
"\" class=\"gBar\" onmousedown=\"gInitBarDrag(this)\">Hello</div>";
....
gInitBarDrag = function(thisGanttObject)
{
alert(thisGanttObject.variable2);
// This line wont work because it doesn't know what ganttChart to reference!
}
}
function gnattChart(gContainerID) {
var div = document.createElement('div');
div.id = 'gBar';
div.className = 'gBar';
//If you want to reference properties from the gnattChart object...
//Use `self` where you'd normally use `this` in the handler function
var self = this;
div.onmousedown = function () {
//contents of gInitBarDrag here...
};
//If you want the container to be emptied...
this.gContainer.innerHTML = '';
this.gContainer.appendChild(div);
}
this.gContainer.innerHTML += "<div id=\"gBar" + i + "\" class=\"gBar\" onmousedown=\"function(){ alert('here'); }\">Hello</div>";
Although, inline functions are generally frowned upon.
OK, I will answer without testing it, and using prototypejs, but I'm sure you can workout the functions for yourself if you don't want to use a JS framework.
First, you will want to create your div using document.createElement instead of injecting HTML, something like this:
var d = document.createElement("div");
// Set your div properly.
Then you will have to use document.appendChild to put your new div (variable d) in your page. Now the "difficult" part: listen for mousedown events and act accordingly. You can do this by using Event.observe (prototypejs) AND bind (prototypejs) to bind your object to the listener, so you can use its variables (this.variable1, variable2, etc).
This will give a code somewhat like this:
function ganttChart(gContainerID) {
this.variable1 = "lol";
this.variable2 = "hai dere";
this.variable3 = "cometishian";
// Create Element part (createElement, appendChild, etc).
var d = document.createElement("div");
// continue from here.
this.gInitBarDrag = function()
{
alert(this.variable2);
};
$(d).observe("mousedown", this.gInitBarDrag.bind(this));
}
Some notes: bind and observe can be implemented somewhat easily without a JS framework. This code is untested.
If you define a function as a property of an object, then this
points to the object:
var myObject = { foo: true, bar: function(){ if(this.foo){ doStuff(); }};
If this
is used in a constructor function that returns an object, then this
is bound to the new object that is returned. The way you're using this
in the code you posted, this
points to the global scope, which is one of the bad parts of Javascript.
So, here's how I would approach this:
function GanttChart(gContainerID) {
var chart = {
variable1: "lol",
variable2: "hai dere",
variable3: "cometishian",
containerId: gContainerID,
gInitBarDrag: function(){
alert(this.variable2);
}
}
return chart;
}
myChart = new GanttChart("chart1");
document.getElementById(myChart.containerId).innerHTML += "<div id=\"gBar" + i + "\" class=\"gBar\" onmousedown=\"myChart.gInitBarDrag();\">Hello</div>";
I changed the ganttChart function to be capitalized because by convention, constructor functions that return an object are capitalized.
var gInitBarDrag = function(){
///function body here
};
function ganttChart(gContainerID) {
....
this.gContainer.innerHTML += "<div id=\"gBar" + i + "\" class=\"gBar\" onmousedown=\"gInitBarDrag(this)\">Hello</div>";
....
}
精彩评论