Javascript-форум (https://javascript.ru/forum/)
-   jQuery (https://javascript.ru/forum/jquery/)
-   -   Задать свойтво content для псевдоэллемента after (https://javascript.ru/forum/jquery/39114-zadat-svojjtvo-content-dlya-psevdoehllementa-after.html)

animatio 16.06.2013 19:40

Задать свойтво content для псевдоэллемента after
 
Вот собственно и вопрос .
Есть элемент div.
Как реализовать, чтобы div::after свойство content подтягивалось из переменной (назовем ее userVar).Причем userVar может меняться во время нахождения юзера на странице и вместе с ним должно меняться значение content.
Помогите,пожалуйста,кто знает. Удачного вечера)

danik.js 16.06.2013 20:31

API для изменения свойств псевдоэлементов отсутствует. Поэтому замените свой псевдоэлемент на обычный элемент.
Если же задача принципиальная, то нужно динамически создавать элемент <style> и вставлять в него нужное правило.

animatio 16.06.2013 20:37

Да. Задача на самом деле принципиальная. Если Вам несложно,напишите,как это сделать через динамический стайл. Спасибо.

danik.js 16.06.2013 21:48

Ну примерно в таком ключе надо работать. Код не тестировал. Часть кода нужна для поддержки IE8. В вебкит почему то не получается напрямую установить pseudoRule.style.content ..
<script>
(function(){
    var head = document.head || document.getElementsByTagName('head')[0];
    head.appendChild(document.createElement('style'));
    var styleSheet = document.styleSheets[document.styleSheets.length - 1];
    if (styleSheet.insertRule) {
        styleSheet.insertRule('span:before {}');
    } else {
        styleSheet.addRule('span:before', '');
    }
    var pseudoRule = (styleSheet.cssRules || styleSheet.rules)[0];
    
    this.setPseudoContent = function(content) {
        // почему-то style.content не работает в хроме.
        pseudoRule.style.cssText = 'content:' + ['"','"'].join(content);
    }
})();
</script>
<input onkeydown="setPseudoContent(value)" />
Pseudo:<span></span>

devote 16.06.2013 21:59

danik.js,
в опере не работает

danik.js 16.06.2013 22:02

Цитата:

Сообщение от devote
в опере не работает

Да я хз если честно как оно должно быть. Не сталкивался с подобными задачами пока.

рони 16.06.2013 22:28

Вариант...
<!DOCTYPE HTML>

<html>

<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <script>
function setPseudoContent(value)
{
var style =  document.createElement('style');
var head = document.getElementsByTagName('head')[0];
head.appendChild(style);
style.innerHTML   = "span:before { content: '"+value+"' }"
}
</script>
</head>

<body>
<input onkeyup="setPseudoContent(this.value)" />
<span> проверка</span>

</body>

</html>

devote 16.06.2013 22:46

рони,
а ты видел что происходит в стилях, при таком использовании?
span::before { 
    content: "впвавпавапвапва";
}

span::before { 
    content: "впвавпавапвапв";
}

span::before { 
    content: "впвавпавапвапв";
}

span::before { 
    content: "впвавпавапвап";
}

span::before { 
    content: "впвавпавапва";
}

span::before { 
    content: "впвавпавапв";
}

span::before { 
    content: "впвавпавап";
}

span::before { 
    content: "впвавпав";
}

span::before { 
    content: "впвавпав";
}

span::before { 
    content: "впвавпав";
}

span::before { 
    content: "впвав";
}

span::before { 
    content: "впвав";
}

span::before { 
    content: "впва";
}

span::before { 
    content: "впв";
}

span::before { 
    content: "вп";
}

span::before { 
    content: "вапвп";
}

span::before { 
    content: "вапвп";
}

span::before { 
    content: "вап";
}

span::before { 
    content: "вап";
}

span::before { 
    content: "ва";
}

рони 16.06.2013 22:52

Цитата:

Сообщение от devote
а ты видел что происходит в стилях, при таком использовании?

нет но знаю

рони 16.06.2013 23:03

devote,
Вариант...без повторов
<!DOCTYPE HTML>

<html>

<head>
  <title>Untitled</title>
  <meta charset="utf-8">

  <script>
function setPseudoContent(value)
{
var style =  document.getElementById('style_before')
if(!style){
style =  document.createElement('style');
style.id = 'style_before';
var head = document.getElementsByTagName('head')[0];
head.appendChild(style);
}
style.innerHTML   = "span:before { content: '"+value+"' }"
}
</script>
</head>

<body>
<input onkeyup="setPseudoContent(this.value)" />
<span> проверка</span>

</body>

</html>

devote 16.06.2013 23:57

function queryStyleRule(selector) {
    var sheets = document.styleSheets,
        j, i = sheets.length,
        rules = [];
    for( ;i--; ) {
        try {
            rules = sheets[i].cssRules ? sheets[i].cssRules : sheets[i].rules ? sheets[i].rules : [];
        } catch(_e_) {
            rules = [];
        }
        for(j = rules.length; j--; ) {
            var sel = rules[j].selectorText.replace(/(^|[^:]):(after|before)/i, '$1::$2');
            if (sel.toLowerCase() === selector) {
                return rules[j];
            }
        }
    }
    var style = document.documentElement.firstChild.appendChild(document.createElement('style'));
    try {
        selector = selector.replace(/::(after|before)/, ':$1');
        if (style.sheet) {
            style.sheet.insertRule(selector + '{}', 0);
            return style.sheet.cssRules[0];
        } else if (style.styleSheet) {
            style.styleSheet.addRule(selector, ' ', 0);
            return style.styleSheet.rules[0];
        }
    } catch(_e_) {
        style.parentNode.removeChild(style);
    }
    return null;
}


queryStyleRule('body::after').style.content = '"Hello World!"';;

alert(queryStyleRule('body::after').style.content);

devote 17.06.2013 00:05

<style>
    div:after {
        content: 'Этот текст будем получать с помощью метода queryStyleRule';
    }
</style>
<div>Во как! </div>
<input type="button" onclick="queryStyleRule('div::after').style.content='\'Вот мы его и заменили)))\'';" value="Заменить текст" />
<script>
function queryStyleRule(selector) {
    var sheets = document.styleSheets,
        j, i = sheets.length,
        rules = [];
    for( ;i--; ) {
        try {
            rules = sheets[i].cssRules ? sheets[i].cssRules : sheets[i].rules ? sheets[i].rules : [];
        } catch(_e_) {
            rules = [];
        }
        for(j = rules.length; j--; ) {
            var sel = rules[j].selectorText.replace(/(^|[^:]):(after|before)/i, '$1::$2');
            if (sel.toLowerCase() === selector) {
                return rules[j];
            }
        }
    }
    var style = document.documentElement.firstChild.appendChild(document.createElement('style'));
    try {
        selector = selector.replace(/::(after|before)/, ':$1');
        if (style.sheet) {
            style.sheet.insertRule(selector + '{}', 0);
            return style.sheet.cssRules[0];
        } else if (style.styleSheet) {
            style.styleSheet.addRule(selector, ' ', 0);
            return style.styleSheet.rules[0];
        }
    } catch(_e_) {
        style.parentNode.removeChild(style);
    }
    return null;
}

alert('Текущий текст у псевдо-элемента: ' + queryStyleRule('div::after').style.content);
</script>

рони 17.06.2013 01:07

devote,
:thanks:

danik.js 17.06.2013 04:08

Мой вариант, без поиска существующих правил, исправленный:
<script>
var addRule =  (function(){
    var head = document.head || document.getElementsByTagName('head')[0];
    var style = head.appendChild(document.createElement('style'));
    var styleSheet = style.sheet || style.styleSheet;
    var cssRules = styleSheet.cssRules || styleSheet.rules;

    return function(selector) {
        if (styleSheet.insertRule) {
            styleSheet.insertRule(selector + '{}', cssRules.length);
        } else {
            styleSheet.addRule(selector, ' ', cssRules.length);
        }
        return cssRules[cssRules.length - 1];
    }
})();
    
var pseudoRule = addRule('span:before');
var setPseudoContent = function(content) {
    pseudoRule.style.content = '"' + content + '"';
}
</script>
<input onkeyup="setPseudoContent(value)" />
Pseudo:<span></span>


Проверено в Opera, Firefox, Google Chrome, IE8, IE10.

Цитата:

Сообщение от devote
addRule(selector, 'e:0;', 0);

Вот тут вроде бы достаточно пробел передать в качестве второго аргумента.

devote 17.06.2013 04:41

Цитата:

Сообщение от danik.js
Вот тут вроде бы достаточно пробел передать в качестве второго аргумента.

ну да, верно говоришь.. подправил свой код

devote 17.06.2013 04:48

Цитата:

Сообщение от danik.js
// почему-то style.content не работает в хроме.

любопытно почему у тебя не работает... у меня все гуд.. Может ты пытаешься назначить свойству просто значение вида:
style.content = 'ololo';

хотя по правилам нужно:
style.content = '"ololo"';
// или
style.content = 'attr(data-my-attr)';

devote 17.06.2013 04:55

кстати о птичках.. а нафига такой хренью заниматься, если можно все упростить))

