Вопрос по javascript, css, gruntjs, angularjs – Решение для двух связывания между угловым и таблицей стилей

5

Я знаю, это звучит глупо, но я пишу редактор wysiwyg, который позволяет дизайнерам создавать руководства по стилю. Я очень увлекся двухсторонним связыванием в угловых и было любопытно, можно ли было двухстороннее связывание между листом CSS иng-model поле ввода. В настоящее время я делаю динамическое руководство по стилю, которое позволяет дизайнеру выбирать основные, второстепенные цвета страницы. Эти цвета изменят всю тему сайта равномерно, и было бы здорово сделать это из самой таблицы стилей.

HTML

<input type="text" ng-model="color.primary" />
<button class="btn primary-color" />

CSS

.primary-color {
  background: {{color.primary}};
}

JS $ scope.color {primary: '00f', Secondary: '# e58'}

Я знаю, что есть много директив, таких какng-style а такжеng-class Но я боюсь, что каждый тег должен быть директивой, потому что все может иметь тег ng-style / ng-class. Это делает мой код не очень сухим и сложным в обслуживании.

Что делать, если я хочу динамическое руководство по стилю CSS. Лист, который я мог бы хранить в виде парных ключевых значений CSS на сервере, например в Firebase, возможно, даже в 3way, связывая изменение цветов в реальном времени? Я почти уверен, что это не может быть достигнуто с использованием исключительно угловых ... есть ли у кого-нибудь идеи о предварительных компиляторах или взломах для выполнения этой задачи, чтобы это привело к одному чистому парню?

Просто плюнь, но, возможно, у тебя мог бы быть сервис, который занимается сменой стилей. Я попытался выполнить поиск, и кажется, что CSS-файлы на самом деле не доступны напрямую из Javascript, я думаю, что использование селекторов jQuery для получения элементов, основанных на классе, и обновление их стилей - лучший выбор. Вы можете реализовать это в сервисе и вставить ее в директиву, которую затем сможете использовать во входах, из которых вы хотите использовать модель. shaunhusain

Ваш Ответ

1   ответ
5

Над этим было весело работать.

У вас есть доступ ко всем стилям на странице черезdocument.styleSheets, так что вам просто нужно ограничить правила стиля. Итак, скажем, что у меня есть этот класс:

.class {
    font-size: 20px;
    color: blue;
}

Как jsfiddle реализует таблицы, это третья таблица стилей, добавленная в документ, поэтому я могу просто назначить область видимости следующим образом:

myApp.controller('TestController', ['$scope', function ($scope) {
    $scope.styles = document.styleSheets[3].rules;     
}]); 

Это позволит вам делать такие вещи, как$scope.styles[0].style['color'] = 'red' изменить цвет всего с классом на красный. Так как это первое, что есть в массиве стилей.

Но это недостаточно круто, поэтому мы хотим создать директиву, в которой мы можем изменить их с помощью пользовательского интерфейса. Итак, мы бы хотели знать все, что контролирует класс, чтобы создавать для них элементы управления, поэтому мы можем манипулировать строкой css, чтобы получить все это.

Затем мы должны создать временный объект в рамках директивы, который начинается со всех стилей. Причина в том, что таблицы стилей имеют проверку, поэтому при вводе во ввод, если вы делаете что-то вроде$scope.styles[0].style['color'] = 'g' и он был красным, он просто сбросится на красный.

Таким образом, мы создаем входные данные для каждого типа стиля с помощью ng-модели нашего temp, затем просто слушаем изменения и пытаемся назначить таблицу стилей.

Я создалиграть на скрипке где я это реализую, но директива выглядит так.

myApp.directive('styler', function() {
    return {
        scope: {
            styles: '='
        },
        restrict: 'EA',
        template: '<div ng-repeat="type in types">{{type}} <input ng-change="Change(type)" ng-model="temp_styles[type]"/></div>',
        link: function(scope, elt, attrs) {      
            // get the actual styles
            var types = scope.styles.cssText.replace(/ /g, '').split('{')[1].split('}')[0].split(';');
            scope.types = [];
            scope.temp_styles = {};
            // get rid of "" element at the end
            types.pop();
            for (var i in types) {
                var split = types[i].split(':');
                scope.types.push(split[0]);
                scope.temp_styles[split[0]] = split[1];
            }
            scope.Change = function(type) {
                scope.styles.style[type] = scope.temp_styles[type];
            };
        }
    };
});

Классная, динамичная двухсторонняя привязка стилей!

Надеюсь, это помогло!

В общем, я думаю, что было бы лучше, если бы это был другой вопрос, но, поскольку это не очень хороший ответ, это нормально. Вы можете либо добавить класс к стайлеру в html и удалить его в функции ссылки, либо передать его как '@' стайлеру и просмотреть все таблицы стилей и проверить текст селектора. hassassin
Hassassin ... браво мой человек .. это здорово. Я пометил это правильно, но не могли бы вы узнать, как использовать REGEX или каким-либо другим способом нацеливать на изолированную область стилей: '=', используя строку класса, а не позицию массива? Я сделал jsfiddle excersize, который может быть интересным для вас ...jsfiddle.net/Jk28j/4  Я могу задать новый вопрос, если вы хотите больше очков, лол Matthew Harwood
Вашdocument.styleSheets[3].rules должно бытьdocument.styleSheets[3].cssRules вместо. David R Tribble
Хороший вызов, cssRules кажется стандартом W3C. hassassin

Похожие вопросы