添加<;脚本>;及<;链接>;使用JavaScript的元素?

添加<;脚本>;及<;链接>;使用JavaScript的元素?,javascript,css,dom,progressive-enhancement,Javascript,Css,Dom,Progressive Enhancement,最近我看到一些HTML在其中只有一个元素 <head> <title>Example</title> <script src="script.js" type="text/javascript"></script> <link href="plain.css" type="text/css" rel="stylesheet" /> </head> 请注意,文档中有一个plain.cssc

最近我看到一些HTML在其
中只有一个
元素

<head>
    <title>Example</title>
    <script src="script.js" type="text/javascript"></script>
    <link href="plain.css" type="text/css" rel="stylesheet" />
</head>
请注意,文档
中有一个
plain.css
css文件,
script.js
只是添加了启用js的用户代理将使用的所有css和JavaScript


这种技术的优点和缺点是什么?

我想我能想到的一个优点是,如果你在多个页面上使用这些脚本,你只需要记住包含一个脚本,这样可以节省一些空间

它的优点是不需要在每个HTML文件中重复脚本引用。缺点是浏览器必须先获取并执行主javascript文件,然后才能加载其他文件

一个主要缺点是浏览器不兼容。并非所有浏览器都能正确地获取资源并将其合并到DOM中,因此使用这种方法是有风险的。样式表的情况比脚本更为如此

另一个问题是可维护性。在客户端连接和写入字符串以添加DOM元素可能会成为维护的噩梦。最好使用诸如createElement之类的DOM方法在语义上创建元素

一个明显的优点是,它使有条件地使用资源变得更加容易。您可以使用确定加载哪些资源的逻辑,从而减少带宽消耗和页面的总体处理时间。我将使用jQuery$.getScript()之类的库调用来加载脚本,而不是document.write。这样做的好处是,这种方法更简洁,还允许在请求完成或失败时执行代码

  • 如果禁用了JavaScript-
    ,则根本不会添加元素

  • 如果将JavaScript init函数放在页面底部(这是一个很好的做法),并将CSS与JavaScript链接,则可能会导致CSS加载之前的一些延迟(在短时间内会看到损坏的布局)


  • 好吧,我还是把我的帽子扔到拳击场上吧

    如果您查看google的闭包库base.js,您将看到document.write在其
    writeScriptag_389;()函数中使用。这是“closure”提供的依赖关系管理系统的一个重要部分,在创建复杂的、多文件的、基于库的javascript应用程序时,这是一个巨大的优势——它让文件/代码先决条件决定加载顺序。我们目前正在使用这项技术,并且没有什么问题。TBH,我们在浏览器兼容性方面没有任何问题,我们定期在IE 6/7/8、FF3/2、Safari 4/5和Chrome最新版本上进行测试

    到目前为止,我们唯一的缺点是,跟踪两次加载一个资源或根本无法加载一个资源所导致的问题很有挑战性。由于加载资源的行为是编程的,因此会发生编程错误,并且与将标记直接添加到HTML不同,很难看到确切的加载顺序。但是,通过使用具有某种形式的依赖关系管理系统(如closure或dojo)的库,可以在很大程度上克服这个问题

    编辑:我对这一性质做了一些评论,但我认为最好在我的回答中总结一下: dojo.require()和jQuery.getScript()存在一些问题(它们最终都会执行ajax请求和评估)

  • 通过ajax加载意味着没有交叉脚本——也就是说,没有加载不是来自您站点的javascript。如果要包括描述中列出的内容,这将是一个问题
  • Eval脚本不会出现在javascript调试器的页面脚本列表中,这使得调试非常具有挑战性。firebug的最新版本将向您显示评估代码,但是文件名会丢失,从而使设置断点的操作变得单调乏味。AFAIK、Webkit javascript控制台和IE8开发工具不显示评估脚本

  • 在谷歌PageSpeed上,他们极力劝阻你不要使用这种技术,因为它会让事情变得更慢。除了先顺序加载script.js之外

    现代浏览器使用推测性解析器更有效地发现外部资源[…],因此,使用JavaScript的document.write()获取外部资源使得推测性解析器无法发现这些资源,这可能会延迟这些资源的下载、解析和呈现


    这也有可能是一家SEO公司的建议,尽可能缩短head元素的长度,这样独特的内容就更接近文档的顶部,也创造了更高的文本与HTML的比率。虽然听起来确实如此,但总的来说,这并不是一个很好的方法;虽然这会使维护更加耗时,但如果认为完全有必要减少head元素的大小,更好的方法可能是将javascript压缩为单个.js文件,将css压缩为单个.css文件。

    document.write的阻塞性质
    document.write
    将暂停浏览器在页面上处理的所有内容(包括解析)。由于这种阻塞行为,强烈建议避免。浏览器无法知道此时您将要向HTML文本流中输出什么,也无法知道写入是否会完全破坏DOM树上的所有内容,因此必须停止,直到您完成

    本质上,以这种方式加载脚本将迫使浏览器停止解析HTML。如果您的脚本是联机的,那么浏览器也会在继续之前执行这些脚本。因此,作为旁注,建议您将加载脚本的时间推迟到页面被解析并向用户显示了合理的UI之后

    如果脚本是从中的单独文件加载的
    document.write("<link href=\"javascript-enabled.css\" type=\"text/css\" rel=\"styleshet\" />");
    document.write("<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js\" type=\"text/javascript\"></script>");
    document.write("<script src=\"https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.10/jquery-ui.min.js\" type=\"text/javascript\"></script>");
    document.write("<link href=\"http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.0/themes/trontastic/jquery-ui.css\" type=\"text/css\" rel=\"stylesheet\" />")
    document.write("<script src=\"validation.js\" type=\"text/css\"></script>")