How to detect all events added on a div - javascript

I am new to jQuery and such kind of js frameworks. Till now I used to do like this
<div onclick="function()"></div>
But in jQuery we get the element and add the event there. How can I detect all events added on a div?
I have a div whose height is set to the remaining height. Then I cant find appropriate css for that. I strongly believe that it has been done from javascript. I cant find relavant code any where. I dont know how to debug this.
Any help is highly appreciated.

To answer your question you can use:
jQuery._data( elem, "events" );
This will become an object of all events attached to the selected element.
This will return undefined when no event is attached to the element.
Note that this should be a single element, so for a class you should use:
$._data($('.class')[0], "events")
Which only select the first element with that class, instead of all the elements with that class.
jsFiddle
Source: jQuery find events handlers registered with an object

Related

Getting the width of a newly added element

I need to get the width of a newly added item using JavaScript or jQuery. I know if I need to bind an event to a newly added element I can use event delegation or the .on() method in jQuery. But in this case I’m not binding an event I just need to get the width of that element. How can I do that?
$('#box').width(); // won’t work
document.getElementById("box").width; // won't work either
To get the width
You can just use jQuery's .width() method:
$('#box').width() // Should give you the pixel width with no px/rem/%
// Or plain ol' Vanilla JS
document.getElementById('box').offsetWidth
// Or mix it up
$('#box')[0].offsetWidth
Possible issues
Make sure your element has been created, it is visible and you added it to the DOM.
Your element contains floated elements or absolutely positioned elements and therefore has not gained any width.
You're trying to retrieve the elements width prior to the DOM rendering.
Make sure your element is not affected by any stylesheet and has somehow become inline.
Loading issue
Make sure that your script is on the bottom of the page and/or you are using jQuery's .ready() method:
$(document).ready(function(){
$('#box').width();
});
// Shorthand for the above
$(function(){
$('#box').width();
});
Demos
VanillaJS Demo
jQuery Demo
If anyone can think of other issues or solutions please contribute to the answer.
Try this:
var box = document.getElementById('box');
alert(window.getComputedStyle(box).width);

Bind an event outside of DOM ready?

I'm trying to append a div to all dynamically added divs to my page using this code:
$('.tagged .post').append('<div class="fadeout"></div>');
but I simply cannot get it to work. So I was thinking, would it be possible to bind this outside of $(document).ready() somehow, so the code looks for all the elements that match the selector and append the "fadeout" div to them?
Edit: Check out this answer: Event when element added to page
Long story short, you have two options:
Continually check for the elements
Use Mutation Observers
The answer I linked to above has more details.

Handle stuff after dom changes

