new to writing a function in jquery, just testing the waters.
I have this just to to demo:
(function ( $ ) {
$.fn.update_notifications = function( options ) {
// This is the easiest way to have default options.
var settings = $.extend({
// These are the defaults.
user_id: 0,
}, options );
alert('test');
};
}( jQuery ));
Which I include in a JS file included before the tag. What I want to know, is how to actually call it inside my html?
I was thinking something like:
<script type="text/javascript">
jQuery.update_notifications({
user_id: 1
});
</script>
But that tells me "jQuery.update_notifications is not a function"
You want to call it on selected element like this:
$("some_element").update_notifications();
You can find more here at the official documentation.
No, the function is not part of the jquery object, but of its fn child object
$.fn.update_notifications();
However, it doesnt make sense to add something to the jquery prototype if youre not doing sth jqueryobjectbased
To fix the issue you simply need to change $.fn.update_notifications to $.update_notifications. The $.fn namespace is used for attaching functions to instances of jQuery objects.
(function($) {
$.update_notifications = function(options) {
var settings = $.extend({
user_id: 0,
}, options);
console.log('test');
};
}(jQuery));
jQuery.update_notifications({
user_id: 1
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
That being said, your example is a little redundant as you've just wrapped the existing $.extend() function without adding any real logic - although I assume this is a work in progress.
If your function has nothing to do with any DOM elements, i would suggest you not to pollute jQuery. You can very well declare this function some where else (page, separate JS file etc.).
But if you still want to do this, you can try these
$.update_notifications();
or
$(window).update_notifications();
or
$(document).update_notifications();
Why are you exactly extending the Jquery object?
Usually, lacking a valid reason to do so you would simply write a function inside your script.
Let's assume you have a valid reason and proceed:
Once you bind your function to $ or better create object like $.custom and bind the function (and rest of custom things you wanna bind to Jquery) you can use it like a normal function - only prefix it with $.custom
Not sure I understand your question but are you searching how to run that function from HTML other than using jquery?
Are you asking for an example like this?
<p id="onThis" onclick="$.custom.yourFunctionName()">Click me.</p>
That is obtrusive JS code and is not best practice when dealing with Jquery.
You wanna bind that function to element with on or click handler when document is ready:
$(document).ready( function() {
$('#onThis').on('click', function here);
// OR //
$('#onThis').click(function here);
});
If there is no reason to bind it to jQuery, don't do it you are only implying to someone reading your code something that doesn't exist ;)
Related
I want to create some events in javascript, but what I want is to be able to use them with jQuery objects because I want to do a framework and it has to be easy to use.
What I want is something like this:
function myEvent() {//code here}
$("#myObject").myEvent()
And trigger the event there, of course I want to know how to get the object which triggered it because I can't do anything without it.
I think that I might have to extend a prototype, but I'm not sure about that.
Can anyone help me? Thank you!!
I think you mean custom methods. Events work differently in JavaScript then what your code is trying to display. You can extend jQuery functions like this:
jQuery.fn.extend({
check: function() {
return this.each(function() {
this.checked = true;
});
}
});
// Use the newly created .check() method
$( "input[type='checkbox']" ).check();
DOCS: https://api.jquery.com/jquery.fn.extend/
JoshSpears' answer is perfect. Check also this one, I think you'll find easier to implement (just C&P):
Assuming you have, for example:
var myEvent = function(str) {
alert(str);
};
And you want something like:
$('div').myEvent('hey guys!');
Just implement this:
$.fn['myEvent'] = function( options ) {
return this.each( function() {
myEvent(options);
});
};
This is just a simplification of the jquery plugin pattern wrapper. Check it out here:
https://github.com/jquery-boilerplate/jquery-boilerplate/blob/master/dist/jquery.boilerplate.js
I am going to wrap some of my functions in a nice manner and for this I want to go with jQuery approach. Like jQuery having a lots of methods
$.parseJson()
$.ajax()
$("div").text("hey my testing");
and both methods are present in a same jQuery file. But while reading about how to make a jquery plugin, its specified that you don't need to create multiple functions inside a same plugin. Instead pass an argument which contains the method name as string.
So, Is that the below snippet is correct or do i need to make some corrections in it.
<script type="text/javascript">
(function ($) {
$.fn.testMethod1 = function () {
return $(this).each(function () { });
};
$.fn.testMethod2 = function () {
return $(this).each(function () { });
};
$.test = function () {
return "testresult"
};
})(jQuery);
$("div1").testMethod1();
$("div2").testMethod2();
$.test();
//Is that needed to be replace in a different way like
$("div1").myPlugin("testMethod1");
$("div1").myPlugin("testMethod2");
$("div1").myPlugin("test");
</script>
The second way is preferred because it conserves namespace in the jQuery object.
Read the official jQuery doc for this: Plugins/Authoring
Have you try using jquery boilerplate. It is a good point to start study jQuery plugin development. It's provide a safe and(seem to be) a good solution to create a plugin. They use your second way to call a method.
(function($) {
$.fn.myFunction = function(config) {
var defaults = {
setting1: 'myDiv',
setting2: ''
};
var config = $.extend(defaults, config);
//code here
};
})(jQuery)
$(document).ready(function() {
$.fn.myFunction({
setting1: 'myDiv',
setting2: ''
});
});
This is how I've been using jQuery plugins, but I recently learned it should be used like:
$('#myDiv').myFunction({
setting1: 'myDiv',
setting2: ''
});
1) I take it this allows the usage of $(this) for $('#myDiv')?
2) Is $(document).ready(function() required?
3) Is there anything detrimental about the way I have been using this jQuery function?
4) If $('#myDiv').myFunction() is the proper usage, how would you call the function if it is simply a function to run at document ready - see my usage here: https://stackoverflow.com/a/12316349/1455709. Is this simply an incorrect usage of the function?
Calling $.fn.myFunction() and calling $('#myDiv').myFunction() are two different things. There is no right or wrong - it depends upon what you're doing.
Calling $.fn.myFunction()
This is essentially a static function and you can use it like that if you want. In the jQuery world, .fn is like .prototype so $.fn.myFunction() is like calling jQuery.prototype.myFunction(). It is allowed, but it's a static function call that is not associated with a specific jQuery object. If you just want a static function call, then you can do this, but this is not normally how the jQuery prototype is used and I would not generally recommend it. If you just want a static function and want to use the jQuery namespace, you can just do this:
$.myFunction = function(args) {/* your code here */};
and then call it like:
$.myFunction();
As there is no need to use the prototype at all.
Calling $('#myDiv').myFunction()
The prototype (e.g. .fn in the jQuery world is used when you want to add methods to actual jQuery objects.
When you do this $('#myDiv').myFunction() is a member function of a live jQuery object. You can refer to this inside the myFunction() implementation and it will be a jQuery object that, in this case holds the DOM object that corresponds to id="myDiv". If you return the jQuery object from your method, you can also use chaining.
Which to Use?
If your code operates on a jQuery object, then it should be a method on a live jQuery object and it should access this to get at the jQuery object instance data and you should declare it as $.fn.myFunction = function() {}; and call it as$('#myDiv').myFunction()`.
If you code does not operate on jQuery object and is just a utility function that you call and it doesn't always operate on a jQuery object, then, you should declare it as $.myFunction = function() {}; and you should call it as $.myFunction().
Yes, as well as proper chaining if you return this from inside your function.
Yes, if your code is run before the dom is loaded.
It's not really jQuery, it doesn't work how people would expect it to. Somebody could call it as $('#myDiv').myFunction() and it wouldn't perform as expect.
If you want a function that you can just run any time, don't add it to the jQuery prototype ($.fn). Instead you could add it onto $ like the other jQuery functions that don't require selectors, $.trim for example. Then you could call it like this: $.myFunction(options);
I am writing the a generic function for my website using jquery which would be used over the entire site for displaying a success/error message. I decided to make it a plugin.
A simple form of the plugin is given below:
; (function ($) {
jQuery.FlashMessage=function(msg){
alert(msg);
}
})(jQuery);
I wanted to know whether it is a good practice to define plugins in the jquery namespace or should it defined under $.fn.XXXX ..or am i overthinking and it doesn't matter it at all.
You add those functions to jQuery.fn which should be run on selected elements, e.g. $('div').yourFunction().
If you want a "generic" function, like $.ajax(), then you should add it to the jQuery object, like you already do. But I would use $ inside the function:
(function ($) {
$.FlashMessage=function(msg){
alert(msg);
}
})(jQuery);
So it depends on what kind of functionality you want.
jQuery.fn is equivalent to jQuery.prototype
with jQuery.fn.FlashMessage you can do
jQuery.fn.FlashMessage=function(){
return this.each(function(){
//do some thing
});
});
//use like this, your chaining is secured
jQuery('#someElement').FlashMessage().DoSomeThingElse().SomethingMore();
if you are concerned is modifying only one element than why to use jQuery.FlashMessage, do it like myNameSpace.FlashMessage
Typically plugins on the fn namspace return a jQuery object to maintain chainability. Also they are applied to jQuery.prototype so all jQuery objects can call it.
Check out this page for a very good overview on plugin authoring: http://docs.jquery.com/Plugins/Authoring
I like to organize my javascript in namespace style like below. What I want to know : is there another (shorter?) way to call myFirstFunction() from mySecondFunction()? I tried this.myFirstFunction() and it's not working so maybe there's some kind of mysterious trick here that I don't know.
var myNameSpace = {
myFirstFunction: function(){
alert("Hello World!");
},
mySecondFunction: function(){
myNameSpace.myFirstFunction();
}
}
Thanks for your help as usual, people of SO! :)
As written in your example code, this.myFirstFunction() would work. Your code is likely simplified to illustrate your problem, so it would probably help to see the actual code to tell why it doesn't work with this.
One possible reason that it fails would be if the code where you call this.myFirstFunction() is inside a closure. If so, this would be a reference to the closing function, not your namespace and would therefore fail. See here for a contrived example based on your code to see what I mean. Again, having a look at the actual code would probably be helpful to diagnose what's going on.
Your suggestion to use 'this' should work. i.e.:
var myNameSpace = {
myFirstFunction: function(){
alert("Hello World!");
},
mySecondFunction: function(){
this.myFirstFunction();
}
}
Result:
myNameSpace.mySecondFunction() // "Hello World!".
If you want it to be shorter maybe you should consider the following pattern:
Javascript Design Pattern Suggestion
basically for your example:
var myNameSpace = (function()
{
function _myFirstFunction(){
alert("Hello World!");
}
function _mySecondFunction(){
_myFirstFunction();
}
return {
MyFirstFunction : _myFirstFunction,
MySecondFunction : _mySecondFunction
};
})();
I find this to be the cleanest pattern, also providing "private/public" variables in javascript that's otherwise pretty much impossible
In some cases the this keyword should work fine. If you explicitly call myNameSpace.mySecondFunction() then this.myFirstFunction() will execute as intended.
If you are using myNameSpace.mySecondFunction as an event handler it likely will not. In the case of an event handler you would need some way to refer to the namespace you want to use. A lot of JavaScript frameworks provide a way to define what the this keyword refers to. For example, in MooTools you can do myNameSpace.mySecondFunction.bind(myNameSpace) which will cause this to refer to myNameSpace inside mySecondFunction. If you are not using a framework you could make your event handler an anonymous function like:
document.getElementById('myId').addEventListener('click', function(e) {
myNameSpace.mySecondFunction.call(myNameSpace);
});
For more information on the call method I would refer to the MDC page for the call function or you could use apply which behaves similarly to call but passing an array of arguments for the second paramter rather than having a varargs like approach for additional parameters.
All of these suggestions are predicated on defining your namespace as #Harnish suggested:
var myNameSpace = {
myFirstFunction: function(){
alert("Hello World!");
},
mySecondFunction: function(){
this.myFirstFunction();
}
}
For more information about JavaScript function binding I'd highly suggest reading Justin's article on Function scope and binding in JavaScript
If you are attaching to event:
possible issue could be if you are attaching Namespace's function to event, like:
$(el).on("click", nameSpace.myFunc);
....
nameSpace = {
myFunc: function(){
this.anotherFunc();
}
}
that will throw error.
Solution 1
You may change this.anotherFunc() with nameSpace.anotherFunc()
Solution 2
You might change
$(el).on("click", nameSpace.myFunc);
// to ----->
$(el).on("click", function(){ nameSpace.myFunc(); } );