Reputation: 1527
I'm trying to improve my understanding of javascript/jQuery function patterns. I've been playing with this simple demo in an attempt to get a revealing module pattern working.
Could anyone help me understand why this isn't working? I know that in reality you would solve just using CSS and that there are easy other ways to solve it - what I'm interested in is why my attempted solution doesn't work.
HTML
<body>
<p>Here is a test input element</p>
<form>
<label>Some label</label>
<input type="text">
<button>Click me</button>
</form>
</body>
</html>
jQuery:
$(document).ready(function(){
var roll = (function(){
function rollEnter(){
$("button", this).css("text-decoration", "underline");
}
function rollExit(){
$("button", this).css("text-decoration", "none");
}
return{
underlined: rollEnter,
standard: rollExit
};
})();
//When I try and call the functions, it doesn't work
$("button").on('mouseenter', roll.underlined());
$("button").on('mouseleave', roll.standard());
});
Any advice on what went wrong/how to get this type of pattern working?
Upvotes: 1
Views: 102
Reputation: 29271
There are two issues here:
you are invoking your callback functions in your event handlers, instead of allowing the event handler to invoke them.
// roll.underlined is invoked immediately
$("button").on('mouseenter', roll.underlined());
// roll.underlined is invoked when button emits the 'mousenter' event
$("button").on('mouseenter', roll.underlined);
You are passing an un-needed context to your jQuery selector in each callback
// nonworking: no need for "this"
function rollEnter(){
$("button", this).css("color", "red");
}
// working
function rollEnter(){
$(this).css("color", "red"); // $(this) is element event was triggered on
}
Upvotes: 4
Reputation: 11714
Found the fix. Get rid of the , this
up in the jQuery selector (I'm pretty sure it does not know what to do with this so it just doesn't do anything at all.) A helpful tip to keep in mind is that jQuery uses CSS selector syntax when trying to select jQuery elements so write it as if you were trying to apply CSS to it (in this case to a button)
Also remove the parentheses at the bottom because putting parentheses next to a method tells the code to call it immediately.
$(document).ready(function(){
var roll = (function(){
function rollEnter(){
//removed ", this"
$("button").css("text-decoration", "underline");
}
function rollExit(){
$("button").css("text-decoration", "none");
}
return{
underlined: rollEnter,
standard: rollExit
};
})();
$("button").on('mouseenter', roll.underlined); //<-- () removed
$("button").on('mouseleave', roll.standard); //
});
Upvotes: 1