JS will not change the navigation display property from none to flex - javascript

JS will not change the nav-hidden display property from none to flex. I tried with !important, that seems to work in some cases, but I would like to know why this does not work, so that I can understand this better.
When I press the button there is a new class assigned to the element, but the property stays as none.
What I was trying to do: have nav-hidden only appear when I click on button over the whole screen when the screen is smaller than 700px, and have nav-line in line with the logo inside when screen is wider than 700px.
function myFunction() {
var fullnavigation = document.getElementById("nav-hidden");
fullnavigation.classList.toggle("open-nav");
}
body{
margin: 0;
font-family: 'Roboto', sans-serif;
}
header{
background-color: #009933;
width:100%;
position: fixed;
top: 0;
left: 0;
right: 0;
display: flex;
justify-content: space-evenly;
align-items: center;
}
.logo img{
display: block;
height: 4em;
}
#media screen and (max-width:700px){
.nav-line{
display: none;
}
.open-nav{
display: flex;
}
.nav-hidden{
display: none;
position: fixed;
top: 0;
width: 100%;
height: 100%;
background-color: #009933;
flex-direction: column;
}
.nav-button{
display: block;
color: #ffffff;
background-color: transparent;
padding: 0px;
border: 0px;
cursor: pointer;
font-size: 4em;
z-index: 9999;
}
}
<!DOCTYPE html>
<html lang="sl">
<head>
<title></title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="slike\favicon\favicon.png" type="image/gif" size="128x128">
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
<script src="js\index.js"></script>
<link rel="stylesheet" href="css\index.css">
</head>
<body>
<header>
<div class="logo"><img src="" alt="logo"></div>
<button id="nav-button" onclick="myFunction()">☰</button>
<nav id="nav-line" class="nav-line">
<div class="nav-text">DOMOV</div>
<div class="nav-text">O NAS</div>
<div class="nav-text">KONTAKT</div>
<div class="nav-text">POVPRAŠEVANJE</div>
</nav>
</header>
<nav id="nav-hidden" class="nav-hidden">
<div class="nav-text">DOMOV</div>
<div class="nav-text">O NAS</div>
<div class="nav-text">KONTAKT</div>
<div class="nav-text">POVPRAŠEVANJE</div>
</nav>
</body>
</html>

As CSS reads your code successively, .open-nav class has been intercepted by the next one .nav-hidden. Problem is not in your JS code and if you look to this JSFiddle it works and js switches your class well. Just put .open-nav after .nav-hidden
#media screen and (max-width:700px){
.nav-line{
display: none;
}
.nav-hidden{
display: none;
position: fixed;
top: 0;
width: 100%;
height: 100%;
background-color: #009933;
flex-direction: column;
}
.open-nav{
display: flex;
}
}

.classList.toggle('className') : When only one argument is present: Toggle the class value; i.e., if the class exists then remove it and return false, if not, then add it and return true.
So your JS will add the "open-nav" class but won't remove the "hidden-nav". I think the error might come from that.
Tell me if you need more help after that.
Source:
https://developer.mozilla.org/en-US/docs/Web/API/Element/classList

Related

Uncaught TypeError: marked is not a function at HTMLTextAreaElement.<anonymous>

