Uirri
Uirri

Reputation: 273

Why do I lose reference to an element?

I stumbled upon something peculiar (at least to me). Here is the case:

I select an element, child1, from the DOM and save it to a variable. I continue on by adding a new element to child1's parent, parent1. Now if I try to modify some value on child1 it does not register the change. It seems as though the reference has disappeared and it is only referring to an earlier copy.

EXAMPLE
child1 = inputField
parent1 = container

function start() {
    var inputField = document.querySelector('#inputField');
    // Works if addSomething() is commented out.
    addSomething();
    console.log(inputField);
    doSomething(inputField);
}

function addSomething() {
    var container = document.querySelector('#container');
    container.innerHTML += '<div class="something"></div>'
}

function doSomething(el) {
    el.value = 'Some random input';
}

start();

EXAMPLE FIDDLE

http://jsfiddle.net/mdTkZ/

Excuse me if this is something incredibly basic or something that has been asked before. I tried googling, but did not find anything with the search words I used. A

Upvotes: 3

Views: 1798

Answers (6)

Moti Korets
Moti Korets

Reputation: 3748

When replacing innerHTML on object you removing inputField from the DOM so the object changes does not register in the browser

container.innerHTML += '<div class="something"></div>'

You actually do

container.innerHTML = container.innerHTML + '<div class="something"></div>';

Upvotes: 1

Unknownman
Unknownman

Reputation: 483

Try this
    var inputField;
    function start() 
    {
        inputField = document.getElementById('inputField');
        // Works if addSomething() is commented out.
        addSomething();
        console.log(inputField);
        doSomething(inputField);
    }

    function addSomething() 
    {
        var t=document.getElementById('container').innerHTML;
        document.getElementById('container').innerHTML = t+'<div class="something"></div>'
    }

    function doSomething(el) 
    {
        el.value = 'Some random input';
    }

    start()

Upvotes: 0

benhowdle89
benhowdle89

Reputation: 37474

From this: Is it possible to append to innerHTML without destroying descendants' event listeners?

"Unfortunately, assignment to innerHTML causes the destruction of all child elements, even if you're trying to append"

You could use: https://developer.mozilla.org/en-US/docs/Web/API/element.insertAdjacentHTML

Upvotes: 0

Jashwant
Jashwant

Reputation: 29005

When you do container.innerHTML += '<div class="something"></div>', it replaces the content with some other text.

inputField which you had before changing innerHTML, was holding a reference to DOM object. But now, that is destroyed and is replaced by just a string. You would need to access/select that input from DOM again ( by document.querySelector('#inputField'); ) to use it.

Upvotes: 1

Yury Tarabanko
Yury Tarabanko

Reputation: 45121

You are replacing the entire DOM subtree by setting innertHTML. inputField is now detached from its parent. You can check it by logging inputField.parentNode === null.

You can use insertAdjacentHTML instead.

function addSomething() {
    var container = document.querySelector('#container');
    container.insertAdjacentHTML('beforeend', '<div class="something"></div>');
}

http://jsfiddle.net/tarabyte/mdTkZ/1/

Upvotes: 1

Teemu
Teemu

Reputation: 23406

container.innerHTML += ... doesn't do what you think it does. It re-creates all the HTML to the element, and the original content is gone.

To fix this you need to create a new div and append it to container.

var div = document.createElement('div');
div.className = 'something';
container.appendChild(div);

A live demo at jsFiddle.

Upvotes: 5

Related Questions