Ответ 1
Вы можете прочитать sass файл со стороны сервера script, "разобрать" его и повторить значения, необходимые для javascript.
Я создаю сетку 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-столбцы не привязаны ни к чему напрямую, поэтому мне придется придумать хакерский способ сделать это в div. Есть ли более чистый способ совместного использования значений из sass/css в javascript или наоборот?
Вы можете прочитать sass файл со стороны сервера script, "разобрать" его и повторить значения, необходимые для javascript.
Я считаю, что мое решение довольно хоккейное; но он работает...
В моем _base.scss
у меня есть определенные переменные:
$menu_bg: rgb(45, 45, 45);
$menu_hover: rgb(0, 0, 0);
В a 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 script:
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.
Если у кого-то есть что-то еще, это должно быть чище, чем это...
Я хотел бы добавить, что теперь есть несколько способов обмена данными между Sass и JavaScript с помощью JSON. Вот несколько ссылок на статьи, описывающие различные методы:
Вероятно, это всего лишь вопрос времени, пока импорт JSON не будет поддерживаться изначально в Sass.
Я бы рекомендовал посмотреть sass-extract, который использует собственные функции sass для извлечения вычисленных значений переменных в JSON.
Также, если вы используете webpack sass-extract-loader, вам будет легко просто потребовать/импортировать файлы sass, как в const variables = require('sass-extract-loader!./variables.scss');
и ваши переменные sass в приятном объекте JSON.
Так как он также поддерживает операторы @import
, вы все равно можете разделить свои переменные в разных файлах и не нужно добавлять дополнительную предварительную обработку или отдельные json файлы с переменными.
Существует много альтернативных способов достижения этого, как указано в других ответах, и который вы выберете, будет зависеть от вашего использования и среды.
Отказ от ответственности, я являюсь автором обеих упомянутых библиотек.
Если вы используете 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/
Другим способом может быть использование gulp -template, чтобы вы могли создать любую структуру, которая вам нужна для вашего JavaScript.
Обмен переменными между Javascript и Sass с помощью Gulp с gulp -template 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, или меньше или что вы хотите.
сохранен на. /dev/templates/sass -config.txt
<% _.each(defaults, function(category, key) { %>
// Var <%= key %>
<% _.each(category, function(value, key) { %>
$<%= key %>: <%= value %>;
<% }) %>
<% }) %>
сохранен в. /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++ %>
<% }); %>
};
<% }) %>
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'));
});
Это можно сделать, используя gulp-sass-vars-to-js. Он создает файл .js из вашего .scss файла. Файл .js содержит все переменные, объявленные в вашем .scss файле. Затем вы можете "потребовать" этот сгенерированный js в ваш .js
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
(webpack) и node-sass
.