I've got a page with some Javascript / jQuery stuff, for example:
(function()
{
$('.tip').tooltip();
$('.test').click(function()
{
alert('Clicked!')
});
}();
On the page I insert some HTML with jQuery so the DOM changes. For example, I insert a extra element with the class "tip" or "test". The just new inserted elements doesn't work because jQuery is working with the non-manipulated DOM and the just inserted elements aren't there. So I've searched around and came to this solution for the "click":
$('body').on('click','.click',function()
{
alert('Clicked!')
});
I don't understand why, but this way it's working with the manipulated DOM and the jQuery stuff works on the new inserted elements. So my first question is, why does this work and just the click() function not? And the second question, why do I have to point to the "body"?
Finally, my third question is, how get this done with the tooltip?
I know that there is so many information about this subject (previous the delegate() and live() function I've read) but I can't found a explanation about it. And I can't get my third question solved with the information I found.
I'm looking forward to your responses!
Extra question:
4) Is it recommended to point always to the "body" for this kind of situations? It's always there but for possible performance issues?
So my first question is, why does this work and just the click()
function not?
Because the event handler is now delegated to a parent element, so it remains even after replacing/manipulating child elements.
Ancient article on event delegation for your perusal - but the concepts remain the same:
http://www.sitepoint.com/javascript-event-delegation-is-easier-than-you-think/
And the second question, why do I have to point to the "body"
You don't, any suitable parent element will do. For example, any direct parent (a div wrapper, for instance) which does not get replaced.
Finally, my third question is, how get this done with the tooltip?
You need to re-initialize your tooltip plugin on the newly inserted elements. For example:
$.get("foo.html", function (html) {
$("#someDiv").html(html);
$("#someDiv").find(".tip").tooltip();
});
The click() event doesn't work when you manipulate the DOM because JQuery is not watching for DOM changes. When you bind the click() event it is selecting the elements that are on the page at that time. New ones are not in the list unless you explicitly bind the event.
Because you have pointed the click() event on the body. JQuery then checks to see if the target of the click matches any of the event handlers (like what you have created) match the element clicked. This way any new elements will get the event 'associated' with them.
Because the tooltip isn't an event that you can place on the body, you will need to re-initialize it when the element is created.
EDIT:
For your fourth question, is it depends. The advantage of binding to the body is that you don't accidentally bind an event to an element more than once. The disadvantage is that you are adding event handlers that need to be checked on each event and this can lead to performance issues.
As for your concerns about DRY, put the initialization of the tooltips into a function and call that when you add them. Trying to avoid having the same function call is a little overkill in this regard, IMO.
Events are bound to the specific object you are binding it to.
So something like $('.tip').tooltip() will perform the tooltip() functionality on $('.tip') which is actually just a collection of objects that satisfies the css selector .tip. The thing you should take note of is, that collection is not dynamic, it is basically a "database" query of the current page, and returns a resultset of HTML DOM objects wrapped by jQuery.
Therefore calling tooptip() on that collection will only perform the tooltip functionality on the objects within that collection, anything that was not in that collection when tooltip is called will not have the tooltip functionality. So adding an element that satisfies the .tip selector, after the tooltip() call, will not give it the tooltip functionality.
Now, $('body').on('click','.click', func) is actually binding the click event to the body tag (which should always exist :P), but what happens is it captures whether the click event has passed through an element your target css selector (.click in this case), so since the check is done dynamically, new elements will be captured.
This is a relatively short summary of what's going on... I hope it helped
UPDATE:
Best way for your tooltip thing is to bind tooltip after you have added elements, e.g.
$('#container').load('www.example.com/stuff', function() {
$('.tip', $(this)).tooltip();
});

Jquery .children() not working as expected

I am trying to make a basic captcha module for jQuery. I have a decent start on it, but for some reason .children() doesn't seem to work. See it here: http://jsfiddle.net/pTbeW/
I currently have this:
$(this).children('.captchain-start').hide();
$(this).children('.captchain-show').show();
If I change it to
$('.captchain-start').hide();
$('.captchain-show').show();
it works perfectly. But this solution is less than ideal, because it wouldn't allow two instances of this captcha to be on the same page. I suspect it has to do with the html being set by query, but I'm not sure how. I'm far from a javascript and jQuery expert, but this seemed like a relatively easy thing to do. What am I missing? Do I have tired eyes from looking at it so long? Any help would be appreciated.
Because the '.captchain-*' elements are not children, but are siblings. Try the following:
$(this).nextAll('.captchain-start').hide();
$(this).nextAll('.captchain-show').show();
You should use $(this).nextAll() instead of $(this).children() because the elements you want to hide and show are not children of the a element, but siblings.
See http://api.jquery.com/nextAll/
this
In your click event references the clicked element, which is the element with the class 'captchain-start'. So you do not have to scan for the children, you can use:
$(this)
for the actually clicked element or the element selector instead
instead.

jQuery UI .trigger('click') not working

I've got a relatively complicated jQuery UI sortable, which I'm able to drag in elements from somewhere else. I'm using the following code, and am attempting to find the first element inside of what's been dropped with a class of editable, and trigger a click on it. This isn't working. I've thrown in some alerts and a console.log of ui.item[0].innerHTML returns an object with the correct DOM elements in it. So, I'm not quite sure what's going on here.
stop : function(event, ui){
$(ui.item[0].innerHTML).find('.editable').first().trigger('click');
}
Can anybody throw some of their wisdom my way? I'd greatly appreciate it. Just to note - if I click on the added element manually, it works as expected.
Thank you!
I would guess that you want just $(ui.item[0]) and not $(ui.item[0].innerHTML) because innerHTML returns the HTML syntax of the element ui.item[0] (a string) and not references to the DOM nodes like you want.
$(ui.item[0].innerHTML) creates a new element. So triggering an event on this element is useless.
Use $(ui.item[0]) instead.

Categories