I would like to make my navbar dynamic so that when I am on that selected page the class active is added.
I know I can do as bellow, however, is there a simpler way even with Javascript so that I don't need to copy and paste a bunch of times?
(maybe with a different class?)
$a='home';
<nav>
home
</nav>
this is a JavaScript salutation:
<!doctype html>
<html>
<head>
<style>
.active {
color: red;
}
</style>
</head>
<body>
Curent Page
Difrent Page
Difrent Page
<script>
var navClass = document.getElementsByClassName("nav-item");
var path = window.location.href;
for (i = 0; i < navClass.length; i++) {
if (path.includes(navClass[i].href)) {
navClass[i].classList.add("active");
}
}
</script>
</body>
</html>
it takes the content of the href and sees if it is included in curent url if yes it adds a class
Related
I would like the Google Sheets sidebar to open with a color set in cell Sheet1:A1. My current code works (I suspect there may be a more efficient way to do this), but the CSS steps through each theme in root until it lands on the correct theme.
For example, if A1 is set to 'Orange', calling the sidebar will load with the body first as 'Default' and then switch to 'Orange'. Is there a way to load the correct root theme on the initial page load instead of stepping through the themes in root?
Google Apps Script
function onOpen(e) {
SpreadsheetApp.getUi()
.createMenu("Sidebar")
.addItem("Show sidebar", "showSidebar")
.addToUi();
}
function showSidebar() {
var htmlWidget = HtmlService.createTemplateFromFile('Test').evaluate()
.setTitle("Theme Test");
SpreadsheetApp.getUi().showSidebar(htmlWidget);
}
function getColorTheme() {
colorTheme = SpreadsheetApp.getActive().getRange("Sheet1!A1").getDisplayValue();
return colorTheme;
}
HTML for Sidebar
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<style>
:root,
:root.Default {
--bg-color: #45818e;
}
:root.Orange {
--bg-color: #e69138;
}
body {
background-color: var(--bg-color);
}
</style>
<script>
function setTheme(colorTheme) {
document.documentElement.className = colorTheme;
}
</script>
</head>
<body>
<p>Hello world</p>
<script>
google.script.run.withSuccessHandler(setTheme).getColorTheme();
</script>
</body>
</html>
From your situation, how about the following patterns?
Pattern 1:
In this pattern, HTML is modified using Google Apps Script and the modified HTML is used with HtmlService.createHtmlOutput().
Google Apps Script side:
function showSidebar() {
var colorTheme = SpreadsheetApp.getActive().getRange("Sheet1!A1").getDisplayValue();
var html = HtmlService.createHtmlOutputFromFile('Test').getContent().replace("{{colorTheme}}", colorTheme);
var htmlWidget = HtmlService.createHtmlOutput(html).setTitle("Theme Test");
SpreadsheetApp.getUi().showSidebar(htmlWidget);
}
HTML side:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<style>
:root,
:root.Default {
--bg-color: #45818e;
}
:root.Orange {
--bg-color: #e69138;
}
body {
background-color: var(--bg-color);
}
</style>
<script>
document.documentElement.className = "{{colorTheme}}";
</script>
</head>
<body>
<p>Hello world</p>
</body>
</html>
Pattern 2:
In this pattern, HTML is modified using HTMl template and the modified HTML is used with HtmlService.createHtmlOutput().
Google Apps Script side:
function ashowSidebar() {
var colorTheme = SpreadsheetApp.getActive().getRange("Sheet1!A1").getDisplayValue();
var htmlWidget = HtmlService.createTemplateFromFile('Test')
htmlWidget.colorTheme = colorTheme;
SpreadsheetApp.getUi().showSidebar(htmlWidget.evaluate().setTitle("Theme Test"));
}
HTML side:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<style>
:root,
:root.Default {
--bg-color: #45818e;
}
:root.Orange {
--bg-color: #e69138;
}
body {
background-color: var(--bg-color);
}
</style>
<script>
document.documentElement.className = "<?= colorTheme ?>";
</script>
</head>
<body>
<p>Hello world</p>
</body>
</html>
Note:
From the recent benchmark of the HTML template, it seems that in the current stage, the process cost of evaluate() is a bit high. Ref So, I proposed the above 2 patterns with and without an HTML template.
In this case, <html class="{{colorTheme}}"> and <html class="<?= colorTheme ?>"> might be able to be used instead of Javascript. But, I'm not sure about your actual situation. So, in this answer, Javascript is used as a sample modification.
References:
createHtmlOutput(html)
HTML Service: Templated HTML
createTemplateFromFile(filename)
first of all: I‘m not a coder!
I want to inject a dynamic h1 based on page title on a webpage.
Example: <title>Garden</title>
Now I need this as H1 class - I want to include this H1 after a given div class <div class="teaser"></div>
It is may totally simple and I already read some stuff but i don‘t get it…
Fairly trivial
window.addEventListener('DOMContentLoaded', function() {
const h1 = document.createElement('h1')
h1.innerHTML = document.title;
document.querySelector(".teaser").insertAdjacentElement("afterend", h1)
})
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Garden</title>
</head>
<body>
<div class="teaser">Teaser</div>
</body>
</html>
I want to change the css properties of many html objects (but in this example I only took body to simplify. My goal is to display dark mode if the current mode is light, or display light mode if current mode is dark.
My javascript function does not work.
debug.html:
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="debug.css">
<script src="darkmode.js"></script>
</head>
<body id="bodyElem" class="my-body light-mode">
<h1>Settings</h1>
<p>Dark mode:</p>
<button type="button" onclick="invertMode()">click</button>
</body>
</html>
debug.css:
.my-body.light-mode{
background-color: yellow;
}
.my-body.dark-mode{
background-color: black;
}
darkmode.js:
function invertMode() {
var body = document.getElementById("bodyElem");
var currentClass = body.className;
body.className = currentClass == "dark-mode" ? "light-mode" : "dark-mode";
}
You will need to add an ID for the <body> tag to be able to find it using your code.
<body id="bodyElem" class="light-mode">
and access it using:
var body = document.getElementById("bodyElem");
If you need to access mutiple elements, you can use their CSS class name like:
document.getElementsByClassName("CLASSNAMEHERE");
then loop them all to apply the changes you need.
you will be using .classList.remove("CLASSNAME") to remove single class and .classList.add("CLASSNAME") to add single class to DOM element
Here is a complete sample fiddle:
https://jsfiddle.net/j3o8Lt5k/1/
If you click the button, it should have showed, but it doesn't.
Is any wrong here?
I have written many JavaScript files in this way, and tried many ways like changing the position of JavaScript code anywhere. But all the files I wrote don't work
Thanks in advance!
An instance :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Debug</title>
</head>
<style>
.debug {
display : none;
}
</style>
<body>
<div class = "debug">
<p>Welcome!</p>
</div>
<button class = "show" onclick = "JavaScript : show();">Show</button>
<script type = "text/JavaScript">
function show() {
document.querySelector("debug").style.display = "flex";
}
</script>
</body>
</html>
Thanks to all of you!
About .querySelector()
The Document method querySelector() returns the first Element within the document that matches the specified selector. [...] The selector is a CSS selector string.
- MDN web docs
You should, therefore, put in your code:
document.querySelector(".debug")
You can also select HTML elements by their tags, for example, you want to select the first div:
document.querySelector("div")
document.querySelector("div").style.color = "lightgreen"
<div>Hello World</div>
Imagine you had your own HTML tag: <hello>, then you can select all hello elements with:
document.querySelector("hello")
document.querySelector("hello").style.color = "lightblue"
<hello>Hello World</hello>
Side note on inline eventListeners
Also in HTML for inline event listener instead of:
<button class = "show" onclick = "JavaScript : show();">Show</button>
you can simply write:
<button class = "show" onclick = "show();">Show</button>
It is recommended to use JavaScript to initiate these eventListeners instead of having them inline inside your HTML markup. Use the .addEventListener() method:
document.querySelector(".show").addEventListener('click', show)
↑ ↑
event function
type
Back to your code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Debug</title>
</head>
<style>
.debug {
display : none;
}
</style>
<body>
<div class = "debug">
<p>Welcome!</p>
</div>
<button class ="show">Show</button>
<script type = "text/JavaScript">
document.querySelector(".show").addEventListener("click", show)
function show() {
document.querySelector(".debug").style.display = "flex";
}
</script>
</body>
</html>
Last thing
Also it's better to keep HTML, JavaScript and CSS all in separate files, for instance:
- index.html
- style.css
- script.js
And call the CSS and JavaScript files in your HTML file with the link (preferably inside <head>) and script (at the bottom of <body>) tags:
<link rel="stylesheet" type="text/css" href="style.css">
And
<script src="script.js"></script>
For class selector you need to add a dot (.) e.g. .debug
Also, in HTML, you can simply have onclick as onclick="show();"
function show() {
document.querySelector(".debug").style.display = "flex";
}
.debug {
display: none;
}
<div class="debug">
<p>Welcome!</p>
</div>
<button class="show" onclick="show();">Show</button>
You were not passing class to querySelector. Set ".debug" instead of "debug".
Below is working code:
function show() {
document.querySelector(".debug").style.display = "flex";
}
.debug {
display: none;
}
<div class="debug">
<p>Welcome!</p>
</div>
<button class="show" onclick="JavaScript : show();">Show</button>
queryselectors requires . and # for class and ID selector:
querySelector(".debug")
the goal here is onclick of 1.gif, everything with .panel1 class disappears(style.display.none), and everything with a .panel2 class becomes visable (style.display.inline)
I'm new at this..so I think its just a syntax issue with ' ' or maybe " "
<!DOCTYPE html>
<html>
<head>
<title>main</title>
<meta charset="utf-8">
<style type="text/css">
.panel1 {display:inline;}
.panel2 {display:none;}
</style>
<script type="text/javascript">
function panelTransition(panelOut,panelIn)
{
document.getElementByClass(panelIn).style.display="inline";
document.getElementByClass(panelOut).style.display="none";
}
</script>
</head>
<body>
<img class="panel1" src=1.gif onclick="panelTransition(panel1,panel2)" />
<img class="panel2" src=2.gif />
</body>
</html>
There is no getElementByClass. It's getElementsByClassName, and it returns an array of items, so you'll need to modify your code to loop through them.
function panelTransition(panelOut, panelIn) {
var inPanels = document.getElementsByClassName(panelIn);
for (var i = 0; i < inPanels.length; i++) {
inPanels[i].style.display = 'inline';
}
var outPanels = document.getElementsByClassName(panelOut);
for (var i = 0; i < outPanels.length; i++) {
outPanels[i].style.display = 'none';
}
}
If you were using a JavaScript library, like jQuery, this would be much easier to do. Also, as has been mentioned, you need quotes around your arguments to panelTransition.
<img class="panel1" src=1.gif onclick="panelTransition('panel1', 'panel2')" />
<img class="panel2" src=2.gif />
<img class="panel1" src=1.gif onclick="panelTransition('panel1','panel2')" />
I think you need quotes there
<html>
<head>
<title>main</title>
<meta charset="utf-8">
<style type="text/css">
.panel1 {display:inline;}
.panel2 {display:none;}
</style>
<script type="text/javascript">
function panelTransition(panelOut,panelIn)
{
// panelIn gets turned on
setDisplay(panelIn,"inline");
// panelOut gets turned off
setDisplay(panelOut,"none");
}
function setDisplay(className,displayState)
{
// retrieve a list of all the matching elements
var list = document.getElementsByClassName(className);
// step through the list
for(i=0; i<list.length; i++) {
// for each element, set the display property
list[i].style.display = displayState;
}
}
</script>
</head>
<body>
<img class="panel1" src="1.gif" onclick="panelTransition('panel1','panel2')" />
<img class="panel2" src="2.gif" onclick="panelTransition('panel2','panel1')" />
</body>
</html>
Or you can accomplish the same in jQuery
// fires when the page is up and running
$(document).ready(function(){
// find all the panel1 elements,
// attach an on click handler
$(".panel1").bind("click", function(){
// find all the panel1 elements
// set their css display property to inline
$(".panel1").css("display","inline");
// find all the panel2 elements
// set their css display property to none
$(".panel2").css("display","none");
});
$(".panel2").bind("click", function(){
$(".panel2").css("display","inline");
$(".panel1").css("display","none");
});
});
You can learn all about jQuery here : http://www.jquery.com/
You'll only be able to get your code to run once, as soon as you click a panel1 image all of the panel2 images will disappear, you won't be able to click them back on ever again.