JavaScript文本追加

4
我不知道如何描述这个问题,但如果你访问这个链接,你肯定会明白。 http://jsfiddle.net/pahnin/yN3xf/ 我想用JavaScript将文本添加到一个p元素中,我成功了。但是,如果文本包含像这样的标记,那么标记就会按原样显示。
我应该添加代码来检测HTML元素吗?还是可以用其他方法来实现? 如果我添加检测字体标签的代码,如何将标签添加回文本中?

2
don't use font, use span. - zzzzBov
如果您只是简单地附加它,它可以正常工作:http://jsfiddle.net/yN3xf/2/。 - ayyp
我的意图是在一段时间后追加每个字母。 - pahnin
4个回答

4
你可以将 var textcopied = $('.welcome').html(); 替换为 var textcopied = $('.welcome').text();,这样就可以提取文本而不包含任何HTML标签。但是,你将无法获得标签。 更新: 一种稍微不同的方法使用jQuery动画平滑地将整个标题滑入视图中:
$(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/


这就是我的基本问题。 - pahnin
更大的问题是.append只允许有效的HTML。就你的代码而言,唯一要做的就是提前提取HTML,并将其包装在每个字符周围,然后再次附加它。基本上,我认为你的整个方法是无效的。 - Blazemonger
还是guanome的方法更好,我认为这就是我要找的,我说过我需要在一定时间间隔后追加,动画会固定整个文本的时间,这意味着如果我的文本更长,我会得到更快的动画。抱歉。 - pahnin
此外,它看起来像动画,我只想要在guanome的方法中成功实现的附加。我不想要动画,我想要附加它。你的方法不够建设性。 - pahnin
让我们在聊天中继续这个讨论 - pahnin
显示剩余3条评论

3
你可以这样做。等所有文本都写好后,用原始文本替换welcome的整个HTML。我承认这不是最好的方法。

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



更新

这将通过不同的手段给您所需的效果。它在原始文本上方有一个 div,缓慢显示文本,看起来像是正在打字。

示例

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

更新 2

通过这个更改,叠加层将动态添加到欢迎消息中,宽度不需要设置,并且可以轻松处理多行。

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

那就是答案,谢谢,好主意! - pahnin
@pahnin,我更新了我的答案,我认为这就是你要找的。 - FarFigNewton
这是一个不错的想法,但仅适用于单行,并需要事先知道滑动 div 的长度。请查看 我的建议 以获得更灵活(和可改进)的方法(实际上我不懂 JQuery)。 - Xavi López
@XaviLópez 宽度不需要预先知道,并且只需进行一些简单的更改即可处理多行。http://jsfiddle.net/guanome/LrbVy/3/ - FarFigNewton

1

您还可以通过迭代根元素的contents()来实现此目的,并逐个输出每个子节点。

在处理每个contents元素时,如果它是文本节点,则足以使用超时输出所有字符。如果不是文本节点,请克隆该节点并将其附加到目标元素。其中的所有字符都可以以相同的方式附加。

在这里查看它的工作原理: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);
        }
    }
});

这个示例可以被调整以允许嵌套标签,例如:

<p class="welcome">Hi, there <b>bold text <i>bold italic text</i></b>, normal text</p>

这很好,虽然我不想阅读复杂的代码,但我喜欢它,因为我可以在任何地方使用它,只需要为我的p标签添加一个类,除非是guanome方法的更新版本。 - pahnin
$ originalNode 的最后一次迭代中抛出了异常,我添加了一个检查来检查 $ originalNode 是否未定义,这样就解决了问题。 - FarFigNewton
感谢修复,@guanome,我知道当没有更多的子元素时,treatContents(contNum+1, ... 会出现问题。 - Xavi López
+1 以支持更好的多行功能。我的会同时显示所有行,而你的会一次只显示一行,很不错。 - FarFigNewton
@guanome 嗯,这可能是一个错误或一个特性,取决于它预期要做什么;-) http://jsfiddle.net/yN3xf/37/ - Xavi López

0

尝试替换:

$('.welcome').append(textcopied.charAt(i));

使用:

textHTML += textcopied.charAt(i);
$('.welcome').html(textHTML);

在代码开头加入以下内容:
var textHTML  = '';

它能运行,但看起来不太好:P


我的意图是在一段时间后附加每个字母。 - pahnin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接