Invoke a custom method on a DOM element - javascript

I want to invoke a custom method on a DOM element
like this :
<div id="MyObject">
<!-- some elements -->
</div>
<script>
function doSomething() {
// do something with input DOM element
}
$("MyObject").doSomething();
</script>
How can I develop this problem? Is it necessary to use jQuery or not?

You do not need to use jQuery. You can use document.getElementById('MyObject') to get a reference to the DOM node.
To run your doSomething function on it, you would need to add a node parameter to it something like this:
function doSomething(input) {
// do something with input DOM element
}
doSomething(document.getElementById('MyObject'));
To have it chained, you would need to add to the Element interface which all DOM nodes implement (rereading, I meant inherit from). If you go that way, you could do:
Element.prototype.doSomething = function() {
alert(this);
}
document.getElementById('MyObject').doSomething();
JSFiddle: http://jsfiddle.net/6Lyb4b9p/
MDN: getElementById

Without jQuery, you could do something like
if (typeof $ != 'function') {
//create a function $ which will return the element with said id
window.$ = function(id) {
return document.getElementById(id);
}
}
//Add a method to the Elemen prototype so you can call it on any element object
Element.prototype.doSomething = function() {
this.innerHTML = 'hi from inner';
}
$('MyObject').doSomething();
<div id="MyObject">
<!-- some elements -->
</div>

I found the answer by myself.
I can practice in this way :
<script>
(function ($) {
$.fn.doSomething = function () {
// do something like this
$(this).append("Hello Object");
}
} (jQuery));
$("#MyDOMElement").doSomething();
</script>

Related

not able to get ID of calling element in jquery

I need to get the id of element calling the function,
I have a div like this,
<div id="MainDiv"></div>
Below is the jQuery code,
when i keep a breakpoint and type this I get the things info about the div, but I am not sure of how to get its id, i.e this.id
$(document).ready(function () {
$("#MainDiv").Scrollit();
});
$.fn.Scrollit = function (e) {
alert(this.id);
};
Inside the plugin this refers to the jQuery object, not a dom element so it does not have the id property.
You can iterate through the jQuery object using .each() and get the each element's properties - because the plugin can be initialized on a set containing more than one element
$.fn.Scrollit = function (e) {
this.each(function () {
alert(this.id)
})
};
Demo: Fiddle
Few pointers though
If you are developing a plugin don't depend on the id of the elements, use options or data attributes to pass informations
Also return the jQuery object back to enable chaining
$.fn.Scrollit = function (e) {
return this.each(function () {
alert(this.id)
})
};

Find parent element in JQuery event

