Browse Category

Javascript

jQuery using $.on to call newly added elements

More than a year ago, I had written a blog about how to bind events to newly added elements using jQuery.

The scenario can be found here: http://blog.kongnir.com/2012/02/08/jquery-function-not-binding-to-newly-added-dom-elements/

In my previous solution, I had used $.live() in place of $.change(). However, as noted by a commenter in that blog, as of time of writing, $.live() is deprecated.

Instead, we should now use $.on() if you need to capture events of newly added elements.

For example, in normal circumstance, we would do this:

$(".existing-button").click(function() {
    alert("This will work if button already exist on load");
});

However, if you add new elements to the document using AJAX, then the above will not work. That button doesn’t exist.

In both circumstances, this will work:

$(document).on("click",".new-button", function() {
    alert("This will work even if element is newly added");
});

If you notice, the syntax is quite different. The element to call on is the containing element, not the element that the event is called. So let’s say “.new-button” is contained within “#main”, then the following should work too.

$("#main").on("click",".new-button", function() {
    alert("This will work even if element is newly added"); 
});

Reference: http://api.jquery.com/on/

Raphael.js IE7 issue with innerHTML on elements other than div

I kept having this unknown error on IE7 (IE9 compatibility mode) when I use Raphaël JavaScript Library. On deeper research, this error points me to line 5178’s “span.innerHTML”.

I found this very interesting article http://domscripting.com/blog/display/99 about usage of .innerHTML in IE7:

…innerHTML can cause some problems, particularly in Internet Explorer. If you use innerHTML to add or update form elements, all sorts of screwiness can occur. Sometimes the data from the newly added elements won’t be included when the form is submitted to the server.

and it provided a useful fix:

First of all, use the DOM to create a block level element—such as a div—using createElement. Then update the innerHTML property of this newly-created element. Finally, insert the updated element into the document using a DOM method like appendChild or insertBefore…

I thought it was a perfect fix, so I searched for the .innerHTML implementation in raphael.js (line 5178):

res.textpath.string && (span.innerHTML = Str(res.textpath.string).replace(/"));

and changed it to:

/*Resolve IE7 issue with innerHTML*/	
var newdiv = document.createElement("div");
res.textpath.string && (newdiv.innerHTML = Str(res.textpath.string).replace(/"));
span.appendChild(newdiv);
/*end of resolution*/

Somehow it worked very well. I had forked and submitted a fix but still waiting for the main master to commit this change. You can find the fix at my fork:
https://github.com/kongnir/raphael/compare/master…patch-1

jQuery function not binding to newly added dom elements

Updated (14 Nov 2013): $.live() is deprecated. I had written another blog on the new $.on() which will do the same. http://blog.kongnir.com/2013/11/14/jquery-using-on-to-call-newly-added-elements/

I was trying to use jQuery’s .append() function to insert some HTML code into a div.

This was the HTML (Example):

<div class="conditions-basic">
	<span class="function">
		<select name="someName"
                    id="someID" class="ddlSelect">
		<option selected="selected" value="1">1</option>
		<option value="2">2</option>
		<option value="3">3</option>
		</select>
	</span>
	// More elements here
</div>
<div class="conditions-more"></div>

The div class “conditions-basic” contains a select input. So when a user clicks on an ADD button somewhere, I want to duplicate the same select input in div class “condition-more” by doing this:

$('#btnAnd').click( function () {
	var appendHtml = $('div.conditions-basic').html().trim();
	$('div.conditions-more').append(appendHtml);
});

The select input will make some changes to its own newly appended elements. However, the .change() function doesn’t work for newly added elements.
Upon some research, I had read that instead of using .change(), we should use .live() instead.

Reason: live is a late-binding dynamic handler that can attach to elements added to the DOM after the handler is declared. See documentation for more info.

Instead of using .change() event directly like this:

$('.ddlSelect').change(function () {
    alert("this is not working");
});

Use .live() like this:

$('.ddlSelect').live("change", function () {
    alert("this is working");
});

Reference: http://stackoverflow.com/questions/6537323/jquery-function-not-binding-to-newly-added-dom-elements