Какой стандартный способ передачи переменной SASS в javascript?
Я огляделся и увидел одно решение, где в вашем html у вас будет тег, посвященный передаче sass-переменных в javascript. Я говорю о втором ответе
Есть ли способ импортировать переменные из javascript в sass или наоборот?
Я также пробовал использовать html
<div class="selector"></div>
с css
.selector { content: "stuff"; }
но глядя на dom в инструментах разработчика, он не добавляется, хотя мы можем видеть его на отображаемой странице, поэтому я не могу его забрать с помощью javascript
$('.selector').text()
Как все это делают?
Ответы
Ответ 1
Не уверен в "отраслевом стандарте", но это очень удобный способ и не слишком сложный. Содержимое псевдоэлементов недоступно через text()
, но вы должны использовать getComputedStyle
.
Пример использования body:after
:
Sass (используя расширение точки останова компаса):
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
Ответ 2
Я считаю, что инъекция переменных SASS с помощью CSS content
- это очень хакерский способ сделать что-то.
Вместо этого вы можете хранить переменные в отдельном месте и читать их как SASS, так и JS.
Сначала сохраните список точек останова в файле breakpoints.json
:
["0", "300px", "500px", "700px", "900px", "1100px"]
Затем используйте Ruby, чтобы прочитать этот JSON файл и сделать его содержимое доступным как список SASS через функцию SASS. Поместите это в свой Compass 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 .get
для запроса файла JSON следующим образом:
var
breakpoints = [],
requestBreakpoints = $.get('breakpoints.json');
requestBreakpoints.done(function (response, textStatus, jqXHR){
breakpoints = response; // You might want to remove "px" here
});
Когда я собирал эту настройку, я нашел существующее решение здесь, но я решил переопределить его, используя мои любимые инструменты SASS: Singularity и Slice для точки останова.
Для вашего удобства я разработал концептуальный проект GitHub со всем, что было настроено хорошо, с некоторым уродливым JS-кодом.:)
И здесь живая демонстрация!
Ответ 3
Совпадение состояния через свойство CSS content
кажется грязным. Мне также не нравится идея делать дополнительные запросы XHR.
Я думал о создании пользовательского решения, которое бы просто скомпилировало SASS файл и JS-модуль. Но оказалось, что пакет npm
называется rosetta. Он делает именно это. Форматы вывода довольно гибкие, и мне не потребовалось много времени, чтобы настроить его как задачу 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"
}
После всего этого вам просто нужно импортировать _shared_variables.scss в SASS и использовать модуль rosetta.js в вашем JavaScript для доступа к общим переменным. Когда вы вносите изменения в файлы *.rose, ваши стили и JS будут обновлены.
Ответ 4
Если вы используете GULP
или GRUNT
(надеюсь, вы используете первый)
В этом примере показано, как это сделать, используя 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
Аналогичные пакеты NPM gulp для переменных SCSS: