HTML Typer
by soulwire
HTML
<section id="content"></section>
CSS
html, body {
background: #f2f2f2;
}
#content {
background: #fff;
font-size: 18px;
padding: 20px;
margin: 0 auto;
width: 80%;
}
#content strong {
font-weight: 600;
}
#content em {
font-style: italic;
}
#content li {
list-style-type: square;
margin-left: 20px;
}
.highlight {
background-color: #fff885;
}
JavaScript
jQuery.fn.outerHTML = function(s) { return (s) ? this.before(s).remove() : jQuery("<p>").append(this.eq(0).clone()).html();}
var regex = {
tags: /(<\w[^>]+>)([^\<]+)(<\/[^>]+>)/,
index: /\{\/?(\d+)\}/,
open: /\{(\d+)\}/,
shut: /\{\/(\d+)\}/
};
var tags = [];
var queue = [];
var $container = $('#content');
function parse(content) {
// Recursively parse and replace the content
var result = regex.tags.exec(content);
while(result) {
// Get the start and end of the string
var before = content.substr(0, result.index);
var after = content.substr(result.index + result[0].length);
// Create the main content
var insert = '{n}' + result[2] + '{/n}';
insert = insert.replace(/(\{\/?)n(\})/g, '$1' + tags.length + '$2');
// Insert it between the rest of the content
content = before + insert + after;
// Store the tags we've replaced
tags.push(result[1] + result[3]);
// Find the next result
result = regex.tags.exec(content);
// Rest the regex
regex.tags.lastIndex = 0;
}
// Strip into queue
queue.push(' ');
queue = queue.concat( content.match(/\{?\/?.\}?/g) );
}
var $tags = [];
var $tag = null;
function type() {
if(queue.length > 0) {
var char = queue.shift();
if(regex.index.test(char)) {
// If we're opening a tag
if(regex.open.test(char)) {
var index = +char.match(regex.index)[1];
var $tag = $(tags[index]);
$container.append($tag);
$container = $tag;
} else {
// Close the tag and go up one level
$container = $container.parent();
}
// We've done nothing, so step forward
type();
} else {
$container.append(char);
}
}
}
parse('Lorem <span class="highlight"><a href="#">ipsum</a> dolor <a href="#">sit <strong>amet</strong></a>,...