【问题标题】:Is there a way to import variables from javascript to sass or vice versa?有没有办法将变量从 javascript 导入 sass,反之亦然?
【发布时间】:2012-03-10 09:23:55
【问题描述】:

我正在制作一个依赖于块概念的 CSS 网格系统。所以我有一个基本文件,例如:

$max-columns: 4;
$block-width: 220px;
$block-height: 150px;
$block-margin: 10px;

它被一个mixin使用:

@mixin block ($rows, $columns, $max-columns) {
  display: block;
  float: left;
  margin: $block-margin 0 0 $block-margin;
  box-sizing: border-box;
  width: ($block-width * $columns) - $block-margin;
}

但我也希望 javascript 能够访问基本文件中的变量。我在想我可以制作一个不可见的 div,并为其赋予 $block-width、$block-height 和 $block-margin 属性并从那里提取值。但是 max-columns 并没有直接映射到任何东西,所以我必须想出一个 hacky 方法来在 div 中呈现它。有没有一种更简洁的方法可以将值从 sass/css 共享到 javascript,反之亦然?

【问题讨论】:

    标签: javascript css sass


    【解决方案1】:

    您可以使用服务器端脚本读取 sass 文件,“解析”它并将您需要的值回显到 javascript。

    【讨论】:

      【解决方案2】:

      我认为我的解决方案相当不成熟;但它确实有效......

      在我的_base.scss 中,我定义了一些变量:

      $menu_bg: rgb(45, 45, 45);
      $menu_hover: rgb(0, 0, 0);
      

      menu.scss 我有:

      @import "base";
      
      #jquery_vars {
        .menu_bg {
          background-color: $menu_bg;
        }
        .menu_hover {
          background-color: $menu_hover;
        }
      }
      

      在一个方便的页面模板中:

      <span class="is_hidden" id="jquery_vars">
        <span class="is_hidden menu_bg"></span>
        <span class="is_hidden menu_hover"></span>
      </span>
      

      最后这允许在附近的 jQuery 脚本中:

      var menu_bg = $('#jquery_vars .menu_bg').css("background-color");
      var menu_hover = $('#jquery_vars .menu_hover').css("background-color");
      

      这太丑了,我爸爸头上戴着一个包。

      jQuery 可以从页面元素中提取任意 CSS 值;但这些元素必须存在。我确实尝试从原始 CSS 中提取其中一些值,而无需在 HTML 中创建跨度,而 jQuery 提出了undefined。显然,如果将这些变量分配给页面上的“真实”对象,则您实际上并不需要任意的 #jquery_vars 元素。同时,人们可能会忘记.sidebar-left nice-menu li 是用于向 jQuery 提供变量的重要元素。

      如果有人有别的东西,那一定比这更干净……

      【讨论】:

        【解决方案3】:

        我想补充一点,现在有几种方法可以使用 JSON 在 Sass 和 JavaScript 之间共享数据。以下是一些详细介绍各种技术的文章的链接:

        Sass 原生支持 JSON 导入可能只是时间问题。

        【讨论】:

          【解决方案4】:

          另一种方法是使用 gulp-template,这样您就可以为 JavaScript 生成所需的任何结构。

          使用 Gulp 和 gulp-template 在 Javascript 和 Sass 之间共享变量 https://youtu.be/UVeUq8gMYco

          它是从头开始创建的,因此人们可以从头开始看到它,并且有一个带有最终结果的 git repo:

          https://github.com/PocketNinjaCoUk/shared-js-sass-vars-using-gulp/tree/master/dev

          你基本上有你的配置对象

          保存在 ./dev/config.js

          module.exports = {
            defaults: {
              colours: {
                primary: '#fc0'
              },
              sizes: {
                small: '100px',
                medium: '500px',
                large: '1000px'
              },
              zIndex: {
                model: 100,
                dropdown: 50,
                header: 10
              }
            }
          }
          

          那么你就有了 Sass 和 Javascript 的模板,或者更少或任何你想要的。

          Sass 下划线模板

          保存在 ./dev/templates/sass-config.txt

          <% _.each(defaults, function(category, key) { %>
            // Var <%= key %>
            <% _.each(category, function(value, key) { %>
              $<%= key %>: <%= value %>;
            <% }) %>
          <% }) %>
          

          Javascript 下划线模板

          保存在 ./dev/templates/js-config.txt

          namespace.config = {};
          
          <% _.each(defaults, function(monkey, key) { %>
            namespace.config.<%= key %> = {
            <% i = 1 %>
            <% _.each(monkey, function(value, key) { %>
              <% comma = (Object.keys(monkey).length === i) ? '': ',' %>
              <% if(typeof value === 'string') {%>
                <%= key %>: '<%= value %>'<%= comma %>
              <%} else { %>
                <%= key %> : <%= value %><%= comma %>
              <% } %>
              <% i++ %>
            <% }); %>
            };
          <% }) %>
          

          然后gulp编译一下

          var gulp = require('gulp');
          var template = require('gulp-template');
          var rename = require('gulp-rename');
          var removeEmptyLines  = require('gulp-remove-empty-lines');
          
          var sharedVars = require('./dev/config');
          
          gulp.task('compile', function() {
            gulp.src('./dev/templates/sass-config.txt')
              .pipe(template(sharedVars))
              .pipe(rename('_sass-config.scss'))
              .pipe(removeEmptyLines())
              .pipe(gulp.dest('./dev/sass'));
          
            gulp.src('./dev/templates/js-config.txt')
              .pipe(template(sharedVars))
              .pipe(rename('js-config.js'))
              .pipe(removeEmptyLines())
              .pipe(gulp.dest('./dev/js'));
          });
          

          【讨论】:

            【解决方案5】:

            我建议查看sass-extract,它使用原生 sass 功能将计算的变量值提取到 JSON 中。

            此外,如果您使用的是 webpack,sass-extract-loader 将非常容易地像在 const variables = require('sass-extract-loader!./variables.scss'); 中那样要求/导入 sass 文件,并将您的 sass 变量放在一个不错的 JSON 对象中。

            由于它还支持@import 语句,您仍然可以将变量分隔在不同的文件中,无需添加额外的预处理或使用变量分隔 json 文件。

            正如其他答案中提到的,有许多替代方法可以实现这一点,您选择哪一种取决于您的用例和环境。

            免责声明,我是上述两个库的作者。

            【讨论】:

              【解决方案6】:

              如果你使用 webpack,你可以使用 sass-loader 来导出变量,例如:

              $animation-length-ms: $animation-length + 0ms;
              
              :export {
                animationMillis: $animation-length-ms;
              }
              

              然后像这样导入它们

              import styles from '../styles/animation.scss'    
              const millis = parseInt(styles.animationMillis)
              

              https://blog.bluematador.com/posts/how-to-share-variables-between-js-and-sass/

              【讨论】:

              • 这个!这应该是公认的答案。我建议在导出时像:export { animationMillis: strip-unit($animation-length-ms);}strip-unit 一样剥离单元,这样我们就可以直接将变量用作数字而无需解析字符串。
              • 完美解决方案!
              • 在我运行 webpack@5.45.1sass-loader@12.1.0node-sass@6.0.1 的环境中不起作用。变量styles 记录为undefined,因此我无法访问:export 中声明的变量。有什么想法吗?
              【解决方案7】:

              这可以使用gulp-sass-vars-to-js 来完成。它从您的 .scss 文件生成一个 .js 文件。 .js 文件包含在 .scss 文件中声明的所有变量。然后你可以将这个生成的 js 'require' 到你的 .js 中

              【讨论】:

                【解决方案8】:

                sass-ffi 应该可以解决问题,但方式相反(从 JS 到 SASS/SCSS)。它将定义一个名为ffi-require 的函数,它允许您从SASS 中require .js 文件:

                config.js:

                module.exports = {
                     maxColumns: 4,
                };
                

                style.scss:

                $max-columns: ffi-require('./config', 'maxColumns');
                

                适用于 sass-loader (webpack) 和 node-sass

                【讨论】:

                  猜你喜欢
                  • 2011-01-10
                  • 1970-01-01
                  • 2012-12-06
                  • 1970-01-01
                  • 2021-06-10
                  • 2011-02-24
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多