less.js 中使用库,从浏览器中的更少文件动态地重新生成 css。如果有一个简单的方法来修改更少的代码,这将是一种非常强大的动态更新站点 css 的方法。
想象一下,您有一种颜色在整个大型站点中使用了 100 次。如果你想只使用 javascript 动态地改变这种颜色,你需要更新具有这种颜色的每一点 css(可能是 50 行代码)。
根据我的想象,你需要写的只是这样的东西:
$('@mainColour').value('#F04');
我正在考虑自己尝试一下,但这听起来像是一个庞大的项目,我想知道是否有人已经开始这样的事情?
编辑:澄清一下,理想情况下,我希望能够做的是获取一串 Less 代码,以编程方式对其进行编辑(可能使用类似 jquery 的选择器语法),然后将其作为修改后的 Less 吐出。理想情况下,代码是Javascript(但不一定是客户端)我上面给出的示例是一个可能的应用程序,但可能不是一个好的应用程序(可能有更好更常见的实现方法)。
这绝对是可能的,但我不得不稍微修改较少的源代码(我认为这很好,考虑到这真的不应该:)完成)
我想每个人都想先看一个演示,点击这里:http://jsfiddle.net/kritzikratzi/BRJXU/1/(脚本窗口只包含修改后的 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();
};
将属性保存到对象中,并告诉 Less 更新其样式。
修改解析函数
function parse(str, callback ){
...
var overrides = "nn";
for( var key in less.Overrides ){
overrides += key + ": " + less.Overrides[key] + ";n";
}
str += overrides;
我们在这里所做的只是序列化被覆盖的属性,并将它们添加到每个解析文件的末尾。
修改加载样式函数
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 会将 type 参数从 <style type='text/less'>
替换到 type='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>
这在我的电脑上工作得很好,我不得不承认它看起来非常整洁。我还没有测试外部较少的文件,如果它们不起作用,应该很容易修复。
我仍然认为在生产环境中使用它不是最好的主意(出于其他人已经提到的原因)。
虽然我同意@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);
}
}
}
如果您在浏览器中本地使用 less 编译器,现在有一个修改更少变量的功能:
less.modifyVars({
'@buttonFace': '#5B83AD',
'@buttonText': '#D9EEF2'
});
首先,JavaScript不能写入文件。最好的你将能够做到 要做的是让Javascript读取和编辑XML,然后发布该数据 到服务器端脚本以写入文件。
好吧,一般来说,人们使用不同的类来解决这个问题,并用新类替换现有类,而不是编辑CSS文件本身,这对我来说听起来很奇怪。
我偶然发现了这篇博文,也许这就是你正在寻找的......他展示了根据您的要求获取新闻样式表的不同方法。
如果您可以执行 C# 并希望在服务器端执行此操作,则端口无点支持插件,您可以在其中实现访问者模式以编程方式更改较小的 ast,然后再将其吐出...
是一个很好的idéer,但是如果你的CSS/HTML是正确的,这根本不是必需的,你只需要以正确的方式CSS,如果你有很多"a"标签,你可以堆叠你的类。如果你有非常大的网站,你的客户可能会对一些小的改变(如字体)非常挑剔,那么定制你的结果是件好事,然后很容易用css摆脱它,而不是制作更多的变量来制作你的结果
如果您想更改 1 种颜色,只需使用您的查找工具并使用查找和替换。
请使用一些CSS和Comon Knowlegde来获得结果,操作网站的脚本越多,加载时间就越长。
此致敬意
SP