Adding onclick event to element BEFORE appending to the DOM

Hi there,

I never learned javascript before I got into jQuery, so I’ve decided to use pure js for a little side-project to get my js chops up.

I’ve run into a problem almost instantly:


<!DOCTYPE>
<html lang="en-GB">
<head>
<meta charset="utf8">
</head>

<body>
<div id="span-holder"></div>

<script>
var elem = document.createElement('span');
elem.className = "newSpan";
elem.innerHTML = "My shiny new span element";
elem.onclick = function(){ alert('Hi!'); };

var spanHolder = document.getElementById('span-holder');

spanHolder.appendChild(elem);
</script>

</body>
</html>

I was hoping that the span would have a click event when it was added to the DOM. Alas, it does not. Do I really have to add the click event AFTER the element has been added to the DOM?

If so, what are the pros/cons of doing this instead:


var spanHolder = document.getElementById('span-holder');

spanHolder.innerHTML = '<span class="newSpan" onclick="alert(\\'Hi\\')">My shiny new span element</span>';

Many thanks,
Mike

It has. I don’t think you have scripting enabled.

Your right.

The post was actually a simplification of an issue that I’m having… so obviously they way I’m creating and appending the span element isn’t the issue.

Here’s my actual code for this project so far:


<head>
	<meta charset="utf8">
	<style>
	#note-holder, #note-holder input[type=text]{font-family:monospace;font-size:65px;line-height:1.5em;letter-spacing:-1px;}
	#note-holder input[type=text]{width:280px;margin:0;height:90px;line-height:1.2px;padding-top:0;padding-bottom:0;}
	span.chord{display:inline-block;width:280px;}
	</style>
</head>
<body>
	<label for="bars">Number of bars: </label>
	<input type="text" id="bars" value="4" />
	<input type="submit" id="go" value="Go" onclick="start()" />
	<div id="note-holder"></div>


<script>
var newNotes = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'],
	chords = ['maj', 'm', '7', 'maj7', 'm7', 'add9', 'sus2', 'sus4'],
	noteHolder = document.getElementById("note-holder"),
	t,
	barsPerLine = 4,
	first = true,
	notes,
	numBars,
	barsDone = 0;


function generateChord(){
	var note = notes.splice(Math.round(Math.random() * (notes.length-1)), 1),
	chord = note + chords[Math.round(Math.random()*5)];
	
	var elem = document.createElement('span');
	elem.className = "chord";
	elem.appendChild(document.createTextNode(chord));

        //onclick added here
	elem.onclick = function(){
		console.log("clicked " + chord);
	};

        //span element(s) append to the DOM fine...
	noteHolder.appendChild(elem);
	barsDone++;
	if(!(barsDone%barsPerLine)){
		noteHolder.innerHTML += '<br>';
		first = true;
		notes = newNotes.slice();
	}
	if(barsDone < numBars) generateChord();
}

function start(){
	numBars = Number(document.getElementById("bars").value),
	noteHolder.innerHTML = "",
	notes = newNotes.slice(),
	barsDone = 0,
	first = true;
	generateChord();
}
</script>
</body>
</html>

So I’m creating random chord spans and adding them to the DOM. I want to add a click event so I can start to incorporate user interaction to the application. But the click events are not firing…

That line is overwriting everything added to the div. Append a generated ‘br’ element instead.