Reputation: 5588
I dont know how to describe this but I'm sure you'll understand if you visit this link. http://jsfiddle.net/pahnin/yN3xf/
I want to append text to a p element with javascript and I'm sucessful, but if the text contains a tag like <font>
the tag is displayed as it is.
Should I add code to detect the html elements or it can be done any other means? if I do add code which detect font tag how to add the tag back to the text??
Upvotes: 4
Views: 1194
Reputation: 7273
You could do something like this. Once all the text has been written out, then you replace the whole html of welcome
with the original text. It's not the best I admit.
$(document).ready(function() {
var htmlcopied = $('.welcome').html();
var textcopied = $('.welcome').text();
$('.welcome').text('');
function foobar(i) {
if (i < textcopied.length) {
$('.welcome').append(textcopied.charAt(i));
setTimeout(function() {
foobar(i + 1);
}, 80);
}
else {
$('.welcome').html(htmlcopied);
}
}
foobar(0);
});
This should give you the desired effect through different means. It has a div on top of the original text, and it slow reveals the text, which looks like it is being typed out.
Example
http://jsfiddle.net/guanome/LrbVy/
html
<div class="welcome">Hi, there <span class="hl">special text</span>, normal text
<div class="overlay"></div>
</div>
javascript
$(document).ready(function() {
$('.overlay').css('width', $('div.welcome').css('width'));
$('.overlay').css('height', $('div.welcome').css('height') + 15);
var origWidth = $('.overlay').css('width').replace(/px/g,'');
foobar(origWidth);
});
function foobar(i) {
if (i > -10) {
$('.overlay').css('width', i);
setTimeout(function() {
foobar(i - 10);
}, 80);
}
}
css
.hl{
color: red; font-family: helvetica;
background: #efefef;
color: black;
padding: 2px 7px;
-moz-box-shadow: 0 1px 1px #CCCCCC;
-webkit-box-shadow: 0 1px 1px #CCCCCC;
box-shadow: 0 1px 1px #CCCCCC;
}
div.welcome
{
position: relative;
width: 500px;
}
.overlay
{
position: absolute;
right: 0;
top: -3px;
width: 100%;
height: 25px;
background-color: #FFF;
z-index: 10;
}
With this change, the overlay will be added dynamically to the welcome message, the width doesn't have to be set, and it will work with multiple lines easily.
http://jsfiddle.net/guanome/LrbVy/4/
html
<div class="welcome">Hi, there <span class="hl">special text</span>, normal text</div>
javascript
$(document).ready(function() {
showWelcome();
});
function foobar(i, overlay) {
if (i > -10) {
overlay.css('width', i);
setTimeout(function() {
foobar(i - 10, overlay);
}, 80);
}
else {
overlay.remove();
}
}
function showWelcome() {
var welcome = $('div.welcome');
welcome.append('<div class="overlay"></div>');
welcome.css('position', 'relative');
var overlay = $('.overlay');
overlay.css({
'width': welcome.css('width'),
'height': (welcome.outerHeight() + 5),
'position': 'absolute',
'right': '0',
'top': '-3px',
'background-color': '#FFF',
'z-index': '10'
});
var origWidth = overlay.css('width').replace(/px/g, '');
foobar(origWidth, overlay);
}
Upvotes: 3
Reputation: 27880
You can also achieve this by iterating over the root element's contents()
, and outputting individually each of the children nodes, one by one.
When treating each of contents
elements, if it is a text node, it is enough to output all characters with a timeout. If it is not a text node, clone the node and append it to the target element. All characters inside it can be appended in the same way.
See it working here: http://jsfiddle.net/yN3xf/36/
$(document).ready(function(){
var $clonedContent = $('.welcome').clone();
$('.welcome').textContent = '';
$('.welcome').text('');
treatContents(0, $clonedContent, $('.welcome'));
function treatContents(num, container, target){
var $originalNode = container.contents()[num];
var $targetNode;
if ($originalNode.nodeType == 3){
$targetNode = target;
}
else{
$targetNode = $(container.contents()[num]).clone(false, false).appendTo(target);
$targetNode.text('');
}
$targetNode.textContent = '';
writeCharacters($originalNode.textContent , 0, $targetNode, num, container, target);
}
function writeCharacters(origText, x, target, contNum, contCont, contTarg) {
if(x<origText.length){
target.append(origText.charAt(x));
setTimeout(function() { writeCharacters(origText, x+1, target, contNum, contCont, contTarg); }, 80);
}
else{
treatContents(contNum+1, contCont, contTarg);
}
}
});
This sample could be adapted to allow nested tags, for instance:
<p class="welcome">Hi, there <b>bold text <i>bold italic text</i></b>, normal text</p>
Upvotes: 1
Reputation: 93003
You could simply replace var textcopied = $('.welcome').html();
with var textcopied = $('.welcome').text();
to extract the text without any HTML tags included. But then, of course, you won't get your tags back at all.
Update: A somewhat different approach uses jQuery animations to slide the entire title into view smoothly:
$(document).ready(function(){
var $title = $('.welcome');
var twidth = $title.width();
var theight = $title.height();
$title.css({
overflow: 'hidden',
width: 0,
whiteSpace: 'nowrap',
height: theight
}).animate({
width: twidth
}, 5000); // milliseconds
});
http://jsfiddle.net/mblase75/yN3xf/16/
Upvotes: 4
Reputation: 5008
Try replacing:
$('.welcome').append(textcopied.charAt(i));
with:
textHTML += textcopied.charAt(i);
$('.welcome').html(textHTML);
And at the begening of the code, put this:
var textHTML = '';
It works, but it doesn't look very good :P
Upvotes: 0