I tried to make this simple notes app, just for learning javascript. Then I got error when I tried to hit the "edit" button on this program. It was saying that marked is not a function.
My code is here:
HTML
<html>
<head>
<title>Notes App</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.2/css/all.min.css">
<link rel="stylesheet" href="style.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/4.2.12/marked.min.js"></script>
</head>
<body>
<div class="notes">
<div class="tools">
<button class="edit"><i class="fas fa-edit"></i></button>
<button class="delete"><i class="fas fa-trash-alt"></i></button>
</div>
<div class="main hidden">
</div>
<textarea></textarea>
</div>
<script src="script.js"></script>
</body>
</html>
CSS
#import url('https://fonts.googleapis.com/css2?family=Ibarra+Real+Nova&display=swap');
* {
box-sizing: border-box;
}
body {
display: flex;
flex-wrap: wrap;
background-color: #7BDAF3;
margin: 0;
font-family: 'Ibarra Real Nova', serif;
}
.notes {
background-color: #fff;
width: 400;
height: 400;
margin: 20px;
}
.notes .tools {
background-color: #9ec862;
display: flex;
justify-content: flex-end;
padding: 0.5rem;
}
.notes .tools button {
background-color: transparent;
border: none;
color: #fff;
font-size: 1.5rem;
margin-left: 0.5rem;
}
.notes .main {
height: 100%;
width: 100%;
}
.notes textarea {
outline: none;
font-family: inherit;
border: none;
height: 100%;
width: 100%;
}
.notes .hidden {
display: none;
}
Javascript
const notesEl = document.querySelector('.notes');
const editBtn = document.querySelector('.edit');
const deleteBtn = document.querySelector('.delete');
const main = notesEl.querySelector('.main');
const textArea = notesEl.querySelector('textarea');
editBtn.addEventListener('click', () => {
main.classList.toggle('hidden');
textArea.classList.toggle('hidden');
});
textArea.addEventListener("input", (e) => {
const { value } = e.target;
main.innerHTML = marked(value);
});
It supposed to show the mark when I hit the edit button. But, even without giving any input of markdown, the result is nothing. And it showed an error on the console log.
I found the problem. So that there is a bug in this version of mark, then I change the marked version to 3.0.7. And its all works fine, cause its fixed in this version.
So change the way you import it in html code:
from:
https://cdnjs.cloudflare.com/ajax/libs/marked/4.2.12/marked.min.js
to:
https://cdn.jsdelivr.net/npm/marked#3.0.7/marked.min.js

How to align html elements horizontally when they have different parents

