pahnin
pahnin

Reputation: 5588

javascript text append

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

Answers (4)

FarFigNewton
FarFigNewton

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.

http://jsfiddle.net/yN3xf/13/

$(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);
});



UPDATE

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;
}

UPDATE 2

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

Xavi L&#243;pez
Xavi L&#243;pez

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

Blazemonger
Blazemonger

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

MatuDuke
MatuDuke

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

Related Questions