So I have a bar that contains many smaller divs inside it, each with the same class.
.outer-bar{
width: 100%;
height: 50px;
background-color: blue;
}
.outer-bar button {
width: 50px;
height: 40px;
outline: none;
background-color: white;
border: none;
margin-top: 5px;
margin-bottom: 5px;
float: left;
margin-left: 2px;
}
<div class = "outer-bar">
<button class = "a">Hi</button>
<button class = "a">Hi</button>
<button class = "a">Hi</button>
<button class = "a">Hi</button>
<button class = "a">Hi</button>
<button class = "a">Hi</button>
<button class = "a">Hi</button>
<button class = "a">Hi</button>
<button class = "a">Hi</button>
</div>
When the window resized, I want the window to only show enough of them that there is no overflow, but there is as many as there can be.
So using: window.addEventListener("resize", function() {} );, is there any way to implement that?
One great example I saw was on Google Docs, where their bar automatically adjusts.
I would prefer doing this with Javascript and CSS and no Jquery or external libaries. (Note that I simplified the widths and number of elements for illustration purposes although the basic idea is still the same). I also prefer the use of for loops and document.getElementsByClassName("a").
I already started it by using:
var ribbon = document.getElementsByClassName("outer-bar")[0];
var prevChild = 0;
for(var i = 0; i < ribbon.children.length; i++) {
if(ribbon.children[i].getBoundingClientRect().right < prevChild) {
for(var c = i; c < ribbon.children.length; c++) {
ribbon.children[c].style.display = "none";
}
break;
}
prevChild = ribbon.children[i].getBoundingClientRect().right;
}
Although that method does not make the children displayable once I resize the window to be bigger.
If you know ribbon length why not divide it by the size you want the button to be. Then loop through the buttons making the first ones(ribbon length/size) block and the rest none.
I am not sure I understand you right, but it looks like you need to do a different styling to the inner divs when the screen resizes. CSS is capable of handling this for you without needing to use JavaScript at all.
Media Queries let you specify different styling based on the current size of the window.
.outer-bar button {
width: 50px;
height: 40px;
outline: none;
background-color: white;
border: none;
margin-top: 5px;
margin-bottom: 5px;
float: left;
margin-left: 2px;
}
#media screen and (max-width: 600px) {
.outer-bar button {
/*
Specify here any different styling
Ex.
*/
width: 25px;
}
}
Related
I have implemented a customized scrollbar (code is provided below).
I want to use the javaScript event "onScroll" to change the scrollbar thumb styling while scrolling, but I don't know the right way to do so.
Is there a way to access the scrollbar style, perhaps as a JavaScript object, i.e.:
Container.style.-webkit-scrollbar-thumb.backgroundColor = 'black';?
Here is some code to demonstrate how my scrollbar is implemented:
CSS:
#container::-webkit-scrollbar {
width: 10vw;
}
#container::-webkit-scrollbar-thumb {
background-color: grey;
border-radius: 50px;
border: 5px solid black;
}
#container::-webkit-scrollbar-thumb:hover {
border: 2px solid black;
background-color: grey;
}
#container::-webkit-scrollbar-track {
background-color: black;
border-bottom-left-radius: 12px;
border-top-left-radius: 12px;
}
JavaScript:
elementsContainer.addEventListener("scroll", function wheelStyle() {
//elementsContainer.WHAT??
});
Here is my solution:
The idea is to create a CSS stylesheet rule dynamically and update it while scrolling.
Here is the snippet I used to test in stackoverflow itself (by running it from the console directly):
// Based on https://stackoverflow.com/a/31126328/1941313
appendRule = (sheet) => {
console.log({sheet});
const len = sheet.cssRules.length;
sheet.insertRule('body{}', len);
return sheet.cssRules[len];
}
ruleForScroll = appendRule(Array.from(document.styleSheets).slice(-1)[0]);
randomColor = () => Math.floor(255 * Math.random());
component = document.querySelector('.left-sidebar--sticky-container.js-sticky-leftnav');
component.addEventListener("scroll", function wheelStyle() {
ruleForScroll.selectorText = '.left-sidebar--sticky-container.js-sticky-leftnav::-webkit-scrollbar-track';
ruleForScroll.style["background"] = `rgb(${randomColor()},${randomColor()},${randomColor()})`;
});
This specifically affects the side menu of stackoverflow, changing the scrollbar's color randomly while scrolling.
Here is an independent solution in a CodePen. Note that an important prerequisite for the style to apply is the following css rule:
.test::-webkit-scrollbar {
width: 10px;
height: 10px;
background-color: transparent;
}
Here is the pen I've created.
HTML
<div class = 'cc'>
<div class = 'bb'><div class = 'aa'> Some word </div></div>
</div>
CSS
.cc {
width: 100%;
min-height: 90px;
margin: 0;
padding: 0;
border: 1px solid #999999;
border-radius: 3px;
padding-left: 20px;
padding-right: 20px;
font-family: "Calibri";
font-size: 17px;
color: #666666;
background-color: rgba(0,0,0,.0);
}
.bb {
height: 100px;
width: 100%;
background-color: rgba(0,0,0,.5);
}
.aa {
position: relative;
top: 50%;
transform: translateY(-50%);
}
Now I want to create a clickable event such that when user click on class bb, page will check the top parameter of class aa - if it is 50% then smoothly change that to 10% and vice versa.
I want to use JavaScript code to achieve that. How can I do that?
hey just tried to gave shot at it , seems its working please look into this
let bb = document.querySelector('.bb');
let aa = document.querySelector('.aa');
bb.addEventListener('click',e => {
let top = window.getComputedStyle(aa).getPropertyValue('top');
if(top === '50px'){
aa.style.top = '10%';
}else{
aa.style.top = '50%';
}
})
Got it. It is tested and it seems to work.
let bb = document.querySelector('.bb');
let aa = document.querySelector('.aa');
bb.addEventListener('click', function(){
if(window.getComputedStyle(aa).getPropertyValue('top') === '50px'){
aa.style.top = '10%';
}else{
aa.style.top = '50%';
}
})
First, I used querySelector to get .bb and .aa.
Then, I added a event listener to bb.
Next, in the event listener I used window.getComputedStyle(), got the value of top from it and checked if it is 50px.
Last of all, if it is, change that to 10%, else change it to 50%.
I did this on CodePen, you can check it here (notice I changed the style from gray to white because gray is hard to read inside a black box).
First of all, no, I'm not going to use jQuery.
So, I have this project I'm working on, and I want to do a slide toggle element. Everything is nice and good until I press the button really fast. Then the borders dissapear and the element has reached its final height(500 px in this case).
Perhaps my explanation wasn't that accurate, but I'll give you the code.
var div = document.getElementById('div');
var btn = document.getElementById('button');
function clickFunction(){
if(div.style.height === "0px") {
div.style.height = "500px";
div.style.borderStyle = "solid";
} else {
div.style.height = "0px";
setTimeout(function(){div.style.borderStyle = "none";}, 500);
}
}
btn.onclick = clickFunction;
div#div {
transition: 500ms ease;
width: 100px;
height: 200px;
margin-top: 20px;
}
.container {
width: 120px;
background-color: red;
padding: 8px;
}
<button id="button">
Press me
</button>
<div class="container">
<div id="div" style="border-style: none; border-width: 2px; height: 0px;"></div>
</div>
I also tried using clearTimeout() but it wasn't working. Yes, I set setTimeout as a variable, but it doesn't do anything.
Any ideas? Cheers.
Your current code uses combinations of inline styles and an id selector in conjunction with the inline style being updated by JavaScript in an if/then as well as with a setTimeout() callback. All of these instructions, coupled with the speed at which the client can repaint the UI are all contributing to the problem.
By cleaning up the approach to toggling the styles and how the styles are applied in the first place, there is much less potential conflict in instructions and timing.
Remove all the static styles from the HTML and set up CSS classes for the normal and expanded states of the element. Then just use the element.classList.toggle() method to seamlessly toggle the use of the expanded class. No timers needed.
var div = document.getElementById('div');
var btn = document.getElementById('button');
btn.addEventListener("click", function(){
div.classList.toggle("expanded");
});
.container {
width: 120px;
background-color: red;
padding: 8px;
}
.normal {
transition: 500ms ease;
width: 100px;
margin-top: 20px;
border:0px solid black;
height: 0px;
}
.expanded {
height: 200px;
border:2px solid black;
}
<button id="button">Press me</button>
<div class="container">
<div id="div" class="normal"></div>
</div>
NOTE:
Be careful when setting up CSS selectors that are id based because they become very difficult to override later. I'm not saying never use them, but more often than not, CSS classes provided the most flexible solutions and help to avoid gobs and gobs of inline styles.
Is it possible to create a minimalist javasript only on-scroll function to hide my menu bar, so only the menu button shows and the button itself gains a white backgroud colour? I have been looking into this and I believed to have the code fairly down. But I am very new to javasript and cannot fully understand the syntax of it yet. Below is what I have now in a jsfiddle:
https://jsfiddle.net/AngusBerry/zLt0yLou/2/#&togetherjs=Vsth32pa6L
html:
<!DOCTYPE html>
<body>
<header>
<h1><span id="tstscroll">0</span></h1>
<div class="MenuButton" id="mobMenu"></div>
<!--<p>as you can see, this is the header for the website. Here will also be contained all of the links to anywhere on the support system. this and the footer will both be FIXED and will move with the page.</p>-->
</header>
</body>
css:
header {
top: 0px;
position: fixed;
max-height: 100px;
width: 100%;
padding-top: 2px;
padding-bottom: 3.5px;
color: green;
animation: max-height-header;
animation-duration: 1.5s;
}
header h1 {
position: relative;
float: left;
margin-left: 3px;
}
header .MenuButton {
width: 28px;
height: 6px;
border-top: 6px solid;
border-bottom: 18px double;
margin-right: 5px;
margin-top: 2px;
}
javascript:
var mobilemenu = document.getElementById('mobMenu');
var testscroller = document.getElementById('tstscroll');
var x = 0;
document.mobilemenu.addEventListener("scroll", menuScrolMob);
function menuScrolMob(mobilemenu.onscroll) {
testscroller.innerhtml = x += 1;
}
You'll need to run that script either last in your body, or after page been loaded, or else it won't be able to access the elements.
Also, your script code is wrong, so here is a solution showing how to solve both those issues
(function(w, d) { /* this is a closure and will keep its variables
from polluting the global namespace and it also
declare 2 variables (w, d) to be used inside it */
w.addEventListener("load", function() {
var mobilemenu = d.getElementById('mobMenu');
var testscroller = d.getElementById('tstscroll');
var x = 0;
mobilemenu.addEventListener("scroll", function() {
testscroller.innerhtml = x += 1;
});
});
}(window, document)); /* here I pass the window and document object into the
closure's variables (w, d) to make the code slimmer */
I am trying to create a box that expands and collapses using regular JavaScript (No jQuery). The problem I'm running into is detecting how to properly detect dynamically created elements or classes that are added to elements after pageload.
Here's an example JS fiddle page:
http://jsfiddle.net/1a518a4t/3/
As you can see, it works when you collapse and then expand once, but then it won't collapse again.
JS code:
function test() {
var badge = document.getElementById('test');
var close_button = document.querySelector('.test-close');
close_button.addEventListener("click", close_box);
function close_box() {
badge.style.bottom = '-70px';
close_button.classList.add("test-open");
close_button.classList.remove("test-close");
var open_button = document.querySelector('.test-open');
open_button.addEventListener("click", open_box);
}
function open_box() {
badge.style.bottom = '0';
close_button.classList.remove("test-open");
close_button.classList.add("test-close");
}
}
window.onload = test;
I think I really just want to learn how to replicate jQuery's on method in JavaScript. That works for elements that are dynamically created after pageload.
Use a single event listener. And don't modify inline styles, just switch classes:
var badge = document.getElementById('test');
var button = document.querySelector('.button');
button.addEventListener("click", function toggle_box() {
badge.classList.toggle('opened');
badge.classList.toggle('closed');
});
#test {
width: 300px;
height: 100px;
background-color: #ccc;
position: fixed;
bottom: 0;
right: 20px;
transition: all 0.2s;
}
#test.closed {
bottom: -70px;
}
#test > .button {
position: absolute;
top: 10px;
right: 10px;
width: 10px;
height: 10px;
text-indent: -9999px;
cursor: pointer;
background-color: #000;
}
#test.closed > .button {
background-color: #CE312F;
}
<div id="test" class="opened">
<div class="button">Test</div>
</div>
As mentioned in the comments, this is because the created element is added dynamically and as such you need to delegate so event handler can bind it to the created element. To do that you can look at #Ramswaroop solution to do this in native JavaScript. Although I don't think it's even nessisary to change class and re-bind the different functions. Simply use the same <div> and have a toggle function:
var button = document.querySelector('#test div');
button.addEventListener("click", toggle_box);
...
function toggle_box() {
if(badge.style.bottom == '-70px') {
badge.style.bottom = '-0';
toggleClass("test-close", "test-open");
} else {
badge.style.bottom = '-70px';
toggleClass("test-open", "test-close");
}
}
Fiddle Example