I have a basic html document with a sticky header and footer. I also have a div below the header that sticks to the header because it will eventually contain some tabs above a form. I have tried to align the form below this vertically but they don't line up. The problem is the tab div does not have a scrollbar but the form does. This means the width of the form is different to the width of the tabs. I tried to set them to 70% of the width and center but, because of the scrollbar they don't line up. I've tried some javascript to get the width of the scrollbar and then add this to the current right margin but it doesn't work. You will see the form is not as wide as the tabs div. I have spent hours on this.
Also, I tried adding a margin-bottom to the form but no margin appears below the border.
$(document).ready(function () {
setFormsWidth();
});
function setFormsWidth() {
let scrollbox = document.createElement('div');
// Make box scrollable
scrollbox.style.overflow = 'scroll';
// Append box to document
document.body.appendChild(scrollbox);
// Measure inner width of box
scrollBarWidth = scrollbox.offsetWidth - scrollbox.clientWidth;
// Remove box
document.body.removeChild(scrollbox);
// Get current width of right margin, which should be 30% of the
// width of the form-panel parent (the content class).
var formPanel = document.getElementById("main-form");
// Get the current right margin and remove the px at end of number
var style = window.getComputedStyle(formPanel);
var marginRightString = style.getPropertyValue('margin-right');
var marginRight = marginRightString.slice(0,-2);
// now addthe scrollBarWidth to the right margin
var newMargin = marginRight + scrollBarWidth;
formPanel.style.marginRight = newMargin + "px";
}
html, body {
height: 100%;
margin: 0;
overflow:hidden;
}
.wrapper {
height: 100%;
display: flex;
flex-direction: column;
}
.header, .footer {
background: silver;
}
.page {
flex: 1;
overflow: auto;
background: pink;
}
.content {
background-color: green;;
}
.tabs {
width: 70%;
height: 50px;
background-color: aqua;
margin: 0 auto;
border-bottom: solid #FE6D73 7px;
}
.form-panel {
width: 70%;
height: 1000px;
background-color: #FFF;
margin: 0 auto;
overflow-y: auto;
border-bottom: solid #FE6D73 7px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css"/>
</head>
<body>
<div class="wrapper">
<div class="header">Header</div>
<div class="tabs">
THIS IS TAB
</div>
<div class="page" id="calculator">
<div style="height:1000px;">
<div class="content">
<form class="form-panel" id="main-form">THIS IS FORM</form>
</div>
</div>
</div>
<div class="footer">Footer</div>
</div>
<script type="text/javascript" src="script.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</body>
</html>
I suggest to show the scrollbar besides .form-panel element but not .page div, so it will not affect centering .form-panel element.
Here is how to change the css.
Set height to 100% for all elements between .page and .form-panel elements, including .form-panel itself, so that scrollbar for .page will not be shown
Set box-sizing: border-box; for .form-panel, so that the border is drawn inside .form-panel
move .footer outside .page element
If you would like to set a specific height for .form-panel, you can create a div inside it and set its height like below:
html, body {
height: 100%;
margin: 0;
overflow:hidden;
}
.wrapper {
height: 100%;
display: flex;
flex-direction: column;
}
.header, .footer {
background: silver;
}
.page {
flex: 1;
overflow: auto;
background: pink;
}
.content {
background-color: green;
height: 100%;
}
.tabs {
width: 70%;
height: 50px;
background-color: aqua;
margin: 0 auto;
border-bottom: solid #FE6D73 7px;
}
.form-panel {
width: 70%;
height: 100%;
background-color: #FFF;
margin: 0 auto;
overflow-y: auto;
border-bottom: solid #FE6D73 7px;
padding-bottom: 7px;
box-sizing: border-box;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css"/>
</head>
<body>
<div class="wrapper">
<div class="header">Header</div>
<div class="tabs">
THIS IS TAB
</div>
<div class="page" id="calculator">
<div style="height:100%;">
<div class="content">
<form class="form-panel" id="main-form">
<div style="height:1000px">
THIS IS FORM
</div>
</form>
</div>
</div>
</div>
<div class="footer">Footer</div>
</div>
</body>
</html>

Codepen code doesn't work on my local files -- code provided [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I recently got help on the following question in which a codepen was provided:
https://codepen.io/diego-fortes/pen/GRvRPzX
Can anyone get this code to run on a local computer as it does in the codepen? If so, can you provide that code? (I believe the jquery 3.6.0 file which is included in the same folder may not be linking properly --> my bar hover is stuck on bar 1 and only cursor changes when I hover over the other bars)
Any help would be super useful! Thanks
Here's the HTML, CSS, and JS that I used on my local computer:
JS:
<head>
<script src="jquery-3.6.0.min.js"></script>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css">
<script type="text/javascript">
const $navbars = document.querySelectorAll(`.navbar-item`);
function removeSelected() {
const $selected = document.querySelectorAll(`.navbar-item--selected, .slider-item--visible`);
if (!$selected) {
return;
}
for (let each of $selected) {
each.classList.remove("navbar-item--selected");
each.classList.remove("slider-item--visible");
}
}
for (let each of $navbars) {
each.addEventListener("mouseover", function () {
removeSelected();
const position = each.getAttribute("data-position");
const $item = document.querySelector(`.slider .slider-item:nth-child(${position})`)
each.classList.add("navbar-item--selected")
$item.classList.add("slider-item--visible");
});
}
</script>
</head>
HTML:
<body>
<div class="wrapper">
<div class="slider">
<div class="slider-item slider-item--visible">
hello item 1
</div>
<div class="slider-item">
hello item 2
</div>
<div class="slider-item">
hello item 3
</div>
</div>
<nav class="navbar">
<span class="navbar-item navbar-item--selected" data-position="1"></span>
<span class="navbar-item" data-position="2"></span>
<span class="navbar-item" data-position="3"></span>
</nav>
</div>
</body>
CSS:
.wrapper {
max-width: 1000px;
width: 100%;
margin: 0 auto;
display: block;
}
/* Slider */
.slider {
max-width: 100%;
width: 100%;
}
.slider-item {
display: none;
}
.slider-item--visible {
display: block;
}
/* Navbar */
.navbar {
max-width: 100%;
display: flex;
align-items: flex-end;
height: 8px;
}
.navbar-item {
max-width: 33.3%;
width: 100%;
display: block;
height: 5px;
cursor: pointer;
opacity: .5;
transition: all .2s;
}
.navbar-item--selected {
height:10px;
opacity: 1;
}
/* Meaningless styles (colors) */
.navbar-item:nth-child(1){
background: salmon;
}
.navbar-item:nth-child(2) {
background: lightblue;
}
.navbar-item:nth-child(3){
background: #19be29;
}
Your code doesn't work because your Javascript is above HTML.
In your case, document.querySelector cannot select anything.
Please move the JavaScript code to bottom of HTML.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.wrapper{
max-width: 1000px;
width: 100%;
margin: 0 auto;
display: block;
}
/* Slider */
.slider{
max-width: 100%;
width: 100%;
}
.slider-item{
display: none;
}
.slider-item--visible{
display: block;
}
/* Navbar */
.navbar{
max-width: 100%;
display: flex;
align-items: flex-end;
height: 8px;
}
.navbar-item{
max-width: 33.3%;
width: 100%;
display: block;
height: 5px;
cursor: pointer;
opacity: .5;
transition: all .2s;
}
.navbar-item--selected{
height: 8px;
opacity: 1;
}
/* Meaningless styles (colors) */
.navbar-item:nth-child(1){
background: salmon;
}
.navbar-item:nth-child(2){
background: lightblue;
}
.navbar-item:nth-child(3){
background: #19be29;
}
</style>
</head>
<body>
<div class="wrapper">
<div class="slider">
<div class="slider-item slider-item--visible">
hello item 1
</div>
<div class="slider-item">
hello item 2
</div>
<div class="slider-item">
hello item 3
</div>
</div>
<nav class="navbar">
<span class="navbar-item navbar-item--selected" data-position="1"></span>
<span class="navbar-item" data-position="2"></span>
<span class="navbar-item" data-position="3"></span>
</nav>
</div>
<script>
const $navbars = document.querySelectorAll(`.navbar-item`);
function removeSelected(){
const $selected = document.querySelectorAll(`.navbar-item--selected, .slider-item--visible`);
if (!$selected){
return;
}
for (let each of $selected){
each.classList.remove("navbar-item--selected");
each.classList.remove("slider-item--visible");
}
}
for (let each of $navbars){
each.addEventListener("mouseover", function(){
removeSelected();
const position = each.getAttribute("data-position");
const $item = document.querySelector(`.slider .slider-item:nth-child(${position})`)
each.classList.add("navbar-item--selected")
$item.classList.add("slider-item--visible");
});
}
</script>
</body>
</html>

How to create a fixed sidebar using ReactJS? The sidebar should collapse in smaller screens

i have two columns on a page.i want to create a sidebar which is fixed on the left side so it shouldn't be scrolled if the content contained in the main body is being scrolled. in smaller screens, the sidebar should collapseable.
after looking into various sources, it seems that i need to use jquery but as much as possible, i want to maximize the functionalities of ReactJs. besides, some sources also say that it's not a good idea to mix Jquery with ReactJs.
the sidebar is now fixed but my problem now is i can't seem to collapse it in smaller screens. it's just fixed in there and it disappears in smaller screen. my goal is to create a button in smaller screens that when clicked should show the sidebar
This is not my whole code. i'm just posting the relevant snippets:
[.js]
constructor(props) {
this.state = {
collapsed: true
};
this.toggleNavbar = this.toggleNavbar.bind(this);
}
toggleNavbar() {
this.setState({
collapsed: !this.state.collapsed
});
}
render() {
return (
<div id="sidebar" >
<Navbar color="faded" light className="sticky-top" data-spy="affix">
<NavbarToggler onClick={this.toggleNavbar} className="main-toggler"/>
<Collapse isOpen={this.state.collapsed} navbar>
<Nav navbar>
<Container>
<div>
<NavbarBrand>Theories</NavbarBrand>
<NavbarToggler onClick={this.toggleTheories} />
<Collapse isOpen={!this.state.theoriesCollapsed} navbar>
<NavItem>
</NavItem>
</Collapse>
</div>
</Container>
</Nav>
</Collapse>
</Navbar>
</div>
);
}
[.css]
#media screen and (max-width: 768px)) {
.main-toggler {
display: block;
}
}
#media screen and (max-width: 768px){
#sidebar {
display: none;
}
}
#sidebar {
background: lightgrey;
height:100%;
position: fixed;
z-index: 1;
overflow-y: auto;
will-change: transform;
backface-visibility: hidden;
}
.main-toggler {
float: left !important;
}
.sticky-top {
top: 1rem;
padding-top: 2rem;
}
#sidebar .navbar{
display: inherit;
}
Based on my comment I've built a very basic example for you.
It's far from beautiful or perfect, but it should get the point across.
No JS needed. Just plain HTML + CSS.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Sidebar Test</title>
<style>
html,
body {
margin: 0;
padding: 0;
}
body {
display: flex;
flex-flow: row;
}
aside {
width: 20vw;
height: 100vh;
}
main {
width: 100%;
height: 100vh;
background: cornflowerblue;
color: white;
}
#sidebar-toggle {
display: none;
}
.toggle-btn {
display: none;
width: 4em;
height: 2em;
position: relative;
cursor: pointer;
background: yellow;
padding: 2px;
}
#media(max-width:1200px) {
.toggle-btn {
display: block;
}
aside {
width: 0vw;
transition: width 0.25s ease-out;
}
#sidebar-toggle:checked+aside {
width: 20vw;
}
}
</style>
</head>
<body>
<label class="toggle-btn" for="sidebar-toggle">click me</label>
<input id="sidebar-toggle" type="checkbox" />
<aside>
<div>
<ul>
<li>Item-1</li>
<li>Item-2</li>
<li>Item-3</li>
</ul>
</div>
</aside>
<main>
<div style="padding: 20px;margin:0 auto;text-align: center;font-size:2em;">Some content</div>
</main>
</body>
</html>

