I have two functions: one that creates a new <textarea> when a button is clicked, and a second function that performs an action when the <textarea> is clicked (or blurred, changed, etc.) That second function selects elements based on a class name. It seems that the second function only works on those matching elements that existed when the page was loaded, but it will not activate on any newly created <textarea> elements. Can anyone figure out why and how to fix this? You'll find the code below. Thanks. --Jake
$('#add').click(function() {
$(this).before("<textarea class='test'></textarea>")
})
$('.test').blur(function () {
alert('just a test')
})
The textarea you create isn't around at the time jQuery assigns the action to elements tagged with the .test class. You'll need the live() function to make this work as desired.
$('.test').live('blur', function () {
alert('just a test')
});
Now any element tagged with .test will automatically bind the specified function on blur no matter when it's created.
You can bind it directly:
$('#add').click(function() {
$(this).before("<textarea class='test'></textarea>").prev().blur(function () {
alert('just a test');
});
});
Or place use jQuery's .delegate() method to place a handler on the parent of #add.
$('#add').click(function() {
$(this).before("<textarea class='test'></textarea>")
}).parent().delegate('.test','blur',function() {
alert('just a test');
});
This is a more efficient approach than using .live().
Related
In framework7, how to add click event on dynamic elements?
If I add my element first on my view, the click event works fine like below:
<div class="test">Click Me</div>
$$('.test').on('click', function () {
myApp.alert("Gotcha!");
});
But if I have dynamic elements, especially elements dynamically added to virtual-list, I cannot make the click event to work. What is the right way to do this?
I even tried inline function, ex: <div class="test" onclick="myFunction();">Click Me</div>, still this won't work.
You can use:
// Live/delegated event handler
$$(document).on('click', 'a', function (e) {
console.log('link clicked');
});
For your case:
$$(document).on('click', '.test', function(e){
console.log('Some code...');
});
Here is docs. Scroll until events section.
Use this for dinamically added elements:
$$(document).on('click', '.test', function () {
myApp.alert("Gotcha!");
});
All answers are good to go with. But if you are using this class 'test' for other elements of the page, you will end up firing some extra click event(when you click on any other element of same class). So if you wanna prevent that, you should add listener to that particular element.
if you're adding an element of class test to an existing element of id testId, then use
$('#testId').on('click', '.test', function(this){
}
In the function where you dynamically add the new elements you have to assign an event handler for them.
Lets say you have a function something like this
function addNewLines(){
//add the new lines here
// you have to run this again
$$('.test').on('click', function () {
myApp.alert("Gotcha!");
});
}
I am trying to write some code for change() event using jQuery Text Editor (jqte), I have two functions which give jqte functionality to textarea's
One for editors loaded with JavaScript, when clicking some elements in a page:
function onLoadEditor(){
jQuery(".comment-editor").jqte({
// some jqte params, such as fsize: false,indent: false...
change: function(){ observeEditor(); }
});
}
And other, generic function, for pages with one single editor
jQuery(function() {
jQuery(".comment-editor").jqte({
// some jqte params, such as fsize: false,indent: false...
change: function(){ observeEditor(); }
});
});
I want to access the id of the concrete textarea (all textareas in the page have an id) which has fired the change() event
How should I write observeEditor() function to achieve this? Or... how I should define the function in jqte change property?
After reading this jQuery blur event with ID and value I have solved it, with following code (simplified)
function onLoadEditor(){
jQuery(".comment-editor").each(function(idx, elem) {
jQuery(this).jqte({
// some jqte params, such as fsize: false,indent: false...
change: observeEditor(elem.id),
});
}
jQuery(function() {
onLoadEditor();
});
But now I have another problem...
As you can read in the original question, onLoadEditor() is called when clicking some elements in a page. Then another javascript function jsComment() is called, builds a form (with a textarea.comment-editor field included) and it is rendered this way
function jsComment(){
...
var form = '<div class="comments_wrapper ... ';
jQuery(form).insertAfter(some_element).fadeIn('fast');
onLoadEditor();
}
Problem is change() event is being fired only once, when form fades in, while the idea is the opposite, event should fire when user adds some text, not when appearing... Any tips?
UPDATE
After reading Event binding on dynamically created elements? I have solved it this way
function onLoadEditor(){
jQuery('.comment-editor').each(function(idx, elem) {
jQuery(this).jqte({
// some jqte params, such as fsize: false,indent: false...
});
jQuery(document).on('change',
jQuery('.comment-editor'),
function(){
observeEditor(elem.id);
}
);
});
}
jQuery(function() {
onLoadEditor();
});
Although finally I am not using change() event, as it was being fired constantly. Performing better with keyup() & paste(), for instance
I am using Infinite Scroll to display some content and I'm having trouble binding some mouseenter/mouseleave events to the newly generated items.
I know that I need to bind .on to a container already existing on the page, but I'm having trouble figuring out the syntax to alter the current jQuery that toggles.
This is the current js:
$(document).ready(function() {
$('.grid-box .actions').hide();
$('.grid-box').on({
mouseenter: function () {
$(this).find('.actions').show();
},
mouseleave: function () {
$(this).find('.actions').hide();
}
});
});
The main container is #grid-container and each individual item is .grid-box. How can I alter the above so that the actions show/hide upon entering/leaving .grid-box?
I think I need something along the lines of this:
$('#grid-container').on('mouseenter mouseleave', '.grid-box', function(e) {
// some action
});
Exactly, this is known as event delegation and it waits for the event to bubble up then matches the event based on the selector. This is much more efficient because there is only one handler registered rather than N times the number of elements. Also, you only have to bind once rather than every time the dynamic content is changed.
$('#grid-container').on('mouseenter', '.grid-box', function(e) {
// some action
}).on('mouseleave', '.grid-box', function(e) {
// some action
});
The selector as the second argument will still work:
$('#grid-container').on({ ...}, '.grid-box');
http://jsfiddle.net/QkFTz/1/
An alternate method would just be to bind them separately, which I personally think is clearer:
$("#grid-container").on('mouseenter', '.grid-box', function () {})
.on('mouseleave', '.grid-box', 'function () {});
I was under the impression that jquery's on() reacted to events attached elements dynamically added to the dom (via ajax or cloning, etc). However, the following is only working for the element attached to the dom at page load. The other copy I make of it using clone() is not being, well, handled.
$(document).ready(function () {
$('.ship_via_dropdown').on('change', function () {
console.log($(this));
if ($(this).hasClass('prev_change')) {
console.log('has');
} else {
$(this).addClass('prev_change');
console.log('hasn\'t');
}
});
});
Code for cloning:
$(document).ready(function(){
var form1 = $('.line_item_wrapper').children().clone();
$('#new_line_content_1').html(form1);
});
HTML for dropdown (contents added by jquery db query on document ready)
<span class="select ship_via_select_container">
<select class="ship_via_dropdown ship_via_dropdown_1">
</select>
</span>
Thank you for any insight!
Either delegate the event instead:
$(document).on('change', '.ship_via_dropdown', function () {
console.log($(this));
if ($(this).hasClass('prev_change')) {
console.log('has');
} else {
$(this).addClass('prev_change');
console.log('hasn\'t');
}
});
Or better yet, use .clone(true) to clone with events. (Note: this will only work if you're cloning AFTER the event handler is attached.)
It does, but not in the way that you think. When used as you have used it:
$('.ship_via_dropdown').on('change',
It is really not different than using .change(). What you are looking for is event delegation. This takes the following form:
$("<selector to static ancestor>").on('change', '.ship_via_dropdown', function () {
Where <selector to static ancestor> is a selector to a static ancestor of the dynamically added elements. (one that is not dynamically created) As a last resort document can be used here. However for performance, this should be the closest static ancestor element.
jquery's on() reacted to events attached elements dynamically added
No - or at least, only if you use it with delegated events. The live method did always delegate events to the document.
Change this line:
$('.ship_via_dropdown').on('change', function () {
to this:
$(document).on('change',".ship_via_dropdown", function () {
I have a table with an ID of InstrumentListGrid. When a row is selected, it sets the class to ui-iggrid-activerow. I want to add a jQuery event on that row for when someone clicks it.
So far I have
$("#InstrumentListGrid tr.ui-iggrid-activerow").click(function (event) {
alert("YAY!");
});
but that isn't firing. How do I bind to an element by class?
since the class is presumably added dynamically you should use .delegate()
$('#InstrumentListGrid').delegate('.ui-iggrid-activerow', 'click', function (e) {
// do stuff.
});
It appears that ui-iggrid-activerow is dynamically added. Use the live() function:
$('#InstrumentListGrid tr.ui-iggrid-activerow').live('click', function() {
alert('YAY!');
});