回答:
(セレクターがないため)インラインstyle = "..."属性に疑似クラスを設定できないのと同じ方法で、特定の要素だけで疑似クラスのスタイルを設定することはできません。
たとえば、ルールを追加して、スタイルシートを変更することでそれを行うことができます。
#elid:hover { background: red; }
影響を与えたい各要素に一意のIDがあり、それを選択できると仮定します。
理論的には、必要なドキュメントはhttp://www.w3.org/TR/DOM-Level-2-Style/Overview.htmlです。これは、次のような構文を使用して(既存の埋め込みまたはリンクされたスタイルシートがある場合)できることを意味します。
document.styleSheets[0].insertRule('#elid:hover { background-color: red; }', 0);
document.styleSheets[0].cssRules[0].style.backgroundColor= 'red';
もちろん、IEには独自の構文が必要です。
document.styleSheets[0].addRule('#elid:hover', 'background-color: red', 0);
document.styleSheets[0].rules[0].style.backgroundColor= 'red';
古いブラウザーとマイナーブラウザーはどちらの構文もサポートしない可能性があります。動的なスタイルシートの変更は、正しく行うのが非常に煩わしく、めったに必要とされず、歴史的に面倒なので、めったに行われません。
function sameOrigin(url) { var loc = window.location, a = document.createElement('a'); a.href = url; return a.hostname === loc.hostname && a.port === loc.port && a.protocol === loc.protocol; }
JSでスタイルシートを操作するための有効なユースケースがあると思うので、このための小さなライブラリを一緒に投げました。理由:
クロスブラウザのものに対処する関数:
addCssRule = function(/* string */ selector, /* string */ rule) {
if (document.styleSheets) {
if (!document.styleSheets.length) {
var head = document.getElementsByTagName('head')[0];
head.appendChild(bc.createEl('style'));
}
var i = document.styleSheets.length-1;
var ss = document.styleSheets[i];
var l=0;
if (ss.cssRules) {
l = ss.cssRules.length;
} else if (ss.rules) {
// IE
l = ss.rules.length;
}
if (ss.insertRule) {
ss.insertRule(selector + ' {' + rule + '}', l);
} else if (ss.addRule) {
// IE
ss.addRule(selector, rule, l);
}
}
};
テンプレート文字列にcssを配置するだけです。
const cssTemplateString = `.foo:[psuedoSelector]{prop: value}`;
次に、スタイル要素を作成し、文字列をスタイルタグに配置してドキュメントに添付します。
const styleTag = document.createElement("style");
styleTag.innerHTML = cssTemplateString;
document.head.insertAdjacentElement('beforeend', styleTag);
残りは、特異性が対応します。その後、スタイルタグを動的に削除および追加できます。これは、ライブラリの単純な代替手段であり、DOMのスタイルシート配列をいじくります。ハッピーコーディング!
insertAdjacentElement
主要なブラウザー(Chrome、Firefox、Edge)で2つの引数が必要です。最初の引数は、参照要素に対する相対的な位置を確立します(ここを参照)。これは最近の変更ですか?(答えに 'beforeend'を追加しました)。
私のトリックは、属性セレクターを使用することです。JavaScriptを使用すると、属性を簡単に設定できます。
CSS
.class{ /*normal css... */}
.class[special]:after{ content: 'what you want'}
JavaScript
function setSpecial(id){ document.getElementById(id).setAttribute('special', '1'); }
html
<element id='x' onclick="setSpecial(this.id)"> ...
別の選択肢があります。擬似クラスを直接操作する代わりに、「ホバー」クラスや「訪問済み」クラスなど、同じものをモデル化する実際のクラスを作成します。通常の「。」でクラスをスタイルします。構文を使用すると、JavaScriptを使用して、適切なイベントが発生したときに要素からクラスを追加または削除できます。
:before
&:after
はクラスではなく、疑似要素です。
JavaScriptを使用して疑似クラスルールを直接設定する代わりに、異なるCSSファイルで異なるルールを設定し、JavaScriptを使用して1つのスタイルシートをオフに切り替え、別のスタイルシートをオンに切り替えることができます。メソッドは、A List Apart(詳細についてはqv。)で説明されています。
CSSファイルを次のように設定します。
<link rel="stylesheet" href="always_on.css">
<link rel="stylesheet" title="usual" href="preferred.css"> <!-- on by default -->
<link rel="alternate stylesheet" title="strange" href="alternate.css"> <!-- off by default -->
そして、JavaScriptを使用してそれらを切り替えます:
function setActiveStyleSheet(title) {
var i, a, main;
for(i=0; (a = document.getElementsByTagName("link")<i>); i++) {
if(a.getAttribute("rel").indexOf("style") != -1
&& a.getAttribute("title")) {
a.disabled = true;
if(a.getAttribute("title") == title) a.disabled = false;
}
}
}
すでに述べたように、これはブラウザがサポートするものではありません。
スタイルを動的に思いついていない場合(つまり、データベースなどからスタイルを取得している場合)は、ページの本文にクラスを追加することで、この問題を回避できるはずです。
CSSは次のようになります。
a:hover { background: red; }
.theme1 a:hover { background: blue; }
そして、これを変更するJavaScriptは次のようになります。
// Look up some good add/remove className code if you want to do this
// This is really simplified
document.body.className += " theme1";
element.classList.add
十分にサポートされていませんか?私は人々がしているのを見続けelement.className +=
ます。
スタイルシートの切り替えは、その方法です。以下は、動的にスタイルシートを作成するためのライブラリであり、その場でスタイルを設定できます。
http://www.4pmp.com/2009/11/dynamic-css-pseudo-class-styles-with-jquery/
ここに2つの関数を含むソリューションがあります:addCSSclassはドキュメントに新しいcssクラスを追加し、toggleClassはそれをオンにします
この例では、divにカスタムスクロールバーを追加しています
// If newState is provided add/remove theClass accordingly, otherwise toggle theClass
function toggleClass(elem, theClass, newState) {
var matchRegExp = new RegExp('(?:^|\\s)' + theClass + '(?!\\S)', 'g');
var add = (arguments.length > 2 ? newState : (elem.className.match(matchRegExp) === null));
elem.className = elem.className.replace(matchRegExp, ''); // clear all
if (add) elem.className += ' ' + theClass;
}
function addCSSclass(rules) {
var style = document.createElement("style");
style.appendChild(document.createTextNode("")); // WebKit hack :(
document.head.appendChild(style);
var sheet = style.sheet;
rules.forEach((rule, index) => {
try {
if ("insertRule" in sheet) {
sheet.insertRule(rule.selector + "{" + rule.rule + "}", index);
} else if ("addRule" in sheet) {
sheet.addRule(rule.selector, rule.rule, index);
}
} catch (e) {
// firefox can break here
}
})
}
let div = document.getElementById('mydiv');
addCSSclass([{
selector: '.narrowScrollbar::-webkit-scrollbar',
rule: 'width: 5px'
},
{
selector: '.narrowScrollbar::-webkit-scrollbar-thumb',
rule: 'background-color:#808080;border-radius:100px'
}
]);
toggleClass(div, 'narrowScrollbar', true);
<div id="mydiv" style="height:300px;width:300px;border:solid;overflow-y:scroll">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed a eros metus. Nunc dui felis, accumsan nec aliquam quis, fringilla quis tellus. Nulla cursus mauris nibh, at faucibus justo tincidunt eget. Sed sodales eget erat consectetur consectetur. Vivamus
a diam volutpat, ullamcorper justo eu, dignissim ante. Aenean turpis tortor, fringilla quis efficitur eleifend, iaculis id quam. Quisque non turpis in lacus finibus auctor. Morbi ullamcorper felis ut nulla venenatis fringilla. Praesent imperdiet velit
nec sodales sodales. Etiam eget dui sollicitudin, tempus tortor non, porta nibh. Quisque eu efficitur velit. Nulla facilisi. Sed varius a erat ac volutpat. Sed accumsan maximus feugiat. Mauris id malesuada dui. Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Sed a eros metus. Nunc dui felis, accumsan nec aliquam quis, fringilla quis tellus. Nulla cursus mauris nibh, at faucibus justo tincidunt eget. Sed sodales eget erat consectetur consectetur. Vivamus a diam volutpat, ullamcorper justo
eu, dignissim ante. Aenean turpis tortor, fringilla quis efficitur eleifend, iaculis id quam. Quisque non turpis in lacus finibus auctor. Morbi ullamcorper felis ut nulla venenatis fringilla. Praesent imperdiet velit nec sodales sodales. Etiam eget
dui sollicitudin, tempus tortor non, porta nibh. Quisque eu efficitur velit. Nulla facilisi. Sed varius a erat ac volutpat. Sed accumsan maximus feugiat. Mauris id malesuada dui.
</div>
REACTを使用する場合、ラジウムと呼ばれるものがあります。ここでとても便利です:
インタラクティブなスタイルが指定されている場合は、プロップにハンドラーを追加します(例::hoverのonMouseEnter、必要に応じて既存のハンドラーをラップ)
いずれかのハンドラーがトリガーされた場合(ホバーなど)、RadiumはsetStateを呼び出して、コンポーネントの状態オブジェクトのRadium固有のフィールドを更新します
再レンダリング時に、要素のキーまたは参照をラジウム固有の状態で検索することにより、適用されるすべてのインタラクティブスタイル、たとえば:hoverを解決します。