【问题标题】:less.js lazy sheet loadless.js 延迟工作表加载
【发布时间】:2010-07-08 13:59:28
【问题描述】:

我想知道是否有办法在页面加载后的某个时间加载单个 less 工作表。 This question 有一个解释如何重新加载所有工作表的答案,但对于我的用例,现有工作表永远不会依赖于新加载的工作表,最好只是懒惰地添加工作表。我在想类似的东西

less.sheets.push(mySheet);
less.loadStyleSheet(mySheet);

可能代表一个可能的 API?干杯,

科林

2010 年 12 月 3 日更新:

我已经尝试了 Livingston Samuel 对 less.js 代码库的修复,虽然它确实有效,但它似乎无法识别已加载样式表中的定义。这是我的示例文件

一个。 index.html

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <title>Simple</title>

  <link rel="stylesheet/less" href="/static/less/style.less" id="abc123"/>
  <script src="/static/js/less-1.0.40.js"></script> 
</head>
<body>
  <div id="container">
    <div>Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet.</div>
  </div>
  <div id="abc"><div>Bingo</div></div>
</body>

<script>
console.log("loading new sheet");
less.loadStyleSheet("/static/less/style2.less", function() {
    console.log("Loaded!"); 
});

console.log("called");

</script>
</html>

b. style.less

@primary_color: green;

.rounded(@radius: 5px) {  
  -moz-border-radius: @radius;  
  -webkit-border-radius: @radius;  
  border-radius: @radius;  
}

#container {
  background: @primary_color;
  .rounded(5px);

  div {
    color: red;
  }
}

c。 style2.less

#abc {
  background: @primary_color;
  .rounded(10px);

  div {
    margin: 2px;
    color: blue;
  }
}

所以第二个样式表确实会延迟加载,但在 style2.less 中有以下解析错误

".rounded 未定义"

.rounded 被定义为 style.less,由于我还没有卸载该工作表,我认为它应该在当前环境中仍然可供编译器使用。

换句话说,我们不想重新开始,也不想卸载现有的定义,而是建立在已经加载的样式之上。谢谢,

科林

【问题讨论】:

标签: javascript less


【解决方案1】:

我无法通过上面的解释弄清楚这一点,所以我会提供自己的解释。

首先。页面加载后加载您的 Less 样式表。像这样的:

$('head').append('<link rel="stylesheet/less" href="path/to/yourDynamicStyles.less" />');

太好了。现在选择您的样式表并将其推送到 Less.js 已有的工作表集合中。它需要一个 DOM 对象,所以我使用了 jQuery 选择器。

less.sheets.push($('link[href="path/to/yourDynamicStyles.less"]')[0]);

如果有人知道更好的方法,请教育我。 (我必须添加 [0] 才能使其正确。)如果您在控制台中执行此操作,它将返回一个数字。这个数字是少知道多少张,所以希望它返回的数字比您在页面加载时已经拥有的数字高一。

下一部分很简单。你告诉 Less.js 重新加载它所有的不太好的工作表,这包括你刚刚添加到它的堆栈中的工作表。

less.refresh();

然后就可以了。那应该只是动态加载一个样式表并告诉 Less 编译它。希望这会有所帮助。

【讨论】:

    【解决方案2】:

    less.js 在其本地范围内有一个函数loadStyleSheet,可用于动态加载和解析较少的样式(延迟加载)。

    唯一的问题是该函数位于为定义 less.js 创建的闭包中,因此您无法从代码中访问该函数。

    也许可以通过扩展 api 暴露出来。


    更新:

    我创建了less.js @https://github.com/livingston/less.js 的分叉版本

    使用此版本,您可以使用方法less.less.loadStyleSheet(YOUR_FILE_URL, CALLBACK) 加载任何样式表

    我还向实际库提出了拉取请求,希望他们接受我的更改。

    【讨论】:

    • 我已经测试过了,它看起来确实可以工作,但是已经加载的样式表中的定义无法识别。将更详细地更新问题。干杯。
    【解决方案3】:

    刚刚为我自己的需要采用了 MatthewForr 的答案:

    $.each(['/css/style1.less', '/css/style2.less'], function (index, fileName) {
        var $sheet = $('<link />', {
            href: fileName,
            rel: 'stylesheet/less',
            type: 'text/css'
        }).appendTo('head');
        less.sheets.push($sheet[0]);
    });
    less.refresh();
    

    【讨论】:

      【解决方案4】:

      或者,您可以编写一些服务器端代码,将您的 .less 样式表即时转换为 .css。从客户端你会懒惰地加载它,就好像它是任何其他 .css 样式表一样。这是http://www.dotlesscss.org/ 使用的方法,尽管它可以用于任何风格的.less。

      也许不是你想要的,但我认为它是一些人的选择。

      【讨论】:

      • 是的,定义。一个选项 - 我的应用程序在 App Engine (python) 上,并且样式脚本是用户在运行时贡献的 - 所以我用于服务器端编译的唯一选项是 (a) python 库(我找不到任何看起来维护良好的东西,当前,或可能可靠地遵循较少的进步)。 (b) 接受源脚本并返回编译输出的外部 Web 服务。 (c) 选择 LESS 以外的其他具有 python 编译器的东西。这些选项都不是很吸引人,而less.js 轻松解决这些问题(如果它可以延迟加载)非常吸引人。谢谢。
      • 另一件事是,因为我需要延迟加载,我需要单独提供/编译这些部分 - 例如userA 可以只使用 script1,而 userB 可以同时使用 script1 和 script2(script2 不能单独使用,因为它依赖于 script1,但 script2 可能不会被所有人使用)。所以当script2加载的时候,如果已经在服务器上预编译过了,那么css文件就会包含已经加载的script1中的所有定义。确实,它们只会覆盖,但不必要的大 css 文件,而且总体上闻起来很糟糕。
      【解决方案5】:

      您可以使用这个轻量级库来lazy load less / css and js files(免责声明:我是作者)。

      这很简单:

      lazy.load('/static/less/style.less');
      

      它还可以接收回调,加载更多具有依赖关系的资产并处理缓存。

      【讨论】:

        【解决方案6】:

        您所要做的就是向 DOM 添加一个新的脚本标签。然后它将被下载并执行。

        function addScript (id, url)    //  Adds scripts to the DOM
        {
            var s = document.createElement('script');
            s.id = id;
            if (url)    s.src=url;
            s.type='text/javascript';
        
            document.getElementsByTagName('head')[0].appendChild(s)
            return s;
        }
        

        这是我在我的网站上使用的,但我在解析时调用它。为了让您将其用作惰性加载器,您应该可以将其称为 onload 或类似的方式。

        【讨论】:

        • 对不起,我以为这是你命名的 javascript 文件 :(
        • 我不太明白你想要做什么?页面加载后是否要向 DOM 添加样式表(可以是 less.js 样式表)?
        • 1.页面加载完成, 2. 用户做了一些事情,并且在将来的某个时间点单击需要加载新样式表的链接。一个很好的例子可能是安装一个 ui 小部件组件。我们不想重新加载整个页面,只需要小部件所需的 html 和 css。
        • 在这种情况下,使用上面相同的代码,但添加一个样式表。这就是我使用的。我的确切实现的副本位于pastebin.com/ER1NYT31
        • 您误将 less 样式表与 css 样式表混淆了。懒惰地加载 css 样式表是很好理解的(以及我目前所做的),但如果我要转向更少,我想做的,那么我需要懒惰地加载更少的表。现在问题中有一些示例较少的样式表。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-10-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-23
        • 2019-07-25
        • 2018-07-19
        相关资源
        最近更新 更多