I've added a click event as follows and would like to check if the target has a specific parent.
$(document).click(function(event){
// Check here if target has specific parent for example -> #parent
});
How can this be done?
There's a .parent() dom traversal method for this.
according to Pointy's crystal ball, you probably want to do something like this:
$(document).click(function(event) {
if ($(event.target).parents('.selector').length > 0) {
}
});
I'm not sure why are you set click handler on document, maybe looking for event delegation and the .on()?
I believe this also works.. AFAIK jQuery events use the the literal element instead of a jQuery object when calling events. Basically this should be your normal DOM element with normal JavaScript properties.
$(document).click(function(event)
{
let myparent = $(this.parentNode); //jquery obj
let parent = $(this.parentNode)[0]; //plain DOM obj
let myself = $(this); //jquery obj;
let $elf = this; //plain DOM obj
});
Note: sometimes using 'self' as a variable is bad/causes conflicts with certain libraries so i used $elf. The $ in $elf is not special; not a jQuery convention or anything like that.
$(document).click(function(event){
var $parent = $(this).parent();
// test parent examples
if($parent.hasClass('someclass')) { // do something }
if($parent.prop('id') == 'someid')) { // do something }
// or checking if this is a decendant of any parent
var $closest = $(this).closest('someclass');
if($closest.length > 0 ) { // do something }
$closest = $(this).closest('#someid');
if($closest.length > 0 ) { // do something }
});
I have reliably used this in the past:
var target = $( event.target )
This will give you a reference to the jQuery object for the element that had the event invoked. You could use this same approach and see if the parent is "#parent", something like this:
var target = $( event.target )
if (target.parent().attr('id') == "#parent") {
//do something
}

Get element under a selector with jquery

I have a selector where I get the first element like that:
$("#MyControl")[0]
Is it possible to get the element with a function other than accessing the elements like a array?
What I want to do with that is to pass this element to a function with .call() to defines the context.
Here is an example:
$(document).ready(function () {
$(document).on("change", "#MyControl", setActivityControlsState);
});
setActivityControlsState: function () {
var selector = "#automaticActivityCreation";
if ($(selector).length > 0) {
if ($.isNumeric(this.value) && this.value > 0)
$(selector).show();
else
$(selector).hide();
}
}
referenceFormOnSuccess: function (data) {
setActivityControlsState.call($("#MyControl")[0]);
}
As you can see in the refreshFormOnSuccess function, I must defines 'this' with $("#MyControl")[0].
I just want to know if is there a better way to do that.
Note that I don't want to access the value of my control with something like $(this).val()
May I suggest a small re-structuring that mitigates that need:
$(document).ready(function () {
$(document).on("change", "#MyControl", setActivityControlsState);
});
setActivityControlsState: function () {
// cache jquery object instead of just the selector
// for better memory management
var automaticActivityCreation = $("#automaticActivityCreation");
if (automaticActivityCreation.length > 0) {
if ($.isNumeric(this.value) && this.value > 0)
automaticActivityCreation.show();
else
automaticActivityCreation.hide();
}
}
referenceFormOnSuccess: function (data) {
// fire the change event which will tap
// the listener you set up in .ready
$("#MyControl").trigger('change');
}
but if you really want to get the object with jquery you do have some options:
// jQuery select #MyControl and get as dom element with array
$("#MyControl")[0]
// jQuery select #MyControl and get as dom element with .get
$("#MyControl").get(0)
but because you are using an element with an ID and you can only use a single ID at a time you really don't need jquery for this
document.getElementById('MyControl')
or
referenceFormOnSuccess: function (data) {
setActivityControlsState.call(document.getElementById('MyControl'));
}

assigning click method to variable

I am creating an array & assigning the value to each index in a function through variables.
I also want to attach a jquery click method to each variable. However, I am getting 'undefined' in return when the click method is called.
var i = 0;
var eCreditTransactions = new Array(6); // 6 members created which will be recycled
function abc()
{
addingElements (i);
}
/* **** THE FOLLOWING IS THE PROBLEM AREA **** */
$(eCreditTransactions[i]).click (function () // if user clicks on the transaction box
{
creditTransactionSlideIn (eCreditTransactions[0], 150); //another function called
});
/* **** this is the function being called in the first function above **** */
function addingElements (arrayIndex) // func called from within the 'createCreditTransaction()' func
{
eCreditTransactions[i] = $(document.createElement('div')).addClass("cCreditTransaction").appendTo(eCreditSystem);
$(eCreditTransactions[i]).attr ('id', ('trans' + i));
$(eCreditTransactions[i]).html ('<div class="cCreditContainer"><span class="cCreditsNo">-50</span> <img class="cCurrency" src="" alt="" /></div><span class="cCloseMsg">Click box to close.</span><div class="dots"></div><div class="dots"></div><div class="dots"></div>');
creditTransactionSlideOut (eCreditTransactions[i], 666); // calling slideOut animation
counterFunc ();
return i++;
}
Try this:
$(document).ready(function() {
$(".cCreditTransaction").click(function() {
//do what you want on click event
});
});
Hope it helps
Given that it looks like each element you're adding to the array has a classname (cCreditTransaction) you can hookup the click events using something like
$(document).delegate(".cCreditTransaction", "click", function() {
// code to fire on click goes here.
});
or in jQuery 1.7+ you can use .on instead of .delegate
You don't then need to hook up n events, but just one event that matches all items in the selector (in your case, the class name)
You should also change $(document) to a container element that has an Id, so that the DOM traversal to find the classes is trimmed down as much as possible. Why? Because finding elements by class name is a relatively expensive procedure, as opposed to finding tags or even better, an ID.
it looks like there should be a loop in this part:
function abc()
{
addingElements (i);
}
there is a call to addingElements, and an 'i' parameter being passed, but 'i' is at that moment still defined as 0.
it should say something like
function abc()
{
for (i=0;i<=7;i++)
{
addingElements (i);
}
}

Best way to modify an element that is not yet created

I have an <input> field in my web page, and I want to add a particular method on it, let say fooBar().
Here is what I do:
<input id="xxx" .../>
<script type="text/javascript">
$("xxx").fooBar = function() { ... };
</script>
This works well. However, for some reasons I will not detail here (in fact the HTML is generated by JSF components), the <script> will be declared before the <input> tag.
So in others words, I will have that in my HTML:
<script type="text/javascript">
$("xxx").fooBar = function() { ... };
</script>
<input id="xxx" .../>
So of course this code will not work correctly, as the script will try to get ($("xxx")) and modify an element that does not exist yet.
If I want to stick on the exact order of these two tags, what is the best way to accomplish what I want?
Edit
In my case, $ refers to prototype, but I am also using jQuery in my application. And I must be compatible with IE6 :o(
You need to run your script after the document is loaded. With jQuery you'd do that with:
$(document).ready(function () {
//do stuff here
});
I can't tell which library you're using here, but they all have an equivalent of jQuery's document ready.
Here's the prototype equivalent:
document.observe("dom:loaded", function() {
// do stuff
});
Try putting your code in load event:
$(window).load(function(){
$("#xxx").fooBar = function() { ... };
});
If the code has to be directly before the input, you can check if it has loaded after a certain period of time.
<script type="text/javascript">
//Sets up a function to execute once the input is loaded
f = function ()
{
//Checks if 'xxx' exists (may vary between frameworks)
if ($("xxx") !== undefined)
{
$("xxx").fooBar = function() { ... };
//Escapes the timer function, preventing it from running again
return true;
}
//If still not loaded check again in half a second (0.5s or 500ms)
setTimeout(f,500);
return false;
}
f();//Initialize the timer function
</script>
<input id="xxx" .../>
Instead of adding a method to the dom node, why not make it a separate function, so instead of
$("xxx").fooBar = function() {
doStuff(this);
};
you would have something like
function xxx_fooBar () {
var me = document.getElementById('xxx');
doStuff(me);
};
Another suggestion: If you can add attributes to the <input> element, you could do something like this...
<script>
function xxx_init (e) {
e.fooBar = function () {
doStuff(this);
};
}
</script>
<input onload="xxx_init(this)" id="xxx" .../>
Or you could do as others suggest and attach the scripts to the window.onload event.

Categories