stromfeldt
(Allan Strømfeldt Christensen)
1
Automatic Dark Mode color scheme switching は素晴らしい機能追加で、これを統合していただきありがとうございます!
(自動)色テーマの切り替えが可能になった今、ブログに埋め込まれたコメントでも、Discourse のライトモードとダークモードを行き来して切り替える方法はないかと考えています。具体的には、私の Ghost ブログには、ユーザーがクリックして手動でライトモードとダークモードを切り替えられるトグルがあります。ブログの CSS では Discourse の iframe 内の CSS に影響を与えられないことは承知していますが、この新機能により、そのトグルで Discourse の色テーマも切り替えられる別の方法はないでしょうか?コメント付きの投稿の例は、こちらの投稿 の下部でご確認いただけます。
「いいね!」 11
pmusaraj
(Penar Musaraj)
2
これは理論的には可能ですが、少し複雑です。現時点では、埋め込みコメントエンドポイントにダークモードの自動切り替え機能は追加されていません。これを追加することはできますが、ブラウザがダークモードに切り替わった際にあなたの Ghost サイトも自動的にダークモードに切り替わる場合に限って機能します。しかし、あなたの Ghost サイトはダークモード切り替えボタンを使用しているようです。これは Discourse の実装では機能しません。
あなたの具体的なケースでは、ボタンをクリックした際に Discourse の埋め込みコメント iframe 内のクラスを切り替え、そのクラスを使って埋め込みスタイルシート内の色を切り替えることができます。
「いいね!」 13
stromfeldt
(Allan Strømfeldt Christensen)
3
なるほど。現在、同僚のためにいくつかのダークモード対応の(Ghost)テーマを作成中ですが、これらすべてが単一の Discourse インスタンスを共有することになります。ただ、それはもう少し先の話です。
残念ながら、ここで提案されていることがよく理解できません。現在、私のブログ内でダークモードのスタイルを利用したい要素は、それらの前に body.dark を付けて CSS を重複して定義しています。具体的には以下の通りです。
p {
color: #000;
}
body.dark p {
color: #FFF;
}
Discourse の iframe 内の要素を変更するために、その body.dark コードを使用することを提案されているのでしょうか?私は Discourse の「埋め込み CSS」フィールドに以下のコードを挿入してみましたが、残念ながら効果はありませんでした。
.FF2F-discourse p {
color: #000;
}
body.dark .FF2F-discourse p {
color: #FFF;
}
もしそうではない場合、トグル操作が iframe 内の特定のクラスをターゲットにして別の変更を引き起こすように、何らかの個別の JavaScript を記述することを提案されているのでしょうか?先ほどコメントした通り、外部のコードが iframe 内の CSS に影響を与えることはできないと思っていたため、混乱しています。しかし、私は HTML/CSS の素人ですので、あなたが私よりも詳しいことはもちろん、私が何かを誤解している可能性も十分にあります。
ヒントをいただきありがとうございます。
「いいね!」 7
pmusaraj
(Penar Musaraj)
4
はい、それが私の提案です。あなたのブログのスタイルシートは iframe に適用できませんが、JS を使って iframe の html または body 要素で dark クラスを切り替え、それに応じて Discourse 埋め込みスタイルシートを更新することができます。
「いいね!」 11
stromfeldt
(Allan Strømfeldt Christensen)
5
Discourse の埋め込み機能でライトモードとダークモードを切り替える方法について説明しているページを 2 つ見つけましたが、私の JavaScript を担当している方が、あなたが提案している方法が postMessage(私が探したページに記載されているもの)を使うのか、それとも別の手法なのかを確認したいと考えています。
以下は、postMessage を使ったウィンドウ間通信の実装方法について説明しているページです。
一方、このページは実際に postMessage を使って iframe 内の CSS を変更する方法、特にライトモードとダークモードの切り替えに特化したチュートリアルです。
https://cobwwweb.com/change-css-iframe
私のアプローチはこれで正しいでしょうか?
「いいね!」 8
pmusaraj
(Penar Musaraj)
6
申し訳ありません、ここへの返信を忘れていました。はい、postMessage があなたのユースケースに適用できると思います。
「いいね!」 11
こんにちは。
大変古いトピックを掘り起こしてしまい申し訳ありませんが、埋め込みコメントエンドポイントへのダークモードの自動切り替えを実装する予定はありますか?
「いいね!」 1
pmusaraj
(Penar Musaraj)
8
現在、この機能を追加する予定はありません。サイトでは、回避策として埋め込みスタイルシートにダークモードのスタイルを追加できます(または、上記で説明した postMessage テクニックを使用できます)。
「いいね!」 7
mikeguo
(Mike)
9
postMessage は message イベントを処理するために埋め込み iframe を必要とします。
イベントを処理するために iframe にコードを追加するにはどうすればよいですか?
「いいね!」 2
mikeguo
(Mike)
10
postMessage を使用して実装しました。コードとその実行ロジックは以下のとおりです。
コードブロック①は、埋め込まれたDiscourse iframe内でイベントリスナーを追加します。これにより、埋め込まれたDiscourseがロードされると、Discourse iframeを埋め込んでいる私のウェブサイトにメッセージが投稿されます。
私のウェブサイトが埋め込まれたDiscourseからのメッセージを受信すると、コードブロック②に示すように検証を行い、合格した場合は setIframeStyle 関数を呼び出して埋め込まれたDiscourseのスタイルを設定します。
コードブロック③に示す setIframeStyle 関数は、postMessage を呼び出すことによって、カラーモード(「dark」または「light」)をiframeに渡します。さらに、ダークモードが切り替わった後、この関数を呼び出すことで、埋め込まれたDiscourseを私のウェブサイトと同じカラーモードに保つことができます。
コードブロック④は、埋め込まれたDiscourseが私のウェブサイトから送信されたカラーモードメッセージを処理できるようにします。ここでは、bodyタグのクラス名を切り替えることでカラーモードを切り替えます。
さらに、コードブロック①と④は、以下のようにDiscourse管理ページに追加されます。
カスタムCSSクラスは以下のように追加する必要があります。
「いいね!」 12
「埋め込みCSS」を編集できない場合(公式テーマではないため)、どこを編集すればよいかご存知の方はいらっしゃいますか?
「いいね!」 2
manuel
(Manuel Kostka)
15
新しいコンポーネントを作成し、その埋め込みタブを使用しますか?
「いいね!」 3
pmusaraj
(Penar Musaraj)
16
上記の概要をありがとうございます @mikeguo、素晴らしい説明です!
また、これを実現するには最新の Discourse を使用する必要があることに注意してください。埋め込みヘッダー機能は数日前に追加されたばかりです。
「いいね!」 8
「編集:」それは私がしなければならなかったことです Structure of themes and theme components
それは間違っているようですか?
const handleMessageListener = (event:MessageEvent<any>)
「いいね!」 2
このコードを有効にできません (!) どなたか、親切に確認していただけますか?
誰もこれを有効にできず、ほとんどの人がライト強制を使用しているのを見かけますが、それは私たちの目に非常に悪いです 
「いいね!」 1
上記の方法で確認できましたが、スクリーンショットからコードを入力しなければならなかったのは残念です
以下に、少し更新したものを記載します。
手順
- コメントのiframeのレンダリングが完了し、メインのブラウザウィンドウにその旨を伝えるメッセージを送信します。
- ブラウザは、ダーク/ライトモードの設定を照会し、その値をiframeに返します。
- iframeはメッセージを受信し、ダーク/ライトモードの設定に基づいてdata-attribute、classなどを設定します。
コード
- iframeが読み込まれたら、親ウィンドウに通知を送信します。これは、Discourse の
管理者 -> カスタマイズ -> (テーマを選択) -> CSS/HTMLの編集 -> 埋め込みヘッダー に入力する必要があります。
window.addEventListener("load", (event) => {
window.parent.postMessage("iframe loaded", "*");
}, false);
- メインウィンドウでこの受信したトリガーを処理します。このコードはブログサイトに配置します。
const discourse_url = "https://your.discourse-instance.org";
// ここでテーマを決定し、テーマが何であるかをiframeに知らせるメッセージを送信します
// notifyFrameStyle を設定する方法については、以下を参照してください
const notifyIFrameOfTheme = () => {
const iframe = document.getElementById("discourse-embed-frame");
if (iframe && iframe.contentWindow) {
iframe.contentWindow.postMessage(
{
// ダークモードの設定をどのように保存しているかに応じて、以下の行をダークモード設定を取得するように変更してください
theme: document.documentElement.getAttribute("data-theme")
},
discourse_url
);
}
};
// "iframe loaded" メッセージを受信したときに setFrameStyle を呼び出します
const handleMessageListener = (event) => {
var origin = event.origin;
if ((origin === discourse_url) && (event.data == "iframe loaded")) {
notifyIFrameOfTheme();
}
};
- (1) の
script ブロックで、notifyFrameStyle によって送信されたテーマメッセージのリスナーを追加します。
window.addEventListener("message", (event) => {
const payload = event.data;
if (payload.theme) {
// テーマ設定で何かを行う。私はiframeの `html` に `data-theme` 属性を設定しましたが、
// class属性などを設定したい場合もあります
document.documentElement.setAttribute("data-theme", payload.theme);
}
}, false);
スタイリング
管理者 -> カスタマイズ -> (テーマを選択) -> CSS/HTMLの編集 -> 埋め込みCSS で、各モードのCSSを提供できるようになります。例えば、Discourseのスタイリング変数をオーバーライドできます。
html[data-theme="dark"] {
--primary: #ced6dd;
--primary-low: #48566b;
--secondary: #14181e;
--tertiary: #2b7e8d;
}
お役に立てれば幸いです!
「いいね!」 6
n1bff
20
上記のコピー&ペースト可能なコードには、埋め込みウィンドウでのイベントリスナーの追加が欠けています。
window.addEventListener("message", handleMessageListener);
注意点:これには特別なCORS設定は必要ありません。
指摘ありがとうございます!上記の投稿はもう編集できませんが、window.addEventListener は (2) のコードスニペットの下部に追加します。
実際の例をご覧ください。
「いいね!」 6