0

目标是能够单击链接以打开一个新窗口,该窗口显示来自父窗口的格式化源代码。

通过研究,我能够完成大部分任务,但我需要新窗口来完全显示源代码就像它在父级、缩进和所有内容中一样。目前,HTML 实体被显示为它们的显示对应物(因此它输出实际商标而不是源的™)。

正如您将在我的示例中看到的那样,我正在考虑遍历一堆实体并进行字符串替换,但我认为逻辑已关闭,我不知道发生了什么。

特别是实体: • (bull), & (amp), ® (reg), ™ (trade), < (lt), > (gt)

这是到目前为止我拥有的超链接启动的代码,对于任何能够弄清楚在第二行输出什么结束正文标签的人(我很难过):

非常感谢您提前提供任何导致解决方案的方向。

function viewSource( e )
{
    e.preventDefault( );

    var source = '<!DOCTYPE html>' + "\n"
               + '<html xmlns="http://www.w3.org/1999/xhtml">' + "\n\n"
               + "\t" + document.getElementsByTagName( 'html' )[0].innerHTML + "\n\n"
               + '</html>';

    entities = [
        new Entity( '<', '&lt;' ),
        new Entity( '>', '&gt;' )
    ];

    for ( var i = 0; i < entities.length; i++ )
    {
        var regex = new RegExp( entities[i].entity, 'g' );
        source = source.replace( regex, entities[i].html );
    }

    source = '<pre>' + source + '</pre>';

    var sourceWindow = window.open( '', '_blank' );
    sourceWindow.document.write( source );
    sourceWindow.document.close( );

    if ( window.focus )
    {
        sourceWindow.focus( );
    }
}

更新(仍未解开的谜团):

我尝试了使用 AJAX 请求的建议,但它仍然产生相同的结果(第 11 行显示new Entity( '<', '<'),)。下面是 AJAX 尝试的样子:

function viewSource( e )
{
    e.preventDefault( );

    var xmlhttp;

    if ( window.XMLHttpRequest )
    {
        // IE7+, Fx, Chrome, Opera, Safari
        xmlhttp = new XMLHttpRequest( );
    }
    else
    {
        // IE6, IE5
        xmlhttp = new ActiveXObject( 'Microsoft.XMLHTTP' );
    }

    xmlhttp.onreadystatechange = 
        function ( )
        {
            if ( xmlhttp.readyState == 4 && xmlhttp.status == 200 )
            {
                var source = xmlhttp.responseText.replace( /</g, '&lt;' ).replace( />/g, '&gt;' );
                source = '<pre>' + source + '</pre>';

                var sourceWindow = window.open( '', '_blank' );
                sourceWindow.document.write( source );
                sourceWindow.document.close( );

                if ( window.focus )
                {
                    sourceWindow.focus( );
                }
            }
        };

    xmlhttp.open( 'GET', '/', true );
    xmlhttp.send( );
}
4

2 回答 2

0

你没有正确地逃避你的来源。您应该使用源的文本表示
构建一个 DOM 元素。

使用 jQuery:

$('<pre />').text(source).appendTo(document.body);
于 2011-11-04T12:43:58.780 回答
0

所以,感谢@SLaks 的所有指导。我能够实现接近我想要的目标,但仍然有一些我可能不得不忍受的小怪癖。我特别想避免使用任何库,例如 jQuery。

仍然出现的问题如下: - 输出源显示没有最后斜线的自闭合标签。因此,例如,<br />正在显示为<br>. - 由于某种原因,结束正文标签被包装到下面的行。它应该呈现为:

    </body>

</html>

但是,相反,它呈现为:

[tab]
</body>

</html>

尽管如此,我仍然对结果感到满意,这应该足够了。但是,如果有人有任何不需要 3rd 方库的更好的解决方案,那将不胜感激。这是最新的尝试:

function htmlEntity( character )
{
    switch ( character.charCodeAt( 0 ) )
    {
        case 174:  return '&reg;';    break;
        case 233:  return '&eacute;'; break;
        case 8211: return '&ndash;';  break;
        case 8220: return '&ldquo;';  break;
        case 8221: return '&rdquo;';  break;
        case 8226: return '&bull;';   break;
        case 8482: return '&trade;';  break;
        default:   return character;
    }

    if ( character.charCodeAt( 0 ) > 127 )
    {
        return '&#' + character.charCodeAt( 0 ) + ';';
    }

    return character;
}

function viewSource( e )
{
    e.preventDefault( );

    var source = '<!DOCTYPE html>' + "\n"
               + '<html xmlns="http://www.w3.org/1999/xhtml">' + "\n\n"
               + "\t" + document.getElementsByTagName( 'html' )[0].innerHTML + "\n\n"
               + '</html>';

    var entities = [ '®' ];
    for ( i = 0; i < entities.length; i++ )
    {
        source.replace( entities[i], htmlEntity( entities[i] ) );
    }

    var temp = '';
    for ( i = 0; i < source.length; i++ )
    {
        temp += htmlEntity( source.charAt( i ) );
    }

    var pre = document.createElement( 'pre' );
    pre.textContent = temp;

    source = '<pre>' + pre.innerHTML + '</pre>';

    var sourceWindow = window.open( '', '_blank' );
    sourceWindow.document.write( source );
    sourceWindow.document.close( );

    if ( window.focus )
    {
        sourceWindow.focus( );
    }
}
于 2011-11-04T14:07:47.793 回答