I'm using Mootools and I have two classes (class1, class2), class2 is used in class1
class2 get two methods (func1, func2)
func1 is used to display elements and is call in class1
func2 is used is one of the func1 displayed element is clicked.
I'd like to get an event in class1 if func2 is called but I don't know how.
Thanks for your help.
Edit: some code example
var Class1 = function(){
var class2 = new Class2();
class2.func1();
class2.onElementsHide(function(){
alert('elements are invisibles !!')
});
}
var Class2 = function(){
this.func1 = function(){
//show elements
elementOnClick(this.func2)
}
this.func2 = function(){
//hide elements
}
this.onElementsHide = function(callback){
//trigger callback when func2 is used
}
}
Take a look at MDN's article about creating and triggering events
Basically do something like the following:
var Class1 = function(){
var class2 = new Class2();
class2.func1();
class2.onElementsHidden(function(){
alert('elements are invisibles !!')
});
}
var Class2 = function(){
//Create a custom event
var ElementsHiddenEvent = new Event("ElementsHidden");
this.func1 = function(){
//show elements
elementOnClick(this.func2)
}
this.func2 = function(){
//hide elements
//Dispatch the event
document.dispatchEvent(ElementsHiddenEvent);
}
//Sets a listener for the event
this.onElementsHidden = function(callback){
//make sure the callback is a function
if(typeof(callback)!=="function") return;
//Set a listener for the custom event, and set it to execute callback
document.addEventListener("ElementsHidden",callback);
}
}
You mean this?
var Class1 = function(){
var class2 = new Class2();
class2.func1();
class2.onElementsHide(function(){
alert('elements are invisibles !!')
});
}
var Class2 = function(){
this.cb = function(){};
this.func1 = function(){
//show elements
elementOnClick(this.func2)
}
this.func2 = function(){
//hide elements
this.cb(); //<<Added
}
this.onElementsHide = function(callback){
//trigger callback when func2 is used
this.cb = callback; /// <<Added
}
}
Related
I just started to learn OOP in JavaScript and right at the beginning I got some problems.
I want to use jQuery in my own Class like so:
var myclass = function() {
this.attr1 = false;
this.target1 = false;
this.func1 = function() {
this.target1.text(this.attr1);
console.log(this.attr1);
}
}
var testObj = new myclass();
$.extend(testObj, $);
testObj.attr1 = "Hello World";
testObj.target1 = $("#targetcontainer");
testObj.func1();
<div id="targetcontainer">some1 out there?</div>
But my Container did not change the text. Could you may help me?
Well you need to make sure the dom has been created before you attempt to query for elements using selectors.
var myclass = function() {
this.attr1 = false;
this.target1 = false;
this.func1 = function() {
this.target1.text(this.attr1);
console.log(this.attr1);
}
}
$(document).ready(function() {
var testObj = new myclass();
$.extend(testObj, $);
testObj.attr1 = "Hello World";
testObj.target1 = $("#targetcontainer");
testObj.func1();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="targetcontainer">some1 out there?</div>
I am trying to understand module patterns in Javascript so that i can separate my code into different modules and use them where required.
var messageHandler = (function(){
var el;
var display = function(a){
if(a=='error'){
el = $('.error');
el.css('display','block');
}
else if (a==='success'){
el = $('.success');
el.css('display','block');
}
else if (a=='warning'){
el = $('.warning');
el.css('display','block');
}
else if (a=='danger'){
el = $('.danger');
el.css('display','block');
}
registerClick(el.find('.close'));
return this;
}
function registerClick(p_el){
p_el.bind('click',function(){
hide();
});
}
var hide = function(){
el.css('display','none');
}
return {
display: display,
hide: hide
}
})();
window.messageHandler = messageHandler;
messageHandler.display('warning');
So, I have four different classes in css for different types of messages.The close class is for a small cross button on the top right to close the message.
This works fine till i call the function only once.When i do this
messageHandler.display('warning');
messageHandler.display('success');
Now both the messages close button have been bind to the success close button because el gets overwritten.
How to achieve it keeping the code reusable and concise.
The problem here is that you have a closure variable el that you are overwriting every time display() is called. The hide() function uses whatever is the current value of el at the time it is called, so overwriting el is a problem.
If you want to have "static" functionality like this display() method, you need to avoid shared state.
As #Bergi points out in the comments, you can eliminate the shared el and modify hide() to take an element as input:
var messageHandler = (function(){
var el; // delete this
var display = function(a){
var el; // add this
function registerClick(el){
el.bind('click', function(){
hide(p_el);
});
}
function hide(el){
el.css('display','none');
}
You could also modify hide to make use of the current event properties, and then just have:
function registerClick(el){
el.bind('click', hide);
}
function hide(event){
$(event.target).css('display','none');
}
Cleaned up version including the auto-hide discussed in the comments:
var messageHandler = (function(){
var display = function(a){
var el = $('.' + a);
el.css('display', 'block');
var hideAction = function () { el.css('display', 'block'); };
var token = setTimeout(hideAction, 5000);
el.find('.close').bind('click', function () {
hideAction();
clearTimeout(token);
});
return this;
}
return {
display: display
}
})();
I have a div that I'm appending to another div when a button is clicked. I'm also calling a bunch of functions on the div that gets created.
HTML
<a onClick="drawRect();">Rect</a>
JS
function drawRect(){
var elemRect = document.createElement('div');
elemRect.className = 'elem elemRect';
elemRect.style.position = "absolute";
elemRect.style.background = "#ecf0f1";
elemRect.style.width = "100%";
elemRect.style.height = "100%";
elemRect.style.opacity = "100";
renderUIObject(elemRect);
$('.elemContainer').draggableParent();
$('.elemContainer').resizableParent();
makeDeselectable();
handleDblClick();
}
var createDefaultElement = function() {
..
..
};
var handleDblClick = function() {
..
..
};
var renderUIObject = function(object) {
..
..
};
var makeDeselectable = function() {
..
..
};
I could clone the element when the browser detects a keydown event
$(window).keydown(function(e) {
if (e.keyCode == 77) {
$('.ui-selected').clone();
return false;
}
});
then append it to #canvas. But the problem is, none of the functions I mentioned above get called with this method.
How can I copy/paste an element (by pressing CMD+C then CMD+V) and call those above functions on the cloned element?
The jQuery.clone method returns the cloned node. So you could adjust your code to do something like this:
var myNodes = $('.ui-selected').clone();
myNodes.each(function () {
createDefaultElement(this);
appendResizeHandles(this);
appendOutline(this);
});
I want to assign onclick event listener to an object from within a class
and then get some variable from the instance that created that onclick
function myclass() {
this.myvar;
this.myfunc = function()
{
alert(this.myvar);
document.onmousedown = this.mouseDown;
}
this.mouseDown = function(e)
{
alert(this.myvar); //does not work of course
//how could I access myvar from current myclass instance
}
}
var myclass_instance = new myclass();
myclass_instance.myvar = 'value'
myclass_instance.myfunc();
http://jsfiddle.net/E7wK4/
this in the mouseDown event is not the this of the instance.
Try this instead:
function myclass() {
var _this = this;
this.myvar;
this.myfunc = function()
{
alert(this.myvar);
document.onmousedown = this.mouseDown;
}
this.mouseDown = function(e)
{
alert(_this.myvar); //<<<<
}
}
Demo: http://jsfiddle.net/maniator/E7wK4/1/
As an alternative to #Neal you could bind this.
document.onmousedown = this.mouseDown.bind(this);
I've this piece of code:
function ActivityDialog(_divId, _title) {
function addButton() {
var buttonElement = document.createElement('input');
buttonElement.setAttribute('type','button');
buttonElement.setAttribute('class','button');
buttonElement.setAttribute('id','updateButton-' + id););
buttonElement.onclick = this.updateAction;
};
function updateAction() {
var buttonId = this.id; // correct: this is the Button
this.sendUpdateRequest(stringUrl); // not defined: Need to reference the current ActivityDialog!!!
};
function sendUpdateRequest(url) {
// something...
};
}
As you can see the problem is when I call function sendUpdateRequest; how can I, at the same time, retrieve button infos and call a function?
You might try this...
function ActivityDialog(_divId, _title) {
// Store the ActivityDialog context
var self = this;
function addButton() {
var buttonElement = document.createElement('input');
buttonElement.setAttribute('type','button');
buttonElement.setAttribute('class','button');
buttonElement.setAttribute('id','updateButton-' + id););
buttonElement.onclick = this.updateAction;
};
function updateAction() {
var buttonId = this.id;
self.sendUpdateRequest(stringUrl); // <---------------------
};
function sendUpdateRequest(url) {
// something...
};
}
Because your using updateAction as a event handler, you correctly see that this will be the button that generates the event. Storing the initial context of the ActivityDialog will allow you to maintain access to it even within event handlers.