i am trying to target a jquery selector by using namespaces in my script and also making function private but i think i am still missing something here, can anyone guide. It works if i try by adding a breakpoint on the last line and than use devtools to access MyUtility.Selectors.ColorCss.myBorder()
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Selectors</title>
</head>
<body>
<ul>
<li class="test">First</li>
<li>Second</li>
<li>Third</li>
</ul>
<!--<script>
$('document').ready(function(){
$('li.test').css('color','green')
})
</script>-->
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<script>
var customModule = (function () {
var MyUtility = {
Selectors: {
ColorCss: function () {
var myBorder = function () {
$('li').css('color', 'red')
console.log('hello')
}
return{
myBorder: myBorder
}
}()
}
}
}())
</script>
</body>
</html>
As you said It works if i try by adding a breakpoint on the last line and than use devtools to access MyUtility.Selectors.ColorCss.myBorder()
This is your code:
var customModule = (function () {
var MyUtility = {
Selectors: {
ColorCss: function(){
var myBorder = function(){
$('li').css('color', 'red');
console.log('hello');
}
return{ myBorder: myBorder }
}()
} // Selectors
} // MyUtility
}())
Your code above can be written as:
function myBorderFunc() { $('li').css('color', 'red'); console.log('hello');}
var selectorObj = { ColorCss : function(){ return{ myBorder: myBorderFunc } }()};
var MyUtility = { Selectors: selectorObj};
var customModule = ( function(){ MyUtility }() );
This shows the problem
var customModule is a function expression that does not return anything and it is therefore undefined
since customModule is undefined you can not use customModule.MyUtility
as you said you can call MyUtility.Selectors.ColorCss.myBorder() since MyUtility is an object that has a property Selectors and so on
you can test it out with this example:
// undefined since nothing is returned
var bar = (function(){ {Foo: "i am foo"} }());
// returns foo and can be used bar.Foo ---> "i am foo"
var bar = (function(){ return {Foo: "i am foo"} }());
To 'fix your code' return MyUtility
var customModule = (function () {
var MyUtility = {
Selectors: {
ColorCss: function(){
var myBorder = function(){
$('li').css('color', 'red');
console.log('hello');
}
return{ myBorder: myBorder }
}()
} // Selectors
} // MyUtility
return MyUtility;
}())
This way you can access it like this customModule.Selectors.ColorCss.myBorder().
More info about Function expressions vs. Function declarations
Related
How can I add on event listener for custom object.
For example:
(function () {
this.EmojiPicker = (function () {
function EmojiPicker(options) {
// ...
}
EmojiPicker.prototype.test = function () {
//...
};
return EmojiPicker;
})();
}).call(this);
I want to add
let emojiPicker = new EmojiPicker();
emojiPicker.on("change", function () {
//
});
I have a simple example modified from you code.
See if this can help.
The main idea is to trigger an event by $(emojiPicker).trigger('change');,
so that you can receive with $(emojiPicker).on("change", function () {});
<html>
<head>
<script type="text/javascript" src="./jquery-1.7.1.js"></script>
<script>
(function () {
this.EmojiPicker = (function () {
function EmojiPicker(options) {
// ...
}
EmojiPicker.prototype.test = function () {
//...
$(emojiPicker).trigger('change');
};
return EmojiPicker;
})();
let emojiPicker = new EmojiPicker();
$(emojiPicker).on("change", function () {
alert("triggered");
});
}).call(this);
</script>
</head>
<body>
</bofy>
</html>
More information from Custom events in jQuery?
I am trying to modify an application by overriding certain functions. I cannot release the code due to enterprise ownership. My code looks like this:
<html>
<head>
<script type="text/javascript" src="https://mylink.scriptX.js"></script>
// Some other scripts and css references
</head>
<body>
<script>
$(document).ready(function () {
form_script = my_script =
{
initialization:function (mode, json_data) {
this.parent_class.initialization(mode, json_data);
//Mycode to override the functions in scriptX.js is below:
var x= {};
function inherit(x) {
var y= {};
y.prototype = x;
return y;
};
(function ($) {
var OverrideFunctions = inherit($.my_methods);
OverrideFunctions.function1 = function () { ...};
OverrideFunctions.function2 = function () { ...};
OverrideFunctions.function3 = function () { ...}
})(jQuery);
}
//some original code here
}
</script>
//some other code here
</body>
</html>
Now the content of the scriptX.js is something like this:
(function ($) {
var my_methods = {
function1 = function () { ...};
function2 = function () { ...};
function3 = function () { ...}
}
})(jQuery);
The problem is that, I am noticing that the debugger skips the whole block of code since OverrideFunctions.function1 = function () { to the end })(jQuery);
So my functions are not being executed and thus the application is not changed. I was wondering if that could be related
I can not seem to find the code to disable a javascript function. What I want to do is have a javascript function and then I want to disable it. Here is the code:
<script>
var fooFunc = function fooFunction() {
alert("HELLO");
};
$(document).ready(function() {
fooFunc.disable();
});
</script>
<button onclick="fooFunc()">Button</button>
Basically, when the button is click the function should not work, it should be disabled. Thanks
"Disabling" fooFunc is the same as setting it to an empty function (not to null--that will cause an error when it is called the next time). In this case:
$(document).ready(function() {
fooFunc = function() { };
});
But I don't see how this is different from simply removing the onclick handler from the HTML element.
If you want the ability to disable/re-enable the function, you can write it like this:
fooFunc = function() {
function _fooFunc() {
if (!enabled) return;
alert("HELLO");
}
var enabled = true;
_fooFunc.enable = function() { enabled = true; };
_fooFunc.disable = function() { enabled = false; };
return _fooFunc;
}();
If you want to extend this to allow any function to be enabled/disabled, you can write a higher-order function, which takes any function as a parameter, and returns a function with enable and disable methods attached to it:
function disablable(fn) {
function inner() {
if (!enabled) return;
fn();
}
var enabled = true;
inner.enable = function() { enabled = true; };
inner.disable = function() { enabled = false; };
return inner;
}
Now you can define fooFunc as
var fooFunc = disablable(function fooFunction() {
alert("HELLO");
});
and the rest of your code will work as you want.
You can access the onclick property of the element..
<button id="id" onclick="fooFunc()">Button</button>
<script>
document.querySelector('#id').onclick = '';
</script>
If you don't want the function to work at all and be totally disabled then use the below.
If you want the function to work only under certain conditions then you will need if/else statements so it will work only when the conditions that you have set are met.
$(document).ready(function(){
$("button").onclick(function(event){
event.preventDefault();
});
});
You were going to define it back to undefined or null.
fooFunc=undefined;
You Should be doing this :) Change function definition on very first run and you are good to go.
<! DOCTYPE html>
<html lang="en">
<body>
<script>
var fooFunc = function() {
alert("HELLO");
fooFunc = function(){};
};
var enablefooFunc = function()
{
fooFunc = function() {
alert("HELLO");
fooFunc = function(){};
};
}
</script>
<button onclick="fooFunc()">Run once and Disable FooFunc</button>
<button onclick="enablefooFunc()">Enable FooFunc</button>
</body>
</html>
The issue is in the model, when recalled by the presenter it does not work like I assumed, in fact it works as if the this keyword refers to an [object HTMLTextAreaElement], not to a Model object.
/** PRESENTER **/
function Presenter() {
var toolbarView;
var outputView;
var sourceCodeModel;
var public = {
setToolbarView: function (view) {
toolbarView = view;
},
setOutputView: function (view) {
outputView = view;
},
setModel: function (_model) {
sourceCodeModel = _model;
},
init: function () {
toolbarView.setNewTableHandler(function () {
outputView.updateSource(sourceCodeModel.string);
});
toolbarView.setNewConstraintHandler(function () {
/*stub*/
alert("new constraint");
});
}
}
return public;
}
/** TOOLBAR VIEW **/
function toolbarView() {
this.setNewTableHandler = function (handler) {
$("#newTable").click(handler);
}
this.setNewConstraintHandler = function (handler) {
$("#newConstraint").click(handler);
}
}
/** OUTPUT VIEW **/
var outputView = {
updateSource: function (newVal) {
$("#sourcetext").val(newVal);
},
draw: function () {
//stub
}
};
/** MODEL **/
var model = new Object(); //o {};
model.source = [];
model.string = function () {
/* ALERT(this) returns [object HTMLTextAreaElement] wtf? */
var stringa = "";
for (var i = 0; i < this.source.length; i++) { //this does not work, since this = HTMLTextAreaElement
stringa += this.source[i] + "\n";
}
return stringa;
}
$(document).ready(function () {
var presenter = new Presenter();
var view1 = new toolbarView();
presenter.setToolbarView(view1);
presenter.setOutputView(outputView);
presenter.setModel(model);
presenter.init();
});
and the HTML is pretty simple:
<!doctype html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="mvp.js"></script>
<meta charset="UTF-8">
<title>Titolo documento</title>
<style type="text/css">
/*unnecessary here*/
</style>
</head>
<body>
<div id="container">
<div id="toolbar">
<button id="newTable">New table</button>
<button id="newConstraint">New Constraint</button>
</div>
<div id="source">
<textarea id="sourcetext"></textarea>
</div>
<button id="update">Update</button>
<div id="output"></div>
</div>
</body>
</html>
What am i doing wrong on the model object?
When you pass a function as a listener the this property will not be available inside the function:
var obj = {
a: function() {
alert(this)
}
};
$('body').click(obj.a);
When body is clicked the function's this property will be document.body.
To prevent this you must bind the function:
$('body').click(obj.a.bind(obj));
Or in older browsers wrap it:
$('body').click(function() {
obj.a();
});
So you must bind the function before pass it:
outputView.updateSource(sourceCodeModel.string.bind(sourceCodeModel));
More info about javascript function's context: http://www.quirksmode.org/js/this.html
this line: var public = { try to do not to use public, that is reserved word.
And a general note, try to bind this to a variable, because this changes context where it is currently.
/** TOOLBAR VIEW **/
function toolbarView() {
var that = this;
that.setNewTableHandler = function (handler) {
$("#newTable").click(handler);
}
that.setNewConstraintHandler = function (handler) {
$("#newConstraint").click(handler);
}
}
i am currently learning about javascript namespaces as i build a website and i have the following requirements: i want to make all of my code private so that other public scripts on the page (possibly adverts, i'm not too sure at this stage) cannot override or alter my javascript. the problem i am foreseeing is that the public scripts may use window.onload and i do not want them to override my private version of window.onload. i do still want to let them run window.onload though.
so far i have the following layout:
//public code not written by me - i'm thinking this will be executed first
window.onload = function() {
document.getElementById('pub').onclick = function() {
alert('ran a public event');
};
};
//private code written by me
(function() {
var public_onload = window.onload; //save the public for later use
window.onload = function() {
document.getElementById('priv').onclick = function() {
a = a + 1
alert('ran a private event. a is ' + a);
};
};
if(public_onload) public_onload();
var a = 1;
})();
i have quite a few questions about this...
firstly, is this a good structure for writing my javascript code, or is there a better one? (i'm planning on putting all of my code within the anonymous function). is my private code really private, or is there a way that the public javascript can access it? i'm guessing the answer to this is "yes - using tricky eval techniques. do not embed code you do not trust", but i'd like to know how this would be done if so.
secondly, when i click on the public link, the event is not fired. why is this?
finally, if i comment out the if(public_onload) public_onload(); line then a is returned correctly when i click the private button. but if i leave this line in then a's value is nan. why is this?
You can attach event listeners to avoid their overriding in some way like this:
<ol id="res"></ol>
<script type="text/javascript">
var res = document.getElementById('res');
function log(line) {
var li = document.createElement('li');
li.innerHTML = line;
res.appendChild(li);
}
// global code:
window.onload = function() {
log('inside the global window.onload handler');
};
// private code:
(function(window) {
function addEvent(el, ev, fn) {
if (el.addEventListener) {
el.addEventListener(ev, fn, false);
} else if (el.attachEvent) {
el.attachEvent('on' + ev, fn);
} else {
el['on' + ev] = fn;
}
}
addEvent(window, 'load', function() {
log('inside the second window.onload handler in "private section"');
});
})(window);
</script>
DEMO
The example of code organization you asked about:
HTML:
<ol id="res"></ol>
JavaScript:
/* app.js */
// in global scope:
var MyApp = (function(app) {
var res = document.getElementById('res');
app.log = function(line) {
var li = document.createElement('li');
li.innerHTML = line;
res.appendChild(li);
};
app.doWork = function() {
app.log('doing a work');
};
return app;
})(MyApp || {});
/* my-app-module.js */
// again in global scope:
var MyApp = (function(app) {
app.myModule = app.myModule || {};
app.myModule.doWork = function () {
app.log('my module is doing a work');
};
return app;
})(MyApp || {});
/* somewhere after previous definitions: */
(function() {
MyApp.doWork();
MyApp.myModule.doWork();
})();
DEMO
MyApp is accessible from outside
Nothing is accessible from outside