有时需要设置一些常量两次:在 SASS 和 JS 中(例如为了更好的性能)。有谁知道同步 SASS/SCSS 和 JavaScript 变量以从 JavaScript 或从 SASS 到 JavaScript 访问 SCSS 变量的解决方案?
3 回答
我知道这是大约一年前提出的问题,但我将这个答案作为下一个遇到此问题的可怜草皮的参考。那里可能有更好的解决方案,但这是我唯一能找到/想出的解决方案。
由于 JavaScript 似乎无法.scss
直接从任何文件中获取变量,因此我们必须使用正则表达式从文件中获取所需的值。但是因为我们不想让它搜索整个 SASS 文件:
创建一个包含变量的 SASS 文件
我们创建一个新文件 ,_variables.scss
供 JavaScript 搜索。假设它看起来像这样:
$menuMobileArrowRotate: 90;
$articleScale: 1.1;
将其导入我们的主 SASS 文件
@import "variables";
通过在样式表顶部附近添加将其导入 SASS 。然后我们可以在整个文件中使用这些变量,而不是手动输入值。
将其导入 JavaScript
我要让 JavaScript 读取_variables.scss
并将其转换为字符串:
var sassVariables = new XMLHttpRequest();
sassVariables.open("GET", 'http://www.use-absolute-url.com/_variables.scss', false);
sassVariables.send(null);
注意:要支持 IE6 及更早版本,请替换var xmlhttp = new XMLHttpRequest();
为:
if (window.XMLHttpRequest) {
var sassVariables = new XMLHttpRequest();
}
else {
var sassVariables = new ActiveXObject("Microsoft.XMLHTTP");
}
如果我设置异步。到true
,Firebug 向我显示一个声称fileContent
不存在的错误。而且由于我的文件只有 4KB,因此我不必担心潜在的性能问题,因为我必须等待它加载。
现在,我要声明我的变量:
var fileContent = sassVariables.responseText, //a string holding the contents of my file
menuMobileArrowRotate = null,
articleScale = null;
我在确保文件实际加载之前声明menuMobileArrowRotate
,articleScale
因为我不希望 JavaScript 给我一个错误并因为它没有加载而搞砸一切。
如果一切正常,我将使用 RegEx 找出每个变量的值。至少我只是浏览一个小文件,而不是搜索整个样式表。
if (sassVariables.status === 200) { //if everything loaded nice and dandy
menuMobileArrowRotate = fileContent.match(/(?:menuMobileArrowRotate.\s*?)(\d+)/)[1];
articleScale = data.match(/(?:articleScale.\s*?)((\d+)\.*(\d+)*)/)[1];
}
注意[1]
after .match()
: RegEx 返回一个数组,我只想要第一个匹配项(在我的情况下,它也是唯一的匹配项)。
对于所有的 JS 放在一起:
if (window.XMLHttpRequest) {
var sassVariables = new XMLHttpRequest();
}
else {
var sassVariables = new ActiveXObject("Microsoft.XMLHTTP");
}
sassVariables.open("GET", 'http://mysite.com/sass/_variables.scss', false);
sassVariables.send(null);
var fileContent = sassVariables.responseText,
menuMobileArrowRotate = null,
articleScale = null;
if (sassVariables.status === 200) {
menuMobileArrowRotate = fileContent.match(/(?:menuMobileArrowRotate.\s*?)(\d+)/)[1];
articleScale = fileContent.match(/(?:articleScale.\s*?)((\d+)\.*(\d+)*)/)[1];
}
console.log(menuMobileArrowRotate); //shows 90
console.log(articleScale); //shows 1.1
我现在可以在这段代码之后在我的 JavaScript 文件中的任何地方使用这些变量。
奖励:媒体查询变量
SASS 不允许您在媒体查询中使用变量。但是,我可以使整个 dang 查询成为 mixin,并将其放入_variables.scss
:
@mixin mediaQuery($point) {
@if $point == 'mobile' {
@media only screen and (max-width: 600px) { @content; }
}
@if $point == 'somethingElse' {
@media only screen and (max-width: 1000px) { @content; }
}
}
在style.scss
中,我可以拥有:
@include mediaQuery(mobile) {
//blah
}
@include mediaQuery(somethingElse) {
//blah
}
然后我可以使用相同的过程来获得所需的值(即 600 和 1000),只是使用不同的 RegEx。