Есть ли способ импортировать переменные из javascript в sass или наоборот?

Я создаю сетку css, основанную на концепции блоков. Итак, у меня есть базовый файл, например:

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

И он используется миксином:

@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 не сопоставляется ни с чем напрямую, поэтому мне пришлось бы придумать хакерский способ отобразить его в div. Есть ли более чистый способ обмена значениями из sass/css в javascript или наоборот?


person Jeremy Smith    schedule 19.02.2012    source источник


Ответы (8)


Вы можете прочитать файл sass с помощью скрипта на стороне сервера, «разобрать» его и повторить значения, которые вам нужны для javascript.

person Corubba    schedule 19.02.2012

Если вы используете 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/

person velop    schedule 13.12.2017
comment
Этот! Это должен быть принятый ответ. И я рекомендую разделять блок при экспорте, например :export { animationMillis: strip-unit($animation-length-ms);}, с помощью strip-unit, поэтому мы можем напрямую использовать переменную как число без необходимости анализировать строку. - person Martin; 20.05.2020
comment
Идеальное решение! - person mmied; 19.04.2021

Я считаю свое решение довольно глупым; но ведь работает...

В моем _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.

Если у кого-то есть что-то еще, оно должно быть чище, чем это...

person ericx    schedule 25.06.2012

sass-ffi должен помочь, но наоборот (с JS на SASS/SCSS). Он определит функцию с именем ffi-require, которая позволяет вам require .js файлы из SASS:

config.js:

module.exports = {
     maxColumns: 4,
};

style.scss:

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

Работает с sass-loader (веб-пакет) и node-sass.

person futpib    schedule 13.05.2019

Я хотел бы добавить, что теперь есть несколько способов обмена данными между Sass и JavaScript с использованием JSON. Вот несколько ссылок на статьи с подробным описанием различных техник:

Вероятно, это всего лишь вопрос времени, когда импорт JSON станет изначально поддерживаться в Sass.

person Teo Dragovic    schedule 22.10.2014

Я бы порекомендовал посмотреть sass-extract, который использует собственные функции sass для извлечения вычисляемой переменной. значения в JSON.

Кроме того, если вы используете веб-пакет, sass-extract-loader очень упростит просто потребуйте/импортируйте файлы sass, как в const variables = require('sass-extract-loader!./variables.scss');, и поместите свои переменные sass в красивый объект JSON.

Поскольку он также поддерживает операторы @import, вы все равно можете разделить свои переменные в разных файлах, и вам не нужно добавлять дополнительную предварительную обработку или отдельные файлы json с переменными.

Есть много альтернативных способов сделать это, как упоминалось в других ответах, и какой из них вы выберете, будет зависеть от вашего варианта использования и среды.

Отказ от ответственности, я являюсь автором обеих упомянутых библиотек.

person jgranstrom    schedule 29.01.2017

Другим способом может быть использование gulp-template, чтобы вы могли создавать любую структуру для своего JavaScript.

Совместное использование переменных между Javascript и Sass с помощью Gulp с шаблоном gulp https://youtu.be/UVeUq8gMYco

Он создан с нуля, чтобы люди могли увидеть его с нуля, и есть репозиторий git с конечным результатом:

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'));
});
person Pocketninja    schedule 24.10.2016