Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Appended div isn't part of the DOM

I have a <div>; it contains a <span>. When you click on the <div>, it removes the span, and replaces it with a <div> containing an <input> and a <button>. This is all well and good.

The <button>, when clicked is supposed to remove its parent <div> (the appended one) and replace it with a <span> again, but something is wrong. It seems that the parent <div> isn't a part of the DOM!

Anyway, here's a quick example:

<div id="myPage">
    <div id="clickMe" class="selectedField editMe">
        <span>Click Me</span>
    </div>
</div>

Some HTML, nothing too fancy. Though, since the DOM is gonna keep changing, I used .on to delegate the events. Here's the JavaScript:

$(function(){
    $('#myPage').on('click', '.selectedField', function () {
        if($(this).hasClass('editMe')){
            var $this = $(this).toggleClass('editMe editing'),
                $input = $('<input/>', {
                    placeholder: 'type something...'
                }),
                $cancel = $('<button></button>', {
                    class: 'cancel',
                    type: 'button',
                    html: 'x'
                })

            $this.children('span').replaceWith($('<div></div>').append($input, $cancel));
        }
    });

    $('#myPage').on('click', '.selectedField .cancel', function () {
        var $this = $(this).closest('.selectedField').toggleClass('editMe editing');

        console.log($this.children('div')[0]);

        $this.children('div').replaceWith('<span>Click Me</span>');
    });
});

DEMO: http://jsfiddle.net/Z8abW/

This looks simple enough, right? Clicking the box replaces the <span> with a <div>, then clicking the (newly added) <button> puts the <span> back.

But, this doesn't work. The first event works. I can click to add the <input> and the <button>, but clicking the <button> does not work.

I don't know how to explain it, but it seems the <div> I want to remove isn't part of the DOM! When I click on the <button>, nothing happens on the page. I added a console.log to make sure the event was being ran. Sure enough, it was, but something was odd.

I'm using Chrome 27, and its console has a neat feature. If you console.log DOM elements, you can hover over them in the log and it will highlight them in the page. I did console.log($this[0]), and it highlighted the element, like I would expect. But, when I did console.log($this.children('div')[0]);, the element was not highlighted in the page! Why not? Makes me think the element, for some reason, isn't in the DOM. It does log a <div> to the console, but it doesn't seem to be the one in the actual DOM.

Because of this the $this.children('div').replaceWith line doesn't do anything!

What's going on! Why can I replace the <span> with a <div>, but not the other way around?

like image 928
Rocket Hazmat Avatar asked May 24 '13 14:05

Rocket Hazmat


People also ask

What is append method in JavaScript?

The Element.append() method inserts a set of Node objects or string objects after the last child of the Element . String objects are inserted as equivalent Text nodes. Differences from Node.appendChild() : Element.append() allows you to also append string objects, whereas Node.appendChild() only accepts Node objects.

What can I use instead of append in JavaScript?

appendChild is another JavaScript method we have for appending stuff to DOM elements. It's a little limited in that it only works with node objects, so we we'll need some help from textContent (or innerText ) for our plain text needs. Note that appendChild , unlike append , is supported in Internet Explorer.

How do you add an element after another element?

How it works: First, select the ul element by its id ( menu ) using the getElementById() method. Second, create a new list item using the createElement() method. Third, use the insertAfter () method to insert a list item element after the last list item element.


1 Answers

Propagation issues. Change:

$('#myPage').on('click', '.selectedField .cancel', function () {

to

$('#myPage').on('click', '.selectedField .cancel', function (e) {
        e.stopPropagation();

jsFiddle example

The click on the cancel bubbles up and triggers the click event on the parent. Kill it with fire.

like image 196
j08691 Avatar answered Nov 09 '22 20:11

j08691