将SASS变量传递给javascript的行业标准方法是什么?

时间:2013-08-27 04:06:57

标签: javascript html sass

我环顾四周,我已经看到了一个解决方案,在你的html中,你有一个专用于将sass变量传递给javascript的标签。我正在谈论

的第二个答案

Is there a way to import variables from javascript to sass or vice versa?

我也尝试过使用html

<div class="selector"></div>

用css

.selector { content: "stuff"; }

但是看看开发人员工具中的dom,即使我们可以在渲染页面上看到它,它也不会被添加,所以我无法用javascript来获取它

$('.selector').text()

每个人都是如何做到的?

4 个答案:

答案 0 :(得分:10)

不确定“行业标准”,但它是一种非常方便的技术,并不太难。无法通过text()获取伪元素的内容,但您必须使用getComputedStyle

使用body:after的示例:

Sass (使用compass breakpoint extension):

body:after {
  display: none;

  @include breakpoint($bp-wide) {
    content: "wide";
  }

  @include breakpoint($bp-medium) {
    content: "medium";
  }

  @include breakpoint($bp-small) {
    content: "small";
  }
}

<强>的JavaScript

if (window.getComputedStyle) {
  var mq = window.getComputedStyle(document.body,':after').getPropertyValue('content');
}

if (mq.indexOf('small') !== -1) {
  // do something
}

信用:我第一次看到这种技术:https://coderwall.com/p/_ldtkg

答案 1 :(得分:4)

我认为通过CSS content属性注入SASS变量是一种非常糟糕的做法。

相反,您可以将变量存储在一个单独的位置,并让它们由SASS和JS读取。

首先,在breakpoints.json文件中存储断点列表:

["0", "300px", "500px", "700px", "900px", "1100px"]

然后使用Ruby读取此JSON文件,并通过SASS函数将其内容作为SASS列表提供。把它放入你的指南针config.rb

sass_options = { :custom => {'breakpoint_file' => 'breakpoints.json'} }

# This creates a SASS function debug() that returns $debug into SASS
module Sass::Script::Functions
  def breakpoints

    # Reading an array of breakpoints into a file
    unless breakpoints_array_raw = JSON.load( IO.read( options[:custom]['breakpoint_file'] ))
      raise Sass::SyntaxError.new("Error: Breakpoints file '#{options[:custom]['breakpoint_file']}' does not exist.")
    end

    # Converting strings in the array to SASS String literals
    breakpoints_array_sassy = breakpoints_array_raw.map { |s| Sass::Script::String.new(s) }

    # Returning the list into SASS
    Sass::Script::List.new( breakpoints_array_sassy, :space )
  end
end

在您的SASS代码中,读取这样的断点:

$breakpoints: breakpoints()

在JS中,使用jQuery&#39; .get方法来请求JSON文件,如下所示:

var
  breakpoints = [],
  requestBreakpoints = $.get('breakpoints.json');

requestBreakpoints.done(function (response, textStatus, jqXHR){
    breakpoints = response; // You might want to remove "px" here
});

当我组装此设置时,我找到了现有解决方案here,但我决定使用我最喜欢的SASS工具重新实现它:SingularityBreakpoint Slicer

为了您的方便,我已经构建了一个概念验证GitHub project,其中包含了一些很好的设置,包含一些丑陋的JS代码。 :)

这里是live demo

答案 2 :(得分:2)

通过CSS content属性共享状态似乎很脏。我也不喜欢提出额外的XHR请求。

我想过构建一个只编译SASS文件和JS模块的自定义解决方案。但事实证明,这是一个名为rosettanpm软件包。它正是如此。输出格式非常灵活,我花了很长时间才将其设置为Grunt.js任务。

$ npm install rosetta

此处的示例 Gruntfile.js

module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
      watch: {
          css: {
              files: ['sass/*.scss', 'sass/lib/*.scss', 'rosetta/*.rose'],
              tasks: ['rosetta', 'compass']
          }
      },
      compass: {
          dist: {
              options: {
                  sassDir: 'sass',
                  cssDir: '../static/css',
                  imagesDir: '../static/img',
                  javascriptsDir: '../static/js'
              }
          }
      },
      rosetta: {
          default: {
             src: ['rosetta/*.rose'],
             options: {
                 jsFormat: 'requirejs',
                 cssFormat: 'scss',
                 jsOut: '../static/js/lib/rosetta.js',
                 cssOut: 'sass/_shared_variables.scss'
             }
          }
      }
  });

  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-compass');
  grunt.loadNpmTasks('rosetta');
  grunt.registerTask('default', ['watch']);

};

package.json

{
  "name": "",
  "version": "0.0.0",
  "description": "",
  "main": "Gruntfile.js",
  "dependencies": {
    "grunt": "^0.4.5",
    "grunt-cli": "^0.1.13",
    "grunt-contrib-compass": "^0.9.1",
    "grunt-contrib-watch": "^0.6.1",
    "rosetta": "git+https://github.com/ukolka/rosetta.git"
  },
  "devDependencies": {},
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

毕竟你只需要在SASS中导入 _shared_variables.scss 并在JavaScript中使用 rosetta.js 模块来访问公共变量。当您对* .rose文件进行更改时,您的样式和JS将会更新。

答案 3 :(得分:1)

如果您使用的是GULPGRUNT(我希望您使用的是第一个)

此示例显示如何使用gulp

执行此操作

定义gulpfile或其他文件中的颜色,然后将其导入gulpfile,然后你可以动态构建SCSS变量和javascript,如下所示:

variables_template.scss(不在主scss文件中导入)

...
$colors : ([COLORS])
...

app.js(一些保存颜色变量的js文件)

var appColors = {[COLORS]};

gulpfile.js

var gulp    = require('gulp'),
    gutil   = require('gulp-util'),
    replace = require('gulp-replace');

var appColors = {
   "red"   : "#d63737",
   "green" : "#69c962"
};

gulp.task('scssVars', ()=>{
    var colorsString = JSON.stringify(appColors);
    colorsString  = colorsString.slice(2,colorsString.length - 2);

    return gulp.src('css/variables_template.scss')
        .pipe(replace(/[COLORS]/g, colorsString ))
        .pipe(rename('variables.scss'))
        .pipe(gulp.dest('/'))
});

// do more of less the same for your app.js, only without renaming, if possible

用于SCSS变量的类似NPM gulp包: