JS solution for hiding an Obsidian Publish Sidebar
9/26/2022
This snippet should be added to your publish.js
.
Info
If this is the first part of your
publish.js
, I recommend uncommenting the commented out(function() {
and})();
lines so that you isolate the scope of this function
JS Snippet for publish.js
//(function () {
function maybeSetFocusMode() {
const noteContainer = document.getElementsByClassName("markdown-rendered")[0];
const hideSidebarClassname = "focus";
const rightSidebarClassname = "site-body-right-column";
const rightSidebar = document.getElementsByClassName(
rightSidebarClassname
)[0];
// if you want to also do the left sidebar, uncomment all of the commented out code that starts with leftSidebar
const leftSidebarClassname = "site-body-left-column";
const leftSidebar = document.getElementsByClassName(leftSidebarClassname)[0];
if (noteContainer.className.includes(hideSidebarClassname)) {
rightSidebar.style = "visibility: hidden; flex: 0; width: 0;";
leftSidebar.style = "visibility: hidden; flex: 0; width: 0;";
} else {
rightSidebar.style = "";
leftSidebar.style = "";
}
}
function initializeRendererObserver() {
// run on page transition
new MutationObserver(maybeSetFocusMode).observe(
document.getElementsByClassName("markdown-rendered")[0],
{
attributes: true,
}
);
// run on page render
maybeSetFocusMode();
}
initializeRendererObserver();
//})();
This sets up a MutationObserver
that observes the element with the markdown-renderer
class of your site. Anytime that element changes (ie, when you visit a different page), it runs the callback function (the first argument passed to MutationObserver
).
The function...
- gets the
markdown-renderer
again so that it has a non-stale instance to check from - ❗
hideSidebarClassname
should be whatever your classname needs to be based on thecssclass
property in your metadata of the filei - gets the sidebar by classname
- if the
cssclass
you want to use to hide the sidebar is present, it will hide the sidebar - if it's not present, it will make it visible
An alternative based on frontmatter
It's possible you want to use frontmatter
instead of the cssclass
to decide whether to do something in this observer. 1
Here's an alternative script that you can use to check the .frontmatter
element for the presence of a field (in this example, I'll use mode: focus
):
//(function () {
function maybeSetFocusMode() {
const noteContainer = document.getElementsByClassName("markdown-rendered")[0];
const rightSidebarClassname = "site-body-right-column";
const rightSidebar = document.getElementsByClassName(
rightSidebarClassname
)[0];
// if you want to also do the left sidebar, uncomment all of the commented out code that starts with leftSidebar
const leftSidebarClassname = "site-body-left-column";
const leftSidebar = document.getElementsByClassName(leftSidebarClassname)[0];
if (meetsCriteria()) {
rightSidebar.style = "visibility: hidden; flex: 0; width: 0;";
leftSidebar.style = "visibility: hidden; flex: 0; width: 0;";
} else {
rightSidebar.style = "";
leftSidebar.style = "";
}
}
function meetsCriteria() {
var yamlContainer = document.querySelector(".frontmatter.language-yaml");
if (!yamlContainer) return false;
return yamlContainer.textContent.includes("mode: focus");
}
function initializeRendererObserver() {
// run on page transition
new MutationObserver(maybeSetFocusMode).observe(
document.getElementsByClassName("markdown-rendered")[0],
{
childList: true,
subtree: true,
}
);
// run on page render
maybeSetFocusMode();
}
initializeRendererObserver();
//})();
Some important distinctions about what changed...
- In the
MutationObserver
, instead of only running onattributes
change, we need to check an element that's a child of themarkdown-rendered
element, so we setchildList
andsubtree
totrue
. - Instead of checking that the
className
includes something, we need to get the.frontmatter
element and if it exists, check if it containsmode: focus
(which we verify by running themeetsCriteria
function), then we set the styles.
A loom walking through how it works...
Final Notes
- This solution is not durable. What I mean by that is that if either of the two classes we use to select the renderer or the sidebar change, they'll need to be updated accordingly.
Footnotes
-
(thanks to Jenna of polyrain.dev for the tip on finding the
.frontmatter
, I had no idea that element was present!) ↩