8

可以使用 less.js 中的库从浏览器中的 less 文件动态重新生成 css。如果有一种简单的方法可以修改更少的代码,这将是一种非常强大的动态更新站点 css 的方法。

想象一下,您有一种在整个大型站点中使用了 100 次的颜色。如果您想仅使用 javascript 动态更改该颜色,则需要更新具有该颜色的每一位 css(可能是 50 行代码)。

根据我的想象,你需要写的是这样的:

$('@mainColour').value('#F04');

我正在考虑自己尝试一下,但这听起来像是一个巨大的项目,我想知道是否有人已经开始了这样的事情?

编辑:澄清一下,理想情况下,我想要做的是获取一串 Less 代码,以编程方式对其进行编辑(可能使用类似 jquery 的选择器语法),然后将其作为修改后的 Less 吐出。理想情况下,代码在 Javascript 中(但不一定是客户端) 我上面给出的示例是一种可能的应用程序,但可能不是一个好的应用程序(可能有更好更常见的实现方法)。

4

6 回答 6

14

这绝对是可能的,但我不得不稍微修改一下较少的源代码(我认为这很好,考虑到它真的不应该这样做:))

我想大家都想先看一个demo,点这里:http: //jsfiddle.net/kritzikratzi/BRJXU/1/ (script-window只包含修改过的less.js-source,感兴趣的都在html窗口中)

kk,我先解释一下我的补丁,用法在最后。

补丁由三部分组成

添加实用功能

less.Overrides = {}; 
less.Override = function( variableName, value ){
    if( !value ){
        delete less.Overrides[variableName]; 
    }
    else{
        less.Overrides[variableName] = value; 
    }
    less.refreshStyles(); 
}; 

将属性保存到一个对象中,并告诉更少更新它的样式。

修改解析函数

   function parse(str, callback ){
        ... 

        var overrides = "\n\n"; 
        for( var key in less.Overrides ){
            overrides += key + ": " + less.Overrides[key] + ";\n"; 
        }

        str += overrides; 

我们在这里所做的就是序列化被覆盖的属性并将它们添加到每个被解析的文件的末尾。

修改 loadStyles 函数

    if (styles[i].type.match(typePattern) || styles[i].hasAttribute( "lessText" )) {
        var lessText; 
        if( styles[i].hasAttribute( "lessText" ) ){
            lessText = styles[i].getAttribute( "lessText" );
        }
        else{
            lessText = styles[i].innerHTML || ''; 
            styles[i].setAttribute( "lessText", lessText );
        }
    ....

默认情况下,less 将替换类型参数 from <style type='text/less'>totype='text/css'并忘记了 less-source。为了防止这种情况,原始的 less-source 被存储和加载。

用法和结论

<style type="text/less">
    @color: green; 

    #header{ color: @color; }
</style>
<div id="header">i'm the header!</div>
<a href="#" onclick="less.Override('@color', 'red');">make it red</a> 

这在我的电脑上工作得很好,我不得不承认它看起来很整洁。我还没有测试过外部较少的文件,如果它们不起作用,应该很容易修复。

我仍然认为在生产环境中使用它不是最好的主意(出于其他人已经提到的原因)。

于 2012-09-19T02:10:56.133 回答
4

虽然我同意@Baz1inga 的观点,一般来说,通过添加和删除类更容易做到这一点,但我也知道在某些情况下 LESS 样式的变量效果更好(例如,如果颜色有时是前景,有时是背景,或者是在某些地方减轻)。这绝对是可行的;事实上,这里有一些经过测试的代码可以做到这一点(减去 jQuery 风格的语法;有什么特别的原因需要这样做吗?):

function update_css(newcss) {
    var id = "styleholder";
    if ((css = document.getElementById(id)) === null) {
        css = document.createElement('style');
        css.type = 'text/css';
        css.id = id;
        document.getElementsByTagName('head')[0].appendChild(css);
    }
    if (css.styleSheet) { // IE
        try {
            css.styleSheet.cssText = newcss;
        } catch (e) {
            throw new(Error)("Couldn't reassign styleSheet.cssText.");
        }
    } else {
        (function (node) {
            if (css.childNodes.length > 0) {
                if (css.firstChild.nodeValue !== node.nodeValue) {
                    css.replaceChild(node, css.firstChild);
                }
            } else {
                css.appendChild(node);
            }
        })(document.createTextNode(newcss));
    }
}

lessvars = {mycolor: "red"};

maincode = "div { color: @mycolor; }"; // this would be a long string, loaded via AJAX from a LESS file on the server

function compile_less(variables) {
    var variable_less = "";
    for (var variable in variables) {
        variable_less += "@" + variable + ": " + variables[variable] + ";";
    }
    new(less.Parser)({
        optimization: less.optimization
    }).parse(variable_less + maincode, function (e, root) {
        update_css(root.toCSS());
    });
}

compile_less(lessvars);

function set_less_var(name, value) {
    lessvars[name] = value;
    compile_less(lessvars);
}

上面的“update_css”函数来源于less.js中的“createCSS”函数;其余的我写。您现在可以随时执行以下操作来更改颜色并使效果立即出现在站点内容中:

set_less_var("mycolor", "green");

(请注意,当然,您的“主代码”可能应该在后台从 .less 文件中加载——为简单起见,我只是将它们分配给变量。)

只是为了好玩(因为我不推荐它) - 并向您展示我认为我的代码可以满足您的需求 - 这是一个允许您使用上述代码执行的函数$("@mycolor").value("black");

function $(varname) {
    return {
        value: function(val) {
            set_less_var(varname.slice(1), val);
        }
    }
}
于 2012-04-23T04:48:01.487 回答
2

如果您在浏览器中本地使用 less 编译器,现在有一个功能可以修改 less 变量

less.modifyVars({
 '@buttonFace': '#5B83AD',
 '@buttonText': '#D9EEF2'
});
于 2015-08-05T15:31:56.697 回答
1

它可能,只是可能是一个很好的 idéer,但如果你的 css / html 是正确的,那么这根本就没有必要,你只需要以正确的方式使用 css,如果你有很多“a”标签,你就可以堆叠你的类。如果您有非常大的网站,您的客户可能对字体等一些小变化非常挑剔,那么定制您的结果很好,然后很容易通过 CSS 摆脱它,而不是制作更多变量来获得结果

如果你想改变一种颜色,你只需使用你的查找工具并使用查找和替换。

请使用一些 css 和通用知识来获得结果,操作您网站的脚本越多,加载时间就越长。

此致

SP

于 2012-09-21T08:02:50.070 回答
1

如果您可以使用 c# 并希望在服务器端执行此操作,则 port dotless 支持插件,您可以在其中实现访问者模式,以便在输出之前以编程方式更改 less ast...

于 2012-04-23T06:12:35.983 回答
1

首先javascript不能写入文件。您能做的最好的事情就是让 Javascript 读取和编辑 XML,然后将该数据发布到服务器端脚本以写入文件。

一般来说,人们使用不同的类来解决这个问题并用新类替换现有类,而不是去编辑 css 文件本身,这对我来说听起来很奇怪..

我偶然发现这篇博文可能就是你要找的东西。他展示了根据你的要求获取新闻样式表的不同方法。

于 2012-04-23T03:01:22.607 回答