Można by pomyśleć, że byłoby to proste pytanie, na które można odpowiedzieć, ze wszystkim innym, co może zrobić jQuery. Niestety problem sprowadza się do problemu technicznego: css: after i: before reguły nie są częścią DOM i dlatego nie można ich zmienić za pomocą metod DOM jQuery.
Tam są sposoby, aby manipulować tych elementów przy użyciu JavaScript i / lub CSS obejścia; to, którego używasz, zależy od twoich dokładnych wymagań.
Zacznę od tego, co jest powszechnie uważane za „najlepsze” podejście:
1) Dodaj / usuń z góry określoną klasę
W tym podejściu stworzyłeś już klasę w swoim CSS w innym stylu :after
lub :before
stylu. Umieść tę „nową” klasę później w arkuszu stylów, aby upewnić się, że zastępuje:
p:before {
content: "foo";
}
p.special:before {
content: "bar";
}
Następnie możesz łatwo dodać lub usunąć tę klasę za pomocą jQuery (lub waniliowego JavaScript):
$('p').on('click', function() {
$(this).toggleClass('special');
});
$('p').on('click', function() {
$(this).toggleClass('special');
});
p:before {
content: "foo";
color: red;
cursor: pointer;
}
p.special:before {
content: "bar";
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
- Plusy: Łatwy do wdrożenia dzięki jQuery; szybko zmienia wiele stylów jednocześnie; wymusza separację problemów (izolowanie CSS i JS od HTML)
- Minusy: CSS musi być wcześniej napisany, więc zawartość
:before
lub :after
nie jest całkowicie dynamiczna
2) Dodaj nowe style bezpośrednio do arkusza stylów dokumentu
Możliwe jest użycie JavaScript do dodawania stylów bezpośrednio do arkusza stylów dokumentu, w tym stylów :after
i :before
. jQuery nie zapewnia wygodnego skrótu, ale na szczęście JS nie jest tak skomplikowany:
var str = "bar";
document.styleSheets[0].addRule('p.special:before','content: "'+str+'";');
var str = "bar";
document.styleSheets[0].addRule('p.special:before', 'content: "' + str + '";');
p:before {
content: "foo";
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p class="special">This is a paragraph</p>
<p>This is another paragraph</p>
.addRule()
a pokrewne .insertRule()
metody są dziś dość dobrze wspierane.
Jako wariant możesz również użyć jQuery, aby dodać do dokumentu zupełnie nowy arkusz stylów, ale niezbędny kod nie jest bardziej przejrzysty:
var str = "bar";
$('<style>p.special:before{content:"'+str+'"}</style>').appendTo('head');
var str = "bar";
$('<style>p.special:before{content:"' + str + '"}</style>').appendTo('head');
p:before {
content: "foo";
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p class="special">This is a paragraph</p>
<p>This is another paragraph</p>
Jeśli mówimy o „manipulowaniu” wartościami, a nie tylko ich dodawaniu, możemy również odczytać istniejące :after
lub :before
style, stosując inne podejście:
var str = window.getComputedStyle(document.querySelector('p'), ':before')
.getPropertyValue('content');
var str = window.getComputedStyle($('p')[0], ':before').getPropertyValue('content');
console.log(str);
document.styleSheets[0].addRule('p.special:before', 'content: "' + str+str + '";');
p:before {
content:"foo";
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p class="special">This is a paragraph</p>
<p>This is another paragraph</p>
Możemy wymienić document.querySelector('p')
z $('p')[0]
przy użyciu jQuery, dla nieco krótszy kod.
- Plusy: każdy ciąg może być dynamicznie wstawiany do stylu
- Minusy: oryginalne style nie są zmieniane, tylko nadpisywane; wielokrotne użycie (ab) może spowodować dowolną rozbudowę DOM
3) Zmień inny atrybut DOM
Możesz także użyć attr()
w swoim CSS do odczytania określonego atrybutu DOM. ( Jeśli przeglądarka obsługuje :before
, obsługuje attr()
również. ) Łącząc to z content:
starannie przygotowanym CSS, możemy zmieniać zawartość (ale nie inne właściwości, takie jak margines lub kolor) :before
i :after
dynamicznie:
p:before {
content: attr(data-before);
color: red;
cursor: pointer;
}
JS:
$('p').on('click', function () {
$(this).attr('data-before','bar');
});
$('p').on('click', function () {
$(this).attr('data-before','bar');
});
p:before {
content: attr(data-before);
color: red;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
Można to połączyć z drugą techniką, jeśli CSS nie może zostać przygotowany wcześniej:
var str = "bar";
document.styleSheets[0].addRule('p:before', 'content: attr(data-before);');
$('p').on('click', function () {
$(this).attr('data-before', str);
});
var str = "bar";
document.styleSheets[0].addRule('p:before', 'content: attr(data-before) !important;');
$('p').on('click', function() {
$(this).attr('data-before', str);
});
p:before {
content: "foo";
color: red;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
- Plusy: Nie tworzy nieskończonych dodatkowych stylów
- Minusy:
attr
w CSS można stosować tylko do ciągów treści, a nie adresów URL lub kolorów RGB