Для ИЕ8 обязательно должен присутствовать у спана атрибут, иначе ИЕ8 не будет обновлять значение
<style>
    span:before {
        content: attr(data-before-content);
    }
</style>
<input onkeyup="document.getElementById('spanId').setAttribute('data-before-content', this.value)" />
Pseudo:<span id="spanId" data-before-content="Начальное значение псевдо-элемента, может быть пустым значением"></span>

danik.js 17.06.2013 06:14

Цитата:

Сообщение от devote
любопытно почему у тебя не работает... у меня все гуд.. Может ты пытаешься назначить свойству просто значение вида..

Я - лох ((
Цитата:

Сообщение от devote
нафига такой хренью заниматься, если можно все упростить

Блин, реально круто )

Кстати, как заэкранировать кавычку? В моем варианте текст с двойной кавычкой не проходит..

devote 17.06.2013 10:11

Цитата:

Сообщение от danik.js
Кстати, как заэкранировать кавычку? В моем варианте текст с двойной кавычкой не проходит..

просто использовать &quot;

devote 17.06.2013 10:31

Цитата:

Сообщение от danik.js
Кстати, как заэкранировать кавычку? В моем варианте текст с двойной кавычкой не проходит..

И еще у меня прокатывает такой вариант:
style.content = JSON.stingify('Мой текст в "Кавычках" и \'одинарных\' тоже');

animatio 17.06.2013 14:38

Цитата:

Сообщение от danik.js
Мой вариант, без поиска существующих правил, исправленный:

То,что нужно спасибо огромное. Если можно скажи а как установить значение по-умолчанию. А то если через CSS задать,то потом это значение всю дорогу отображается после реального значения. Ну например: span:before{content:'1000'},при значении 50, будет отображено 501000


Часовой пояс GMT +3, время: 22:29.