I have an object and lets call this object game.Door.
Inside this object I have a method.
openDoor: function() {
game.removeRoom1();
game.viewRoom3();
},
removeRoom1() is in this js file.
viewRoom3() is in another js file.
My HTML:
<script src="js/viewRoom3jsfile.js"> </script>
<script src="js/filewithObject.js"></script>
viewRoom3() is not working unless I put it in the same js file as my object.
Is there any way to have viewRoom3() in another js file?
Further clarification:
filewithObject.js:
var game = game || {};
game.Door = {
openDoor: function() {
game.removeRoom1();
game.viewRoom3();
},
};
game.removeRoom1 = function(){
}
viewRoom3jsfile.js:
game.viewRoom3 = function(){
}
Currently, my viewRoom3() is in the same file as my object and my javascript works.
However, if I move viewRoom3() into a seperate js file, the function stops working.
As i understand it you have something like this:
var Game= {
removeRoom1: function() { return something; },
viewRoom3: function() { return something; }
}
So the function is inside the object. If you want the function to be in another js file other than the object, i suggest you do something like this:
var Game= {
....//object code here
}
//the following can go to another js file
function removeRoom1(obj) { return obj.something; }
function viewRoom3(obj) { return obj.something; }
Related
I'm working on a Flask app where some data gets passed to a template, and I want to make that data available to multiple instances of an object. Here's what it would look like if I just hardcoded the desired data into my .js file:
var Module = function(selector) {
var targetDiv = selector,
targetData = 'lorem ipsum sit dolor',
show = function() {
$('<p>' + targetData + '</p>').appendTo(targetDiv);
};
return {
show: show,
};
};
$(document).ready(function() {
firstModule = new Module($('#first'));
secondModule = new Module($('#second'));
firstModule.show();
secondModule.show();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='first'></div>
<div id='second'></div>
I can't just call a function on an unconstructed Module object, so my next step is to create a static-like ModuleFactory that I can load with data from jinja, and then create Modules from there:
var ModuleFactory = function() {
var targetData = null,
setData = function(data) {
targetData = data;
},
create = function(selector) {
return new Module(selector, data);
};
return {
setData: setData,
create: create,
};
} ();
Then I attempt to call ModuleFactory.setData({{data}}); from a <script> tag in the HTML, and do something like ModuleFactory.create($('#first')).show(); in the .js
But of course because I have to include my .js file before using the ModuleFactory in the HTML, I end up constructing the objects before the factory is initialized.
(Past this point, my workaround attempts stop being relevant to the problem.)
Anyway, what's the correct way of getting data from Jinja to my JS module? There has to be a common pattern or something.
This feels awful, but it works:
Have an object with a runProgram method, which takes the desired data as a parameter, then executes the logic that had previously been inside the document ready function. e.g.
var ProgramRunner = function() {
var runProgram = function(data) {
ModuleFactory.setData(data);
firstModule = ModuleFactory.create($('#first'));
firstModule.show();
};
return {
runProgram: runProgram;
};
};
Then just
<script>
$(document).ready(function() { ProgramRunner.runProgram({{data}}) });
</script>
in the HTML.
(Leaving question open, because I suspect there's a much better way of handling this.)
Let's say I have an Object View original defined in one file View.js :
var View = (function () {
function View() {
}
View.prototype.SubFunc = function() {
}
return View;
})();
Now I want to be able to split in 2 files :
View.js
var View = (function () {
function View() {
}
return View;
})();
and SubFunc.js
View.prototype.SubFunc = function() {
}
Why it doesn't seem to work anymore ? During execution I get this error :
view.SubFunc is not a function
JS files are imported one by one but asynchronously and there is no guarantee that file1 will be loaded before file2.
You can wrap file2 (SubFunc.js) into a document.onload event so that it will be executed when other files are loaded.
document.onload = function(){
View.prototype.SubFunc = function() {
}
}
In my JavaScript I have an object instance called "View". I want to add a function to this object. The function looks something like
function csiSelectValueRestriction (columnName) {
//... <a rather long and involved function>
}
Ultimately I want to be able to use the function in the following way:
var result = View.csiSelectValueRestriction ("bldgs");
What is the simplest way to accomplish this?
Just assign the function to the property;
View.csiSelectValueRestriction = csiSelectValueRestriction;
This should work if you want to add a function to an existing instance
View['csiSelectValueRestriction'] = function (columnName) { ... ... }
var View = {
someProperty: 'someVal',
csiSelectValueRestriction: function(columnName) {
//JS logic
}
};
or View.csiSelectValueRestriction = function(columnName) { ... }
I need to add some functionality to a core JavaScript object function, without touching the original file.
How can I extend the following object function from my object below while keeping the namespace intact?
core object
(function() {
var DOM = tinymce.DOM;
tinymce.create('tinymce.plugins.WordPress', {
// i need to extend this function
_hideButtons : function() {
// stuff here
};
});
tinymce.PluginManager.add('wordpress', tinymce.plugins.WordPress);
})();
my object
I tried this, but it doesn't work:
(function() {
tinymce.create('tinymce.plugins.Mine', {
init : function(ed, url) {
ed.plugins.wordpress._hideButtons.prototype = function() {
// new function stuff
}
},
});
tinymce.PluginManager.add('mine', tinymce.plugins.Mine);
})();
Am I on the right track?
extending was, in fact, not what i needed.
by just removing .prototype above, allowed me to completely over write the function in question. this is exactly what i wanted to do.
check it...
(function() {
tinymce.create('tinymce.plugins.Mine', {
init : function(ed, url) {
ed.plugins.wordpress._hideButtons = function() {
// new function stuff
}
},
});
tinymce.PluginManager.add('mine', tinymce.plugins.Mine);
})();
I have and external JS scripts file with all my objects in that runs once the document is ready something like this...
jQuery(function($) {
var Main = {
run: function () {
myFunction.setup();
}
}
var myFunction = {
setup: function() {
//Do some stuff here
}
}
Main.run();
});
I want to be able to run myFunction.setup() only if im on a certain page though otherwise I get errors if that method is looking for elements on the page that don't exist e.g a slideshow, menus etc.
At the moment I have got round this by checking if the element exists with .length and if it does then running the rest of the method but I was wondering if there was a nicer way? Maybe like if it was possible to send variables to the scripts file when it loads based on the page im on so it knows what to methods run?
Any help would be really appreciated.
Thanks
Giles
Paul Irish has a great way of doing exactly this, using ID and classes from the body tag to execute certain blocks of code:
http://paulirish.com/2009/markup-based-unobtrusive-comprehensive-dom-ready-execution/
This kind of thing might help:
Page specific
var page_config = {
setup_allowed: true
// ... more config
};
Generic
var Main,
myFunction;
(function ($, _config) {
myFunction = (function () {
var _public = {};
if (_config.setup_allowed === true) {
_public.setup = function () {
};
}
return _public;
})();
Main = (function () {
var _public = {};
if (typeof myFunction.setup !== "undefined") {
_public.run = function () {
myFunction.setup();
};
// Run it as we had Main.run() before
_public.run();
}
return _public;
})();
})(jQuery, page_config);
This way Main.run() and myFunction.setup() are only available if specified in page_config.
Here's a working example you can have a play with. This may be a bit verbose for your particular requirement but hopefully it'll help in some way :-)