Responsive 3 column page with sidebars click to hide

I am trying to create a similar design/approach to this:
https://help.sap.com/viewer/8092b085a68941f6aaa6708685a62b0d/4.2.8/en-US/acc57dbca1ab4a5bac2a352ce8cc52d8.html?q=Amazon
Notice that, when the sidebar << and >> icons are clicked, those sidebars slide out and the topic/content in the center expands to take the freed up space.
They're using AngularJS but I have to do this using html. I can use jquery, vanilla js, and if it makes sense I can try bootstrap (though I'm obviously not very experienced and want to stick to just html and jquery if possible).
Here is what I've come up with so far. Please excuse the awful color scheme - it's just to delineate the divs:
$("#right-sidebar-slider").click(function() {
$('#right-sidebar-content').hide('slide', {
direction: 'right'
}, 300);
$("#topic-container").animate({
width: "75%"
}, {
duration: 600,
specialEasing: {
width: 'linear'
}
});
});
$("#left-sidebar-slider").click(function() {
$('#left-sidebar-content').hide('slide', {
direction: 'left'
}, 300);
$("#topic-container").animate({
width: "77%"
}, {
duration: 600,
specialEasing: {
width: 'linear'
}
});
});
#left-sidebar-slider {
float: left;
width: 3%;
padding-top: 20px;
background-color: green;
min-height: 600px;
}
#left-sidebar-content {
float: left;
width: 19%;
padding-top: 20px;
background-color: pink;
min-height: 600px;
}
#topic-container {
float: left;
min-width: 58%;
min-height: 600px;
padding-top: 20px;
background-color: red;
}
#right-sidebar-slider {
float: left;
width: 3%;
padding-top: 20px;
background-color: green;
min-height: 600px;
}
#right-sidebar-content {
float: left;
width: 17%;
padding-top: 20px;
background-color: pink;
min-height: 600px;
}
.header {
display: flex;
align-items: center;
}
.header .logo {
background: url("logo-onlinehelp.png") no-repeat;
width: 60%;
height: 25px;
border: 1px solid green;
margin-left: 15px;
}
.header .search-input {
border: 2px solid blue;
width: 40%;
margin-left: 25px;
}
footer {
clear: left;
border-top: 1px solid #cccccc;
width: 100%;
height: 40px;
bottom: 0;
position: relative;
background-color: gray;
}
<!doctype html>
<html lang="en">
<head>
<title></title>
<link href="favicon.ico" rel="icon" type="image/x-icon" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="vertex.js"></script>
<script src="dhtml_toc.js"></script>
<script src="dhtml_search.js"></script>
<link rel="stylesheet" type="text/css" href="stylesheet_vertex.css">
<script type="text/javascript" src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<!-- need for slider effect -->
</head>
<body>
<div class="header" style="height: 70px; background-color: gray">
<div class="logo">
</div>
<div class="search-input">
<form action="#">
<input type="text" name="search-input" value="Search available topics..." size="70">
<input type="submit" value="Submit">
</form>
</div>
</div>
<div id="left-sidebar-content">
Table of Contents...
</div>
<div id="left-sidebar-slider">
<<
</div>
<div id="topic-container">
Topic here...
</div>
<div id="right-sidebar-slider">
>>
</div>
<div id="right-sidebar-content">
Feedback form here...
</div>
<footer>
This is our footer text.
</footer>
</body>
</html>
So I have two questions:
1. In terms of overall page structure/approach - wHat is the best approach to building something like this?
What is the best approach to replicating the sliding divs? I don't need them to animate, though that would be nice. I just need the user to be able to fill the viewport with the center topic div content.
All of the actual content will come from a CMS. This single page I'm creating is just a template that the CMS (a proprietary one) will use to then insert the content, table of contents, etc. into the html.
Your approach is not far off, but I have a couple of suggestions:
CSS flexbox instead of floats to setup the three column layout. (A Complete Guide to Flexbox)
Use CSS transitions instead of javascript to add the sliding effect. (Using CSS transitions)
Let the click of a button add/remove a class to the sidebar elements, so you do not need to have presentational informasjon in your javascript
Codepen: https://codepen.io/anon/pen/XqaGEg
HTML:
<button class="sidebar-left-toggle">
<<
</button>
<button class="sidebar-right-toggle">
>>
</button>
<div class="container">
<div class="sidebar-left">sidebar-left</div>
<div class="content">content</div>
<div class="sidebar-right">sidebar-right</div>
</div>
CSS:
.container {
display: flex;
height: 200px;
transition: width 0.3s;
}
.sidebar-left,
.sidebar-right {
background: #ccc;
width: 200px;
transition: width 0.3s;
}
.sidebar-collapsed {
width: 0;
overflow: hidden;
}
.content {
background: #eee;
flex-grow: 1;
}
Javascript:
const leftToggle = document.querySelector('.sidebar-left-toggle');
const rightToggle = document.querySelector('.sidebar-right-toggle');
const leftSidebar = document.querySelector('.sidebar-left');
const rightSidebar = document.querySelector('.sidebar-right');
leftToggle.addEventListener('click', e => {
leftSidebar.classList.toggle('sidebar-collapsed');
});
rightToggle.addEventListener('click', e => {
rightSidebar.classList.toggle('sidebar-collapsed');
});

Categories

Resources