Check if any element is appended to parent - javascript

I am cloning a div and appending it to a parent div on different button click. this cloning and appending event is happening from different different JS files, so I want an event to be triggered when element is added to parent div. One method is to go and add the same code or call a function different places. I was wondering if there is an inbuilt function in jquery which will be triggered when any child is appended to it. Following is my code(Fiddle)
JS/Jquery:
$('.but').on('click',function(){
$('.sample').clone(true)
.removeClass('sample')
.addClass($(this).text())
.appendTo($('.parent'));
$('.rem').fadeIn();
});
$('.rem').on('click',function(){
$('.parent').children('.com:last-child').remove();
});
/*this is my conventional code this will be trigged every time when new element is added to parent div
if(elements are increased in parent div){
do your thing
}
*/
HTML:
<div class="button-wrp">
<div class="but cm">red</div>
<div class="but cm">green</div>
<div class="but cm">blue</div>
<div class="rem cm">Remove</div>
</div>
<div class="parent"></div>
<div class="sample com"></div>
If you want to see all this thing working, please click on fiddle link

You can use the jQuery event system. This would the idea:
First you set your listener:
$( 'div' ).on( 'child_appended', function(){
// this is your parent with a new child
var parent_with_new_child = this;
} );
And then when you append a new child you can to this:
$( '.parent' ).append( $( '.child' ) ).trigger( 'child_appended' );
For more reference go here

Related

jQuery .html() not setting html at all

I have a simple thing. When a user clicks on the edit link it turns the previous element into an input element for editing and the edit into a cancel. If the user decides not to edit he can click on cancel and everything should revert to its initial state.
Right now this is not working at all:
$('.cancel').on('click', function() {
$(this).parent().html("<a href='#'>edit</a>");
});
HTML:
<div class='photo-section'>
<div class='photo-head'>
<div class='photo-info'>
Photo Name : <span class='photo-name'>Work selfie</span>
<span class='title-edit'><a href='#'>edit</a></span>
</div>
</div>
<div class='photo'>
<img src='' alt='' title=''>
</div>
<div class='tag-section'>
<div class='tags'>Photo Tags:
<span>#code#coffee#late#night</span>
<span class="tags-edit">edit</span>
</div>
</div>
</div>
CSS:
// JavaScript to handle photo operations
$(document).ready(function() {
// show/hide edit option
$('.photo-info, .tags').hover(function() {
$(this).find('.title-edit > a, .tags-edit > a').addClass('visible');
}, function() {
$(this).find('.title-edit > a, .tags-edit > a').removeClass('visible');
});
// show editable area
$('.title-edit, .tags-edit').on('click', function () {
edit(this);
});
});
function edit(elem) {
// change element into an input elemnt for editing
var $item = $(elem).prev();
var text = $item.text();
$item.html("<input type='text'>").find('input').attr('value', text);
// change edit to cancel if input element present
if ($('input').length) {
$item.next().html("<a href='#' class='cancel'>cancel</a>");
}
// change cancel back to edit
if ($('.cancel').length) {
$('.cancel').on('click', function() {
$(this).parent().html("<a href='#'>edit</a>");
});
}
}
Result: https://jsfiddle.net/hgwkxygz/6/
Any help would be great!
This is a very common case of attaching event at wrong time in javascript.
Actually you are removing and re-adding a DOM element. So the already attached event to .cancel won't work this time. You again have to write event listener on .cancel whenever you attach a new DOM element after clicking on edit button.
Basically it means whenever you do .html(), you have to re-add event listener for click.
There are various approach to solve this problem.
1) make a function which attach the DOM element as well as click event to that DOM element. Call that function only on click events.
2)Do event delegation.
3)Do not remove DOM elements on click events, rather hide and show elements so that you wont loose your event listeners.
4)If you really have to do remove and re-add DOM elements then in my opinion, best approach is to make a class, where you make DOM elements, add event listeners privately in that class, and on click events just make new instance of that class.
You can check out these options in detail on web.

JQuery .remove() doesn't work on dynamic added element

