【问题标题】:JavaScript, Objective: Display Accurate Source CodeJavaScript,目标:显示准确的源代码
【发布时间】:2011-12-21 16:56:12
【问题描述】:

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

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

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

特别是实体: • (bull), & (amp), ® (reg), ™ (trade), (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( '&lt;', '&lt;'), )。下面是 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( );
}

【问题讨论】:

  • 你想要当前的DOM源还是服务器的原始源?
  • 我猜是当前的 DOM 源。它是一个直接的 HTML 页面,因此没有呈现服务器端代码,也无法用作解决方案。
  • DOM 源不区分实体及其字符。
  • 嗯,我可能有点困惑。例如,在上面代码的第 11 行,如果我通过上下文菜单执行实际的“查看源代码”,它会像上面那样显示。此 JavaScriput 输出窗口将其显示为 new Entity( '&lt;', '&lt;' ),。我想我提出的解决方案行不通。也许,像能够执行命令“view-source:index.html”这样的替代方法可以工作吗?我无法让它在 IE9 中工作。
  • View Source 显示来自服务器的原始源,而不是 DOM 的当前状态。如果你愿意,你可以使用 AJAX。

标签: javascript encoding html-entities formatted-text


【解决方案1】:

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

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

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

【讨论】:

  • 我用我的小眼睛发现了一个隐式全局(循环中的 i 变量)
【解决方案2】:

您没有正确地转义您的来源。
你应该用你的源代码的 text 表示来构建一个 DOM 元素。

使用 jQuery:

$('<pre />').text(source).appendTo(document.body);

【讨论】:

  • 为什么“使用 jQuery”而不是“使用健全的 DOM”?
  • @Zirak:因为我懒得去查textContentinnerText
  • 然后只需创建一个新的文本节点并将其添加到元素中。 pastie.org/2809775
  • 你是对的;我没有想到这一点。但是,jQuery 仍然更短。 (请随意添加答案)
  • 女士们都知道,尺寸并不重要——性能和清晰度才是最重要的(女士们现在可能已经知道后者了)。但我不会为这样的事情重复你的答案。
猜你喜欢
  • 2013-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-19
  • 1970-01-01
  • 2019-10-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多