I have a problem removing element from page.
When I click on a button on a page it adds div like this:
<div class="holder-div" style="position: relative;display: inline-block;">
...
<i class="RemoveMeAndParent"></i>
</div>
And when I click on RemoMeAndParent I want to remove what I added:
$('body').on('click', '.RemoveMeAndParent', function () {
$(this).closest('div').remove();
But this doesn't remove holder-div no error no nothing.
Just for a test I called .empty() and it work.
So why removing this div is not possible?
This is how I added it to the page:
var $this = $(this);
var newElement = $('<div class="holder-div" style="position: rel...');
newElement.prependTo($this);
put the remove function and wrap it in another function and recall that function when you've added the dynamic element.
The function is probably wrapped in a document ready which waits till the dom is is finished loading so it has all the elements. if you add an element after that javascript didn't register it or something. so if you would wrap that remove function in another function and call that after you've added the dynamic element it should work.
Please check this fiddle for answer:
http://jsfiddle.net/cq3vd0yx/6/
The problem is not that element can not be removed, but its rather that event binding dynamically is failing. For dynamic event binding using jQuery, use this syntax:
$(document).on( eventName, selector, function(){} );

Masonry - deleting elements by clicking on something else, than the element itself

In Masonry, it is possible to delete an element by clicking on it. The catch is, that You have to click directly on that element - so if you use these "bricks" as an image gallery (as long as these photos are included as a background image) You can delete them, by clicking on the element. The problem is, when you use these as some messages/info/other content containers. Then, due to formatting-related stuff the parent element gets "hidden" behind other tags, and You can't actually click on it.
The problem is shown here:
http://jsfiddle.net/dan1410/SfU5T/
You can close red boxes, but not green ones, as they are overlapped by another elements.
I've tried code like:
eventie.bind( container, 'click', function( event ) {
// don't proceed if item was not clicked on
if ( !classie.has( event.target, 'closeable' ) ) {
return;
}
// remove clicked element
msnry.remove( event.target );
// layout remaining item elements
msnry.layout();
});
});
and
var todelete = document.querySelector('.closeable');
eventie.bind( container, 'click', function( event ) {
// remove clicked element
msnry.remove( todelete );
// layout remaining item elements
msnry.layout();
});
});
but You still have to click directly on the element You'd like to close...
My masonry content structure looks like
<div id="masonry" >
<div class="item blue closeable">
<div id="itheader"><h2 class="secsectiontitle">Space available</h2></div>
<div id="itcontent">
some statistics here...<br/>
and here, too
</div>
</div>
Only elements with .closeable class are supposed to be closeable.
So, the question is: how to close an element using a button/a link?
I'm not very familiar with JS, so I'd like to ask You guys for help. Thank You in advance!
Unless there are handlers that stops the propagation of the click event on children elements, the click event should bubble up without any issues.
Also, if you are using jQuery, you should use the jQuery Masonry's API.
Note: I couldn't access your fiddle and couldn't test the solution
var $container = $('#masonry').on('click', '.closeable', function (e) {
$container.masonry('remove', e.currentTarget);
$container.masonry(); //layout
$container.masonry('reloadItems'); //OP said it was also required
});

click event being removed on previous elements

answer:
/* I bound the events via the parent instead of binding it
on each span tag individually. this allowed me to manipulate
the span tags uniquely. ( thank you Jason P ) */
$( '.selected-option-wrapper' ).on( 'click', 'span', function() { });
disclaimer:
I am losing my mind.
details:
I am trying to list in html a bunch a options that a user selected via a ul/li dropdown. I want the user to click on a li a and have part of the html within the a tag, placed in a separate div.
For example:
html
// html within the li tag that I want cloned over
<a id="met" class="item-1" href="#">
<div class="left check-wrapper">
<span class="gicon-ok"></span>
</div>
<div class="hide item-display"> // exact element to be moved over
<span class="gicon-remove-sign left remove-option-item"></span>
<div class="left">Metallic Thread</div>
</a>
javascript
$( '.options' ).find( 'a' ).on( 'click', function( e ) {
ind_option_html = $( this ).find( '.item-display' ).clone();
/* attach a click event to the span tag */
ind_option_html.find( 'span' ).on( 'click', function() {
console.log( this );
});
/* this is in a $.each loop that appends each new ind_option_html */
$( '.selected-option-wrapper' ).show().append( ind_option_html );
});
problem
whenever I click just one li a the function fires fine, the this for the span tag is logged out. but what is amazing is that when a user clicks another li a the click event is placed on ONLY the most recent span tag.
Where is the onclick event going with the first span tag?
I'm not sure why you're having the problem you are, but you can probably avoid it using event delegation. Instead of binding the event handler each time, do it like this when the DOM is ready:
$('.selected-option-wrapper').on('click', 'span', function() { ... });
See on(), and the section about direct and delegated events.
Where is the initial var ind_option_html (or is it an accidental global)? Looks like all of the instances of the click handler use the same reference, which is always the last one to be processed.
So your fix would be:
ind_option_html = $( this ).find( '.item-display' ).clone();
to:
var ind_option_html = $( this ).find( '.item-display' ).clone();

javascript link opens the second time I click it

I have a javascript link I want to open, but it is only working the second I click on it. I want to click a Div I have created for this, and there are no anchor tags involved.
The HTML I use:
<li>
<div class="artikel_box_lk">
<div class="button" rel="$productNameSeo">
<span>More Info >></span>
</div>
</div>
</li>
The javascript code I use for this:
$(function(){
$(".artikel_box_lk").click(function(e) {
if($(e.target).hasClass("button")) window.open("/lk/" + $(e.target).attr("rel"), "_blank");
return false;
});
});
So, the strange thing happening is that if I click on it a couple of times it sometimes works. I must have forgotten something crucial here, but cannot seem to find out.
Try to add .button to your click selector:
$(function(){
$( ".artikel_box_lk .button" ).click(function( e ) {
window.open( "/lk/" + $( this ).attr("rel"), "_blank");
});
});
I suppose first time you click outside .button div
It's because you say if the e.target has class name of "button"; that would only be true when you click in areas where the span element and its' parent don't overlap. When you click on the span element, it would say the "target" is the "span" element and it does not have the class name "button". Always do a console.log($(e.target)); to debug the issue.

Categories