I'm creating toggle buttons that need some specific functions:
1) Show content on the first click (this works)
2) Hide content when you click on a different button (this works)
3) Hide content on the second click (this doesn't work)
Right now, if you click the same button twice it first slidesUp (because if you do click a different button, the previous content needs to be closed). Once it's up it then slidesDown, making it very jumpy.
Is there a way to make all 3 functions work??
Removing the " $(".assortiment").slideUp();" line fixes this jumpy problem, but that also stops function 2 from working...
function assortiment(e){
var assortimentid = e.id + "__js";
if ($("#" + assortimentid).display = "block"){
$(".assortiment").slideUp();
$("#" + assortimentid).slideToggle();
} else if ($("#" + assortimentid).display = "none"){
$("#" + assortimentid).slideToggle();
}
}
.assortiment {
display: none;
}
.btn {
border: 1px solid black;
border-radius: 10px;
padding: 10px;
width: 100px;
margin: 5px;
background-color: lightblue;
}
.btn:hover {
cursor: pointer
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="btn" id="section1" onclick="assortiment(this)">Section 1</div>
<div class="btn" id="section2" onclick="assortiment(this)">Section 2</div>
<div class="btn" id="section3" onclick="assortiment(this)">Section 3</div>
<div class="assortiment" id="section1__js">
<p>SOME CONTENT 1</p>
<p>Lorem ipsum dolor sit amet, aliquip apeirian dissentiunt ex pro. Ad choro facilis offendit mel, et quo quot democritum. Aliquip quaestio periculis ad eam, legere altera reprehendunt eu his. Cu has virtute pericula definitionem, cu facete conclusionemque has, cu errem accusamus duo.
</p>
</div>
<div class="assortiment" id="section2__js">
<p>SOME CONTENT 2</p>
<p>Lorem ipsum dolor sit amet, aliquip apeirian dissentiunt ex pro. Ad choro facilis offendit mel, et quo quot democritum. Aliquip quaestio periculis ad eam, legere altera reprehendunt eu his. Cu has virtute pericula definitionem, cu facete conclusionemque has, cu errem accusamus duo.
</p>
</div>
<div class="assortiment" id="section3__js">
<p>SOME CONTENT 3</p>
<p>Lorem ipsum dolor sit amet, aliquip apeirian dissentiunt ex pro. Ad choro facilis offendit mel, et quo quot democritum. Aliquip quaestio periculis ad eam, legere altera reprehendunt eu his. Cu has virtute pericula definitionem, cu facete conclusionemque has, cu errem accusamus duo.
</p>
</div>
Well try to avoid inline javascript..Write a separate function for .btn click to toggle display...use slideToggle() jQuery to toggle the same element...and slideUp() with not() to hide other elements
Also use === for comparison in condition,...= is used to assigned a value...
Also the element.display = "none" is not a valid statement, it should be like element.css("display") === "none"
$(".btn").on("click", function() {
var item = "#" + $(this).attr("id") + "__js"
$(".assortiment").not(item).stop().slideUp();
$(item).stop().slideToggle();
})
.assortiment {
display: none;
}
.btn {
border: 1px solid black;
border-radius: 10px;
padding: 10px;
width: 100px;
margin: 5px;
background-color: lightblue;
}
.btn:hover {
cursor: pointer
}
p {
margin: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="btn" id="section1">Section 1</div>
<div class="btn" id="section2">Section 2</div>
<div class="btn" id="section3">Section 3</div>
<div class="assortiment" id="section1__js">
<p>SOME CONTENT 1</p>
</div>
<div class="assortiment" id="section2__js">
<p>SOME CONTENT 2</p>
</div>
<div class="assortiment" id="section3__js">
<p>SOME CONTENT 3</p>
</div>
You are missing the .stop() method which stops the currently-running animation on the matched element or in other words, prevents repetition:
function assortiment(e){
var assortimentid = e.id + "__js";
if ($("#" + assortimentid).display = "block"){
$(".assortiment").stop().slideUp();
$("#" + assortimentid).stop().slideToggle();
} else if ($("#" + assortimentid).display = "none"){
$("#" + assortimentid).stop().slideToggle();
}
}
* {margin: 0; box-sizing: border-box} /* addition; more "fluent" */
.assortiment {
display: none;
}
.btn {
border: 1px solid black;
border-radius: 10px;
padding: 10px;
width: 100px;
margin: 5px;
background-color: lightblue;
}
.btn:hover {
cursor: pointer
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="btn" id="section1" onclick="assortiment(this)">Section 1</div>
<div class="btn" id="section2" onclick="assortiment(this)">Section 2</div>
<div class="btn" id="section3" onclick="assortiment(this)">Section 3</div>
<div class="assortiment" id="section1__js">
<p>SOME CONTENT 1</p>
</div>
<div class="assortiment" id="section2__js">
<p>SOME CONTENT 2</p>
</div>
<div class="assortiment" id="section3__js">
<p>SOME CONTENT 3</p>
</div>
Try this
function assortiment(e){
var assortimentid = e.id + "__js";
if ($("#" + assortimentid).display == "block"){
$(".assortiment").hide();
$("#" + assortimentid).slideToggle();
} else if ($("#" + assortimentid).display == "none"){
$("#" + assortimentid).slideToggle();
}
Update your JS function defination to :
function assortiment(e){
var assortimentid = e.id + "__js";
$(".assortiment").not("#" + assortimentid).slideUp();
$("#" + assortimentid).slideToggle();
}
Full Snippet: and jsFiddle
function assortiment(e){
var assortimentid = e.id + "__js";
$(".assortiment").not("#" + assortimentid).slideUp();
$("#" + assortimentid).slideToggle();
}
.assortiment {
display: none;
}
.btn {
border: 1px solid black;
border-radius: 10px;
padding: 10px;
width: 100px;
margin: 5px;
background-color: lightblue;
}
.btn:hover {
cursor: pointer
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="btn" id="section1" onclick="assortiment(this)">Section 1</div>
<div class="btn" id="section2" onclick="assortiment(this)">Section 2</div>
<div class="btn" id="section3" onclick="assortiment(this)">Section 3</div>
<div class="assortiment" id="section1__js">
<p>SOME CONTENT 1</p>
<p>Lorem ipsum dolor sit amet, aliquip apeirian dissentiunt ex pro. Ad choro facilis offendit mel, et quo quot democritum. Aliquip quaestio periculis ad eam, legere altera reprehendunt eu his. Cu has virtute pericula definitionem, cu facete conclusionemque has, cu errem accusamus duo.
</p>
</div>
<div class="assortiment" id="section2__js">
<p>SOME CONTENT 2</p>
<p>Lorem ipsum dolor sit amet, aliquip apeirian dissentiunt ex pro. Ad choro facilis offendit mel, et quo quot democritum. Aliquip quaestio periculis ad eam, legere altera reprehendunt eu his. Cu has virtute pericula definitionem, cu facete conclusionemque has, cu errem accusamus duo.
</p>
</div>
<div class="assortiment" id="section3__js">
<p>SOME CONTENT 3</p>
<p>Lorem ipsum dolor sit amet, aliquip apeirian dissentiunt ex pro. Ad choro facilis offendit mel, et quo quot democritum. Aliquip quaestio periculis ad eam, legere altera reprehendunt eu his. Cu has virtute pericula definitionem, cu facete conclusionemque has, cu errem accusamus duo.
</p>
</div>
Related
I have a site and I want each section to take up the screen and as you scroll down the page the sections fade out as the next section comes into view. I'm struggling on how this math needs to work.
For one section it's easy which is basically the height of the element and it's distance from the top to get the opacity percentage. However, I just can't quite figure out the math for other sections. I need section 2 to start fading in as section 1 is fading out.
I do not want to scrolljack. I just want a scrolling effect. Rather than override default scrolling behavior I just want to animate in/out as you scroll where a certain Y scroll value = a certain CSS value rather than a sort of "breakpoint" where it animates to a new "slide".
For the proper effect, for example, my math divides the height of the row by 2 so that it's 50% faded out as the next section should be fading in 50%. But, as of now, the math just doesn't work for the other sections.
This site is using vanilla JS as it's supposed to be a simple one pager.
Example below:
(function () {
window.addEventListener('scroll', () => {
const rows = document.querySelectorAll('.row');
rows.forEach(function (row, index) {
const distanceToTop = window.pageYOffset;
const elementHeight = row.offsetHeight * (index + 1) / 2;
row.style.opacity = ((elementHeight - distanceToTop) / elementHeight * 100) / 100;
});
});
})();
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0 0 0 0;
font-family: sans-serif;
font-family: 'Manrope', helvetiva, sans-serif;
transition: background-color 1s;
color:#fff;
background: linear-gradient(0deg, #100521 0%, #50357c 50%, #878290 100%);
}
header {
position: fixed;
top: 0;
width: 100%;
background: #fff;
z-index: 999;
}
header h1 {
font-family: 'Lack';
font-size: 4em;
text-align: center;
padding: 10px;
color: #100521;
}
.row-container .row:first-child {
opacity: 1;
}
.row {
opacity: 0;
height: 100vh;
display: flex;
flex-direction:column;
}
.row-inner {
display: grid;
grid-template-columns: 1fr 1fr;
position: sticky;
top: 0;
/* border: 1px solid yellow; */
padding: 0;
height: 100vh;
}
.column {
display: flex;
flex-direction: column;
justify-content: center;
align-content: center;
flex: 50%;
padding: 10px;
}
.left-column {
background-color: transparent;
}
.right-column {
background-color: transparent;
}
h1 {
font-family: 'Unbounded', helvetica, sans-serif;
}
h1 {
margin: 0;
font-size: 36px;
}
h2 {
margin: 0;
font-size: 24px;
}
p {
margin: 10px 0;
font-size: 18px;
line-height: 1.5;
}
img {
width: 100%;
height: auto;
}
<!DOCTYPE html>
<html>
<head>
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Manrope&family=Unbounded&family=Lack&display=swap" rel="stylesheet">
</head>
<body>
<header>
<h1>My App</h1>
</header>
<!-- First row -->
<div class="row-container">
<div class="row section-1">
<div class="row-inner">
<div class="column left-column">
<div class="column-inner">
<h1>Headline 1</h1>
<h2>Subhead 1</h2>
<p>Lorem Ipsum dolar Gamet</p>
</div>
</div>
<div class="column right-column">
<div class="column-inner">
<img src="https://avatars.dicebear.com/api/adventurer/team-member-1.jpg" alt="Image 1">
</div>
</div>
</div>
</div>
<!-- Second row -->
<div class="row section-2">
<div class="row-inner">
<div class="column left-column">
<div class="column-inner">
<h1>Headline 2</h1>
<h2>Subhead 2</h2>
<p>Lorem Ipsum dolar Gamet</p>
</div>
</div>
<div class="column right-column">
<div class="column-inner">
<img src="https://avatars.dicebear.com/api/adventurer/team-member-2.jpg" alt="Image 2">
</div>
</div>
</div>
</div>
<!-- Third row -->
<div class="row section-3">
<div class="row-inner">
<div class="column left-column">
<div class="column-inner">
<h1>Headline 3</h1>
<h2>Subhead 3</h2>
<p>Lorem Ipsum dolar Gamet</p>
</div>
</div>
<div class="column right-column">
<div class="column-inner">
<img src="https://avatars.dicebear.com/api/adventurer/team-member-3.jpg" alt="Image 3">
</div>
</div>
</div>
</div>
<!-- Fourth row -->
<div class="row section-4">
<div class="row-inner">
<div class="column left-column">
<div class="column-inner">
<h1>Headline 4</h1>
<h2>Subhead 4</h2>
<p>Lorem Ipsum dolar Gamet</p>
</div>
</div>
<div class="column right-column">
<div class="column-inner">
<img src="https://avatars.dicebear.com/api/adventurer/team-member-4.jpg" alt="Image 4">
</div>
</div>
</div>
</div>
</div>
</body>
</html>
As suggested in one of the comments to your question, it's more effective to use IntersectionObserver rather than the 'scroll' event listener.
If I'm correct, this snippet should help you achieve what you're looking for:
window.addEventListener("load", (event) => {
let options = {
rootMargin: "0px",
threshold: 0.8
};
const intersectionHandler = function(entries, observer) {
entries.forEach((entry) => {
if (entry.isIntersecting && entry.intersectionRatio > 0.8) {
entry.target.classList.remove("fadeOut");
entry.target.classList.add("fadeIn");
} else {
entry.target.classList.remove("fadeIn");
entry.target.classList.add("fadeOut");
}
});
};
let observer = new IntersectionObserver(intersectionHandler, options);
document.querySelectorAll(".section").forEach((row, index) => {
observer.observe(row);
});
});
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0 0 0 0;
font-family: sans-serif;
font-family: "Manrope", helvetiva, sans-serif;
transition: background-color 1s;
color: #fff;
background: linear-gradient(0deg, #100521 0%, #50357c 50%, #878290 100%);
}
header {
position: fixed;
top: 0;
width: 100%;
background: #fff;
z-index: 999;
}
header h1 {
font-family: "Lack";
font-size: 4em;
text-align: center;
padding: 10px;
color: #100521;
}
.row-container .row:first-child {
opacity: 1;
}
.row {
opacity: 0;
height: 100vh;
display: flex;
flex-direction: column;
overflow: hidden;
}
.row-inner {
display: grid;
grid-template-columns: 1fr 1fr;
position: sticky;
top: 0;
/* border: 1px solid yellow; */
padding: 0;
height: 100vh;
}
.column {
display: flex;
flex-direction: column;
justify-content: center;
align-content: center;
flex: 50%;
padding: 10px;
height: 100vh;
box-sizing: border-box;
}
.left-column {
background-color: transparent;
}
.right-column {
background-color: transparent;
}
h1 {
font-family: "Unbounded", helvetica, sans-serif;
}
h1 {
margin: 0;
font-size: 36px;
}
h2 {
margin: 0;
font-size: 24px;
}
p {
margin: 10px 0;
font-size: 18px;
line-height: 1.5;
}
img {
width: 100%;
height: auto;
}
.fadeIn {
animation-name: fadeIn;
animation-duration: 1s;
animation-fill-mode: forwards;
}
.fadeOut {
animation-name: fadeOut;
animation-duration: .5s;
animation-fill-mode: forwards;
}
#keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
#keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
<!-- First row -->
<div class="row-container">
<div class="row section">
<div class="row-inner">
<div class="column left-column">
<div class="column-inner">
<h1>Headline 1</h1>
<h2>Subhead 1</h2>
<p>Lorem Ipsum dolar Gamet</p>
</div>
</div>
<div class="column right-column">
<div class="column-inner">
<img src="https://avatars.dicebear.com/api/adventurer/team-member-1.jpg" alt="Image 1">
</div>
</div>
</div>
</div>
<!-- Second row -->
<div class="row section">
<div class="row-inner">
<div class="column left-column">
<div class="column-inner">
<h1>Headline 2</h1>
<h2>Subhead 2</h2>
<p>Lorem Ipsum dolar Gamet</p>
</div>
</div>
<div class="column right-column">
<div class="column-inner">
<img src="https://avatars.dicebear.com/api/adventurer/team-member-2.jpg" alt="Image 2">
</div>
</div>
</div>
</div>
<!-- Third row -->
<div class="row section">
<div class="row-inner">
<div class="column left-column">
<div class="column-inner">
<h1>Headline 3</h1>
<h2>Subhead 3</h2>
<p>Lorem Ipsum dolar Gamet</p>
</div>
</div>
<div class="column right-column">
<div class="column-inner">
<img src="https://avatars.dicebear.com/api/adventurer/team-member-3.jpg" alt="Image 3">
</div>
</div>
</div>
</div>
<!-- Fourth row -->
<div class="row section">
<div class="row-inner">
<div class="column left-column">
<div class="column-inner">
<h1>Headline 4</h1>
<h2>Subhead 4</h2>
<p>Lorem Ipsum dolar Gamet</p>
</div>
</div>
<div class="column right-column">
<div class="column-inner">
<img src="https://avatars.dicebear.com/api/adventurer/team-member-4.jpg" alt="Image 4">
</div>
</div>
</div>
</div>
</div>
You'll notice I've made some minor modifications to your HTML and CSS, but the magic happens in the Javascript.
I've also used the window "load" event listener to create the observer options, object and callback function when the page is loaded.
You can check the IntersectionObserver API docs for more details on how it works and how to tweak the options or the callback to suit your needs.
Let me know if you have any questions for modifying my code. (I've also had to change your css a bit - the content of the row element was higher than the row element itself what led to some weird issues.)
I have rewritten most of it and it should now work for large row heights. The math for it is just a quadratic formula (Opacity of offset from center of the screen) with it's roots at the height of the row and a maximum at 0 offset with a value of 1.
/** #format */
const calculateOpacity = () => {
const ROW_CONTAINER = document.querySelector(".row-container");
const rows = ROW_CONTAINER.children;
const rowContainerBBox = ROW_CONTAINER.getBoundingClientRect();
console.log("calc")
for (const row of rows) {
const rowBBox = row.getBoundingClientRect();
const top = rowBBox.top - rowContainerBBox.top;
const bottom = rowBBox.bottom - rowContainerBBox.bottom;
if (rowBBox.height > rowContainerBBox.height) {
const opacityOfOffset = (offset) => {
const a = -1 / Math.pow(rowBBox.height, 2);
return Math.max(0, a * Math.pow(offset, 2) + 1);
};
row.style.opacity = opacityOfOffset(top + bottom);
continue;
}
const unvisibleHeightTop = -Math.min(0, top);
const unvisibleHeightBottom = Math.max(0, bottom);
const visibleHeight = rowBBox.height - unvisibleHeightTop - unvisibleHeightBottom;
row.style.opacity = visibleHeight / rowBBox.height;
}
};
document.querySelector(".row-container").addEventListener("scroll", calculateOpacity);
/** #format */
body {
height: 100%;
margin: 0;
padding: 0;
font-family: sans-serif;
font-family: "Manrope", helvetiva, sans-serif;
color: #fff;
}
header {
height: max(70px, 10vh);
position: fixed;
background-color: black;
width: 100%;
display: flex;
align-items: center;
}
header h1 {
margin: 0;
}
main {
padding-top: max(70px, 10vh);
height: 100%;
box-sizing: border-box;
}
.row-container {
background: linear-gradient(0deg, #100521 0%, #50357c 50%, #878290 100%);
height: calc(100vh - max(70px, 10vh));
overflow-y: auto;
}
.row {
height: 150vh;
display: flex;
align-items: center;
padding: 10vh 0;
}
.row .row-inner {
width: 100%;
height: 100%;
display: grid;
grid-template-columns: 1fr 1fr;
}
.row .row-inner .col {
margin-inline: 10px;
display: flex;
align-items: center;
height: 100%;
}
.row img {
width: 100%;
height: auto;
}
.row h2 {
margin: 0;
font-family: "Unbounded", helvetica, sans-serif;
font-size: 36px;
}
.row h3 {
margin: 0;
font-size: 24px;
}
.row p {
margin: 10px 0;
font-size: 18px;
line-height: 1.5;
}
<!-- #format -->
<html>
<head>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Manrope&family=Unbounded&family=Lack&display=swap" rel="stylesheet" />
</head>
<body>
<header>
<h1>My App</h1>
</header>
<main>
<div class="row-container">
<div class="row row-1">
<div class="row-inner">
<div class="col left">
<div class="col-inner">
<h2>Headline 1</h2>
<h3>Subhead 1</h3>
<p>Lorem ipsum dolor sit</p>
</div>
</div>
<div class="col right">
<img src="https://avatars.dicebear.com/api/adventurer/team-member-1.jpg" alt="Image 1" />
</div>
</div>
</div>
<div class="row row-1">
<div class="row-inner">
<div class="col left">
<div class="col-inner">
<h2>Headline 1</h2>
<h3>Subhead 1</h3>
<p>Lorem ipsum dolor sit</p>
</div>
</div>
<div class="col right">
<img src="https://avatars.dicebear.com/api/adventurer/team-member-1.jpg" alt="Image 1" />
</div>
</div>
</div>
<div class="row row-1">
<div class="row-inner">
<div class="col left">
<div class="col-inner">
<h2>Headline 1</h2>
<h3>Subhead 1</h3>
<p>Lorem ipsum dolor sit</p>
</div>
</div>
<div class="col right">
<img src="https://avatars.dicebear.com/api/adventurer/team-member-1.jpg" alt="Image 1" />
</div>
</div>
</div>
</div>
</main>
</body>
</html>
You didn't really ask for a web component, I just got carried away. This is a fun challenge! Anyway, here's a version that is NOT a web component. I also realized that I missed all the css that you provided. So I added that as well. I'm not sure if tweaking the css a little is verbotten ... but I did it. I also added a single [section] tag, which wraps everything but the app header, to make it more bullet proof ... Please let me know if I need to use your code exactly as you posted it.
I had a lot of trouble finding settings that provide a dramatic enough effect on both large screens and phones without some ugly hacks, so I opted for a compromise. You can optimize for either large or small by changing the rootMargin option for the IntersectionObserver. Smaller values make the fade effect more dramatic, but values that are too small cause the content to look washed out on smaller devices. As I'm posting this, rootMargin is set to "-25px". Apparantly you can use negative values, but as far as I can tell, you can only use "px" as the measurement. Other measurements don't seem to work.
Sooooo...
I used IntersectionObserver
const observer = new IntersectionObserver(fadeInOut, options);
One of the options IntersectionObserver takes is something called "threshold". I don't totally understand it, but MDN suggested that if you want to poll the viewport to determine element visibility, you should set the value of "threshold" as an array with many numbers ranging from 0 to 1. The example provided a function that generates 20 of them, so that's what I used.
function buildThresholds() {
const steps = 20;
const thresholds = [];
for (let i = 0; i <= steps; i++) {
let ratio = i/steps;
thresholds.push(ratio);
}
thresholds.push(0);
return thresholds;
}
Then I grabbed the collection of elements to watch using querySelectorAll(".row-container").
Then I looped through the elements and added each one to the observer's watch list.
observer.observe(elem);
Then, in the callback you provide when you create a new instance of IntersectionObserver, I set each element's opacity to the the intersectionRatio, which is a property provided by the instance of the IntersectionObserverEntry which is passed to the callback.
function fadeInOut(items, observer) {
items.forEach( (item) => {
item.target.style.opacity = item.intersectionRatio;
});
}
function buildThresholds() {
const steps = 20;
const thresholds = [];
for (let i = 0; i <= steps; i++) {
let ratio = i/steps;
thresholds.push(ratio);
}
thresholds.push(0);
return thresholds;
}
function fadeInOut(items, observer) {
items.forEach( (item) => {
item.target.style.opacity = item.intersectionRatio;
});
}
function scrollFade() {
const elems = document.querySelectorAll('.row-container');
const options = {
root: null,
rootMargin: "-25px",
threshold: buildThresholds()
};
const observer = new IntersectionObserver(fadeInOut, options);
for (let elem of elems) {
observer.observe(elem);
}
}
document.addEventListener('DOMContentLoaded', scrollFade);
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0 0 0 0;
font-family: sans-serif;
font-family: 'Manrope', helvetiva, sans-serif;
transition: background-color 1s;
color:#fff;
background: linear-gradient(0deg, #100521 0%, #50357c 50%, #878290 100%);
}
header {
position: fixed;
top: 0;
width: 100%;
background: #fff;
z-index: 999;
}
header h1 {
font-family: 'Lack';
font-size: 4em;
text-align: center;
padding: 10px;
color: #100521;
}
section {
margin-top: 6em;
}
h1 {
font-family: 'Unbounded', helvetica, sans-serif;
}
h1 {
margin: 0;
font-size: 36px;
}
h2 {
margin: 0;
font-size: 24px;
}
p {
margin: 10px 0;
font-size: 18px;
line-height: 1.5;
}
img {
width: 100%;
height: auto;
}
.row-container {
background-color: rgb(16, 5, 33);
min-height: 50vh;
}
.row-inner {
align-content: center;
align-items: center;
display: flex;
flex-direction: row;
flex-wrap: wrap-reverse;
padding: 10px;
gap: 10px;
}
.left-column {
flex: 1 1 70vw;
}
.right-column {
flex: 1 1 100px;
text-align: center;
}
<header>
<h1>My App</h1>
</header>
<section>
<div class="row-container">
<div class="row section">
<div class="row-inner">
<div class="column left-column">
<div class="column-inner">
<h1>Headline One</h1>
<h2>Subhead One</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
<div class="column right-column">
<div class="column-inner">
<img slot="avatar" src="https://avatars.dicebear.com/api/adventurer/team-member-1.jpg" alt="Image 1">
</div>
</div>
</div>
</div>
</div>
<div class="row-container">
<div class="row section">
<div class="row-inner">
<div class="column left-column">
<div class="column-inner">
<h1>Headline Two</h1>
<h2>Subhead Two</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
<div class="column right-column">
<div class="column-inner">
<img slot="avatar" src="https://avatars.dicebear.com/api/adventurer/team-member-2.jpg" alt="Image 1">
</div>
</div>
</div>
</div>
</div>
<div class="row-container">
<div class="row section">
<div class="row-inner">
<div class="column left-column">
<div class="column-inner">
<h1>Headline Three</h1>
<h2>Subhead Three</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
<div class="column right-column">
<div class="column-inner">
<img slot="avatar" src="https://avatars.dicebear.com/api/adventurer/team-member-3.jpg" alt="Image 1">
</div>
</div>
</div>
</div>
</div>
<div class="row-container">
<div class="row section">
<div class="row-inner">
<div class="column left-column">
<div class="column-inner">
<h1>Headline Four</h1>
<h2>Subhead Four</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
<div class="column right-column">
<div class="column-inner">
<img slot="avatar" src="https://avatars.dicebear.com/api/adventurer/team-member-4.jpg" alt="Image 1">
</div>
</div>
</div>
</div>
</div>
<div class="row-container">
<div class="row section">
<div class="row-inner">
<div class="column left-column">
<div class="column-inner">
<h1>Headline Five</h1>
<h2>Subhead Five</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
<div class="column right-column">
<div class="column-inner">
<img slot="avatar" src="https://avatars.dicebear.com/api/adventurer/team-member-5.jpg" alt="Image 1">
</div>
</div>
</div>
</div>
</div>
<div class="row-container">
<div class="row section">
<div class="row-inner">
<div class="column left-column">
<div class="column-inner">
<h1>Headline Six</h1>
<h2>Subhead Six</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
<div class="column right-column">
<div class="column-inner">
<img slot="avatar" src="https://avatars.dicebear.com/api/adventurer/team-member-6.jpg" alt="Image 1">
</div>
</div>
</div>
</div>
</div>
</section>
Will this work? I used IntersectionObserver and set the opacity of the sections based on the intersection ratio of each section with the viewport. I pretty much took the idea straight from MDN.
MDN Intersection Observer API
class ScrollFade extends HTMLElement {
template;
shadow;
static observer = false;
constructor() {
super();
this.shadow = this.attachShadow({mode: 'open'});
if (!ScrollFade.observer) {
const buildThresholds = function() {
const steps = 20;
const thresholds = [];
for (let i = 0; i <= steps; i++) {
let ratio = i/steps;
thresholds.push(ratio);
}
thresholds.push(0);
return thresholds;
}
const options = {
root: null,
rootMargin: "0px",
threshold: buildThresholds()
};
ScrollFade.observer = new IntersectionObserver(ScrollFade.fadeInOut, options);
}
}
connectedCallback() {
const tmpl = document.querySelector('#scroll-fade-template').cloneNode(true);
const template = tmpl.content;
ScrollFade.observer.observe(this.shadow.host);
this.shadow.append(template);
}
disconnectedCallback() {
ScrollFade.observer.unobserve(this.shadow.host);
}
static fadeInOut(items, observer) {
items.forEach( (item) => {
item.target.style.opacity = item.intersectionRatio;
});
}
}
document.addEventListener('DOMContentLoaded', customElements.define('scroll-fade', ScrollFade));
body { margin: 0 }
img { width: 100%; }
<scroll-fade>
<h1 slot="headline">Headline One</h1>
<h2 slot="subhead">Subhead One</h2>
<img slot="avatar" src="https://avatars.dicebear.com/api/adventurer/team-member-1.jpg" alt="Image 1">
<div>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip </p>
</div>
</scroll-fade>
<scroll-fade>
<h1 slot="headline">Headline Two</h1>
<h2 slot="subhead">Subhead Two</h2>
<img slot="avatar" src="https://avatars.dicebear.com/api/adventurer/team-member-2.jpg" alt="Image 2">
<div>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip </p>
</div>
</scroll-fade>
<scroll-fade>
<h1 slot="headline">Headline Three</h1>
<h2 slot="subhead">Subhead Three</h2>
<img slot="avatar" src="https://avatars.dicebear.com/api/adventurer/team-member-3.jpg" alt="Image 1">
<div>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip </p>
</div>
</scroll-fade>
<template id="scroll-fade-template">
<style>
.row-container {
background-color: seagreen;
height: 100vh;
overflow: auto;
}
.row-inner {
align-content: center;
display: flex;
flex-direction: row;
flex-wrap: wrap-reverse;
padding: 10px;
gap: 10px;
}
.left-column {
flex: 1 1 70vw;
}
.right-column {
flex: 1 1 100px;
text-align: center;
}
</style>
<div class="row-container">
<div class="row section">
<div class="row-inner">
<div class="column left-column">
<div class="column-inner">
<slot name="headline">Need Headline</slot>
<slot name="subhead">Need Subhead</slot>
<slot>Need Content</slot>
</div>
</div>
<div class="column right-column">
<div class="column-inner">
<slot name="avatar">Need Avatar</slot>
</div>
</div>
</div>
</div>
</div>
</template>
working on a way of displaying information, 8 panels (when each is clicked it expands content below) - however I am trying to add styling so that when one panel is clicked (active) - the background color updates to green and is removed when a new element is clicked. I can't seem to pass the tabName parameter to getElementById so for now the parameter is hardcoded as banking-tab (which does update to green when clicked). Does anyone have any advice for the best possible solution and a potential approach to explore for the remove function?
function onExpandFuncs(tabName) {
openTab(tabName);
styleTab(tabName);
}
function openTab(tabName) {
var i, x;
x = document.getElementsByClassName('containerTab');
for (i = 0; i < x.length; i++) {
x[i].style.display = 'none';
}
document.getElementById(tabName).style.display = 'block';
}
function styleTab(tabName) {
document.getElementById('banking-tab').classList.add('active-column');
}
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: Arial, Helvetica, sans-serif;
}
/* The grid: Four equal columns that floats next to each other */
.column {
background-color: black;
float: left;
width: 25%;
height: 226px;
padding: 50px;
text-align: center;
font-size: 16px;
cursor: pointer;
color: white;
}
.active-column {
background-color: green;
float: left;
width: 25%;
height: 226px;
padding: 50px;
text-align: center;
font-size: 16px;
cursor: pointer;
color: white;
}
.containerTab {
padding: 20px;
color: white;
}
/* Clear floats after the columns */
.row:after {
content: '';
display: table;
clear: both;
}
/* Closable button inside the container tab */
.closebtn {
float: right;
color: white;
font-size: 35px;
cursor: pointer;
}
.arrow-down {
width: 25px;
height: 25px;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="styles.css" />
<script src="index.js"></script>
</head>
<body>
<div style="text-align: center">
<h2>Expanding Grid</h2>
<p>Click on the boxes below:</p>
</div>
<!-- Four columns -->
<div class="row">
<div id="banking-tab" class="column" onclick="onExpandFuncs('b1');">
<img src="./Icons/Banking.svg" />
<p>Banking</p>
<img class="arrow-down" src="./Icons/arrow-down.png" />
</div>
<div id="regtech-tab" class="column" onclick="onExpandFuncs('b2');">
<img src="./Icons/Regtech.svg" />
<p>RegTech</p>
<img class="arrow-down" src="./Icons/arrow-down.png" />
</div>
<div id="insurtech-tab" class="column" onclick="onExpandFuncs('b3');">
<img src="./Icons/InsurTech.svg" />
<p>InsurTech</p>
<img class="arrow-down" src="./Icons/arrow-down.png" />
</div>
<div id="lending-tab" class="column" onclick="onExpandFuncs('b4');">
<img src="./Icons/Lending.svg" />
<p>Lending</p>
<img class="arrow-down" src="./Icons/arrow-down.png" />
</div>
</div>
<!-- Full-width columns: (hidden by default) -->
<div id="b1" class="containerTab" style="display: none; background: black">
<span onclick="this.parentElement.style.display='none'" class="closebtn"
>×</span
>
<h3>Banking</h3>
<p>
Lorem ipsum dolor sit amet, te quo doctus abhorreant, et pri deleniti
intellegat, te sanctus inermis ullamcorper nam. Ius error diceret
deseruisse ad
</p>
</div>
<div
id="b2"
class="containerTab"
style="display: none; background: lightgrey"
>
<span onclick="this.parentElement.style.display='none'" class="closebtn"
>×</span
>
<h2>RegTech</h2>
<p>
Lorem ipsum dolor sit amet, te quo doctus abhorreant, et pri deleniti
intellegat, te sanctus inermis ullamcorper nam. Ius error diceret
deseruisse ad
</p>
</div>
<div
id="b3"
class="containerTab"
style="display: none; background: lightgrey"
>
<span onclick="this.parentElement.style.display='none'" class="closebtn"
>×</span
>
<h2>InsurTech</h2>
<p>
Lorem ipsum dolor sit amet, te quo doctus abhorreant, et pri deleniti
intellegat, te sanctus inermis ullamcorper nam. Ius error diceret
deseruisse ad
</p>
</div>
<div
id="b4"
class="containerTab"
style="display: none; background: lightgrey"
>
<span onclick="this.parentElement.style.display='none'" class="closebtn"
>×</span
>
<h2>Lending</h2>
<p>
Lorem ipsum dolor sit amet, te quo doctus abhorreant, et pri deleniti
intellegat, te sanctus inermis ullamcorper nam. Ius error diceret
deseruisse ad
</p>
</div>
<!-- Bottom four columns -->
<div class="row">
<div class="column" onclick="openTab('b5');">
<img src="./Icons/Accounting.svg" />
<p>Accounting</p>
<img class="arrow-down" src="./Icons/arrow-down.png" />
</div>
<div class="column" onclick="openTab('b6');">
<img src="./Icons/Payments.svg" />
<p>Payments</p>
<img class="arrow-down" src="./Icons/arrow-down.png" />
</div>
<div class="column" onclick="openTab('b7');">
<img src="./Icons/Quote.svg" />
<p>Quote Aggregators</p>
<img class="arrow-down" src="./Icons/arrow-down.png" />
</div>
<div class="column" onclick="openTab('b8');">
<img src="./Icons/WealthTech.svg" />
<p>WealthTech</p>
<img class="arrow-down" src="./Icons/arrow-down.png" />
</div>
</div>
<div
id="b5"
class="containerTab"
style="display: none; background: lightgrey"
>
<span onclick="this.parentElement.style.display='none'" class="closebtn"
>×</span
>
<h2>Accounting</h2>
<p>
Lorem ipsum dolor sit amet, te quo doctus abhorreant, et pri deleniti
intellegat, te sanctus inermis ullamcorper nam. Ius error diceret
deseruisse ad
</p>
</div>
<div
id="b6"
class="containerTab"
style="display: none; background: lightgrey"
>
<span onclick="this.parentElement.style.display='none'" class="closebtn"
>×</span
>
<h2>Payments</h2>
<p>
Lorem ipsum dolor sit amet, te quo doctus abhorreant, et pri deleniti
intellegat, te sanctus inermis ullamcorper nam. Ius error diceret
deseruisse ad
</p>
</div>
<div
id="b7"
class="containerTab"
style="display: none; background: lightgrey"
>
<span onclick="this.parentElement.style.display='none'" class="closebtn"
>×</span
>
<h2>Quote</h2>
<p>
Lorem ipsum dolor sit amet, te quo doctus abhorreant, et pri deleniti
intellegat, te sanctus inermis ullamcorper nam. Ius error diceret
deseruisse ad
</p>
</div>
<div
id="b8"
class="containerTab"
style="display: none; background: lightgrey"
>
<span onclick="this.parentElement.style.display='none'" class="closebtn"
>×</span
>
<h2>WealthTech</h2>
<p>
Lorem ipsum dolor sit amet, te quo doctus abhorreant, et pri deleniti
intellegat, te sanctus inermis ullamcorper nam. Ius error diceret
deseruisse ad
</p>
</div>
</body>
</html>
Any help would be really appreciated!
All you need to do is loop over all the tab elements and set up a click handler on the each that will set the background color of this, which will represent the element that is handling the event. No need to know or use an id (which should be avoided when possible as their use creates brittle code).
Also don't use .getElementsByClassName().
I've removed all the onclick attributes that aren't relevant to this question to avoid errors from their callbacks not being included in the code here.
// Get all the tabs into a collection
// (don't use .getElementsByClassName()!)
let tabs = document.querySelectorAll(".column");
// Loop over all the tabs
tabs.forEach(function(tab){
// Set up a click event handler on each of the tabs
tab.addEventListener("click", function(event){
// Loop over all the tabs and remove the active class
tabs.forEach(function(tab){
tab.classList.remove("active-column");
});
// Set the background of the clicked tab
this.classList.add("active-column");
});
});
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: Arial, Helvetica, sans-serif;
}
/* The grid: Four equal columns that floats next to each other */
.column {
background-color: black;
float: left;
width: 25%;
height: 226px;
padding: 50px;
text-align: center;
font-size: 16px;
cursor: pointer;
color: white;
}
.active-column {
background-color: green;
float: left;
width: 25%;
height: 226px;
padding: 50px;
text-align: center;
font-size: 16px;
cursor: pointer;
color: white;
}
.containerTab {
padding: 20px;
color: white;
}
/* Clear floats after the columns */
.row:after {
content: '';
display: table;
clear: both;
}
/* Closable button inside the container tab */
.closebtn {
float: right;
color: white;
font-size: 35px;
cursor: pointer;
}
.arrow-down {
width: 25px;
height: 25px;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="styles.css" />
<script src="index.js"></script>
</head>
<body>
<div style="text-align: center">
<h2>Expanding Grid</h2>
<p>Click on the boxes below:</p>
</div>
<!-- Four columns -->
<div class="row">
<div id="banking-tab" class="column">
<img src="./Icons/Banking.svg" />
<p>Banking</p>
<img class="arrow-down" src="./Icons/arrow-down.png" />
</div>
<div id="regtech-tab" class="column">
<img src="./Icons/Regtech.svg" />
<p>RegTech</p>
<img class="arrow-down" src="./Icons/arrow-down.png" />
</div>
<div class="column">
<img src="./Icons/InsurTech.svg" />
<p>InsurTech</p>
<img class="arrow-down" src="./Icons/arrow-down.png" />
</div>
<div class="column">
<img src="./Icons/Lending.svg" />
<p>Lending</p>
<img class="arrow-down" src="./Icons/arrow-down.png" />
</div>
</div>
<!-- Full-width columns: (hidden by default) -->
<div id="b1" class="containerTab" style="display: none; background: black">
<span onclick="this.parentElement.style.display='none'" class="closebtn"
>×</span
>
<h3>Banking</h3>
<p>
Lorem ipsum dolor sit amet, te quo doctus abhorreant, et pri deleniti
intellegat, te sanctus inermis ullamcorper nam. Ius error diceret
deseruisse ad
</p>
</div>
<div
id="b2"
class="containerTab"
style="display: none; background: lightgrey"
>
<span class="closebtn"
>×</span
>
<h2>RegTech</h2>
<p>
Lorem ipsum dolor sit amet, te quo doctus abhorreant, et pri deleniti
intellegat, te sanctus inermis ullamcorper nam. Ius error diceret
deseruisse ad
</p>
</div>
<div
id="b3"
class="containerTab"
style="display: none; background: lightgrey"
>
<span class="closebtn"
>×</span
>
<h2>InsurTech</h2>
<p>
Lorem ipsum dolor sit amet, te quo doctus abhorreant, et pri deleniti
intellegat, te sanctus inermis ullamcorper nam. Ius error diceret
deseruisse ad
</p>
</div>
<div
id="b4"
class="containerTab"
style="display: none; background: lightgrey"
>
<span class="closebtn"
>×</span
>
<h2>Lending</h2>
<p>
Lorem ipsum dolor sit amet, te quo doctus abhorreant, et pri deleniti
intellegat, te sanctus inermis ullamcorper nam. Ius error diceret
deseruisse ad
</p>
</div>
<!-- Bottom four columns -->
<div class="row">
<div class="column" >
<img src="./Icons/Accounting.svg" />
<p>Accounting</p>
<img class="arrow-down" src="./Icons/arrow-down.png" />
</div>
<div class="column" >
<img src="./Icons/Payments.svg" />
<p>Payments</p>
<img class="arrow-down" src="./Icons/arrow-down.png" />
</div>
<div class="column" >
<img src="./Icons/Quote.svg" />
<p>Quote Aggregators</p>
<img class="arrow-down" src="./Icons/arrow-down.png" />
</div>
<div class="column" >
<img src="./Icons/WealthTech.svg" />
<p>WealthTech</p>
<img class="arrow-down" src="./Icons/arrow-down.png" />
</div>
</div>
<div
id="b5"
class="containerTab"
style="display: none; background: lightgrey"
>
<span onclick="this.parentElement.style.display='none'" class="closebtn"
>×</span
>
<h2>Accounting</h2>
<p>
Lorem ipsum dolor sit amet, te quo doctus abhorreant, et pri deleniti
intellegat, te sanctus inermis ullamcorper nam. Ius error diceret
deseruisse ad
</p>
</div>
<div
id="b6"
class="containerTab"
style="display: none; background: lightgrey"
>
<span onclick="this.parentElement.style.display='none'" class="closebtn"
>×</span
>
<h2>Payments</h2>
<p>
Lorem ipsum dolor sit amet, te quo doctus abhorreant, et pri deleniti
intellegat, te sanctus inermis ullamcorper nam. Ius error diceret
deseruisse ad
</p>
</div>
<div
id="b7"
class="containerTab"
style="display: none; background: lightgrey"
>
<span onclick="this.parentElement.style.display='none'" class="closebtn"
>×</span
>
<h2>Quote</h2>
<p>
Lorem ipsum dolor sit amet, te quo doctus abhorreant, et pri deleniti
intellegat, te sanctus inermis ullamcorper nam. Ius error diceret
deseruisse ad
</p>
</div>
<div
id="b8"
class="containerTab"
style="display: none; background: lightgrey"
>
<span onclick="this.parentElement.style.display='none'" class="closebtn"
>×</span
>
<h2>WealthTech</h2>
<p>
Lorem ipsum dolor sit amet, te quo doctus abhorreant, et pri deleniti
intellegat, te sanctus inermis ullamcorper nam. Ius error diceret
deseruisse ad
</p>
</div>
</body>
</html>
You are trying to work with two different elements.
Hence, you need to pass two different id's in click function. Something like below
function onExpandFuncs(tabName, clickedTab) {
openTab(tabName);
genericStyleTab(clickedTab);
}
function genericStyleTab(clickedTab) {
document.getElementById(clickedTab).classList.add('active-column');
}
<div id="banking-tab" class="column" onclick="onExpandFuncs('b1', 'banking-tab');">
Please take a look at next link:
http://bootsnipp.com/snippets/ORaWE
What I want to do (and don't know how to achieve it) is to keep active avatar always in center. For example, if 3rd avatar is active, 3rd avatar will be in center (position 2), 1st avatar will be on position 3 and 2nd avatar will be on position 1.
Here is a small graphic demonstration:
(Imagin this as 3 avatars. Green one is currenlty active)
Anyone can help me or at least give me an idea or direction? :)
To achieve this behavior in bootstrap carousel you need to use javascript functionality of carousel instead of the inline data-* attributes.
Here is the working example of what you need -
$(document).ready(function() {
var flag = false;
$("#quote-carousel").on('slide.bs.carousel', function() {
if (!flag) {
var arr = $('ol.carousel-indicators > li');
$($('ol.carousel-indicators')).append($('ol.carousel-indicators > li')[0]);
$('.carousel-inner').append($('.carousel-inner > .item')[0]);
} else {
flag = false;
}
});
$('#quote-carousel').carousel();
$('.item-btn').click(function(obj) {
flag = true;
var arr = $('.item-btn');
var index = arr.index(obj.currentTarget);
var len = arr.length;
var mid = Math.floor(len / 2);
$('#quote-carousel').carousel(index);
if (index < mid) {
for (i = 0; i < (mid - index); i++) {
$($('ol.carousel-indicators')).prepend($('.item-btn')[len - 1]);
$('.carousel-inner').prepend($('.item')[len - 1]);
}
} else if (index > mid) {
for (i = 0; i < (index - mid); i++) {
$($('ol.carousel-indicators')).append($('.item-btn')[0]);
$('.carousel-inner').append($('.item')[0]);
}
}
});
$(".left").click(function() {
flag = true;
var arr = $('ol.carousel-indicators > li');
$($('ol.carousel-indicators')).prepend(arr[arr.length - 1]);
arr = $('.carousel-inner > .item');
$('.carousel-inner').prepend(arr[arr.length - 1]);
$("#quote-carousel").carousel("prev");
});
$(".right").click(function() {
flag = true;
var arr = $('ol.carousel-indicators > li');
$($('ol.carousel-indicators')).append(arr[0]);
arr = $('.carousel-inner > .item');
$('.carousel-inner').append(arr[0]);
$("#quote-carousel").carousel("next");
});
});
/* Carousel */
#quote-carousel {
padding: 0 10px 30px 10px;
margin-top: 30px;
/* Control buttons */
/* Previous button */
/* Next button */
/* Changes the position of the indicators */
/* Changes the color of the indicators */
}
#quote-carousel .carousel-control {
background: none;
color: #CACACA;
font-size: 2.3em;
text-shadow: none;
margin-top: 30px;
}
#quote-carousel .carousel-control.left {
left: -60px;
}
#quote-carousel .carousel-control.right {
right: -60px;
}
#quote-carousel .carousel-indicators {
right: 50%;
top: auto;
bottom: 0px;
margin-right: -19px;
}
#quote-carousel .carousel-indicators li {
width: 50px;
height: 50px;
margin: 5px;
cursor: pointer;
border: 4px solid #CCC;
border-radius: 50px;
opacity: 0.4;
overflow: hidden;
transition: all 0.4s;
margin-bottom: 45px;
}
#quote-carousel .carousel-indicators .active {
background: #333333;
width: 128px;
height: 128px;
border-radius: 100px;
border-color: #f33;
opacity: 1;
overflow: hidden;
margin-bottom: 5px;
}
.carousel-inner {
min-height: 300px;
margin-bottom: 50px;
}
.item blockquote {
border-left: none;
margin: 0;
}
.item blockquote p:before {
content: "\f10d";
font-family: 'Fontawesome';
float: left;
margin-right: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css" rel="stylesheet"/>
<div class="container">
<div class="row">
<div class="col-md-12" data-wow-delay="0.2s">
<div class="carousel slide" id="quote-carousel">
<!-- Bottom Carousel Indicators -->
<ol class="carousel-indicators">
<li class="item-btn"><img class="img-responsive " src="https://s3.amazonaws.com/uifaces/faces/twitter/brad_frost/128.jpg" alt="">
</li>
<li class="item-btn active"><img class="img-responsive" src="https://s3.amazonaws.com/uifaces/faces/twitter/rssems/128.jpg" alt="">
</li>
<li class="item-btn"><img class="img-responsive" src="https://s3.amazonaws.com/uifaces/faces/twitter/adellecharles/128.jpg" alt="">
</li>
</ol>
<!-- Carousel Slides / Quotes -->
<div class="carousel-inner text-center">
<!-- Quote 1 -->
<div class="item">
<blockquote>
<div class="row">
<div class="col-sm-8 col-sm-offset-2">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis
aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. !</p>
<small>Someone famous</small>
</div>
</div>
</blockquote>
</div>
<!-- Quote 2 -->
<div class="item active">
<blockquote>
<div class="row">
<div class="col-sm-8 col-sm-offset-2">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis
aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. </p>
<small>Someone famous</small>
</div>
</div>
</blockquote>
</div>
<!-- Quote 3 -->
<div class="item">
<blockquote>
<div class="row">
<div class="col-sm-8 col-sm-offset-2">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis
aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. .</p>
<small>Someone famous</small>
</div>
</div>
</blockquote>
</div>
</div>
<!-- Carousel Buttons Next/Prev -->
<i class="fa fa-chevron-left"></i>
<i class="fa fa-chevron-right"></i>
</div>
</div>
</div>
</div>
working fiddle here
function showAvatar(){
var no_of_avatars=3;
var data=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
var start_index=10;
var msg='Start : ';
start_index=start_index-Math.floor(no_of_avatars/2)+data.length;
for(i=0;i<no_of_avatars;i++)
{
$('#content-id').append('start_index+i : '+(start_index+i)+'<br>');
msg+=','+data[((start_index+i)%data.length)];
}
$('#content-id').append(msg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button onclick="showAvatar()">click to execute</button>
<div id="content-id">
</div>
This might help you. This is just the login with which you can have data in center but in case if your count of avatars are not odd then it will not generate perfect result though only small change will be required.
When you hover over a green highlight, a div of colors will appear. This will allow you to change the color of the highlight. By the way, the SO Editor is making the offset measure incorrect for the #change_color div. How can I make it where, unless the mouse is over .green_mark or #change_color, #change_color has its visibility hidden?
$(".green_mark").mouseover(function() {
var offsets = $(this).offset();
var top = offsets.top;
var new_top = top - 10;
var left = offsets.left;
var new_left = left - 10;
$("#change_color").css("visibility","visible");
$('#change_color').css({
'top':new_top+'px',
'left':new_left+'px'
});
});
#change_color {
position:absolute;
border:grey solid 1px;
background: #373737;
padding: 5px;
border-radius: 3px;
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Chrome/Safari/Opera */
-khtml-user-select: none; /* Konqueror */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently
not supported by any browser */
visibility: hidden;
}
.blue_mark {
background: #AAF6FF;
cursor: pointer;
}
.red_mark {
background: #FF9B9F;
cursor: pointer;
}
.green_mark {
background: #D6FFAA;
cursor: pointer;
}
.yellow_mark {
background: #FFF8AA;
cursor: pointer;
}
.orange_mark {
background: #FFBF98;
cursor: pointer;
}
.purple_mark {
background: #D7D5FC;
cursor: pointer;
}
.boxes, .boxes2 {
width: 15px;
height: 15px;
cursor: pointer;
display: inline-block;
margin-right: 2px;
position: relative;
top: 3px;
}
#blue_box2 {
background: #AAF6FF;
}
#green_box2 {
background: #D6FFAA;
}
#orange_box2 {
background: #FFBF98;
}
#purple_box2 {
background: #D7D5FC;
}
#red_box2 {
background: #FF9B9F;
}
#yellow_box2 {
background: #FFF8AA;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span id='actual_verse' class='context'>
Lore
<span class="orange_mark">
m ipsum dolor sit amet, iisque scripserit nec at, an case ponderum mea, delectus volupt
</span>
aria in quo. Te aliquid ce
<span class="red_mark">
teros legendos has. Veritus assueverit intelleg
</span>
eba
<span class="orange_mark">
t id per
</span>
, eos cu vero pri
<span class="green_mark">
mis philo
</span>
sophia, no nec blandit propriae
<span class="green_mark">
. Mei stet ferri aperiri eu. Mucius deserunt sensibus eum id.
Ut cas
</span>
e nominavi pro,
<span class="yellow_mark">
dico reprimique suscipiantur in per. Cu vocibus ceteros sententiae mel. Nam te diam ornatus, mei sonet volutpat facilisis ut. Minim mazim persequeri
</span>
s sed id, mei et animal equidem, clita atomorum at has.
<span class="green_mark">
Ut noluisse placerat suscipiantur mel
</span>
, cu pri mundi dicunt
<span class="green_mark">
praesent. Ignota dicunt vulputate ad vim,
</span>
populo option aperiri
<span class="orange_mark">
me
</span>
<span class="purple_mark">
l in. Has cu essent eirmod malorum, nisl electram pri et.
In legimus posidonium his, aeque possit platonem vel ne, nam ad meis nemore delenit. Cu discere legimus eam. Eum eius nostro ad, pro solet semper per
</span>
<span class="orange_mark">
fe
</span>
cto ne, et eros dicam tantas pro. Ex malorum debitis cotidieque pro. Vel in legendos elaboraret conclusionemque, mutat moderatius cotidieque cu usu, mel copiosae assueverit ne. Odio imperdiet eos in, cum sint porro splendide ne, tritani aliquam eum ne.
Mel feugiat recusabo platonem ei, sea cu numquam constituam. Ne tempor postea vim. Ad volumus accumsan apeirian has. At ius aliquid convenire, id est aliquip vivendo accusam.
Solum scaevola ius ut, cum no mutat sadipscing. Mei te dico dolor scaevola, cu veri dictas sit, an per nullam oblique. Ex sit sale quidam reprehendunt, diam velit lucilius nam ne, mnesarchum efficiendi his ut. Nec vivendo mediocrem delicatissimi id, ad debet maiorum qui. No qui latine dolorum corpora, diam cetero insolens in cum.
</span>
<div id='change_color'>
<div id='blue_box2' class='boxes2' title='Blue'></div>
<div id='green_box2' class='boxes2' title='Green'></div>
<div id='yellow_box2' class='boxes2' title='Yellow'></div>
<div id='orange_box2' class='boxes2' title='Orange'></div>
<div id='purple_box2' class='boxes2' title='Purple'></div>
<div id='red_box2' class='boxes2' title='Red'></div>
</div>
You can subscribe to mouseenter and mouseleave events.
var colorPickerHovered = false;
var timer;
$(".green_mark").mouseenter(function() {
if(timer){
clearTimeout(timer);
}
var offsets = $(this).offset();
var top = offsets.top;
var new_top = top - 10;
var left = offsets.left;
var new_left = left - 10;
$("#change_color").css("visibility","visible");
$('#change_color').css({
'top':new_top+'px',
'left':new_left+'px'
});
});
$(".green_mark").mouseleave(function(){
timer = setTimeout(function(){
if(!colorPickerHovered){
$("#change_color").css("visibility","hidden");
}
}, 250)
})
$("#change_color").mouseenter(function(){
colorPickerHovered = true;
})
$("#change_color").mouseleave(function(){
colorPickerHovered = false;
$(this).css("visibility","hidden");
})
jsfiddle example
Use the mouseout event:
$(".green_mark").mouseout(function() {
$("#change_color").css("visibility","hidden");});
If you mouseout from the green to get to the color div, it will go wrong though, so make sure the position error is fixed so you never leave the green to go over the color div (so the color div is close by enough); you could render the color div at the mouse position to fix that part too.
I have a problem with a text: cannot wrap anything except div children.
Here is my problem:
- I use PHPBB forum. Comments texts not wrap any container, I have just plain text.
- I need text-indent to every paragraph
- Comments text include img, strong and many html tags, include divs (like quotes).
What I think, I'd like:
- wrap text to a span (because I can use inline-block indent) with any html tag, exclude div
- delete duplicated br tags, just use one br tag only
I made two way for solution, but have a few problem with these solutions.
HTML code:
<div class="postbody" id="postdiv24216">Itt van a sima szöveg, ami jó hosszú és ezt kellene spanba zárni
<div class="quotetitle">valaki írta:</div>
<div class="quotecontent">
<div class="quotetitle">Másvalaki írta:</div>
<div class="quotecontent">No <strong>meg ezt</strong> sem...
<br />
<!-- m --> <a class="postlink" href="http://m.youtube.com/watch?v=Dp_nePvLZQ0&feature=youtu.be&desktop_uri=%2Fwatch%3Fv%3DDp_nePvLZQ0%26feature%3Dyoutu.be">http://m.youtube.com/watch?v=Dp_nePvLZQ ... 3Dyoutu.be</a>
<!-- m -->
</div>
<br />Ez tök jó! ez idézet</div>
<br />Ez is tuti! <strong>Ez nem idézet</strong>, ezt is spanolni kell.
<br />
<br />
<br />Lorem Ipsum constituam ad; Illum philosophia accusata id solum vocent
oportere corrumpit habemus donec minim offendit tritani tempus risus
sociis maecenas? Usu maiestatis exerci pellentesque exerci! Essent;
Sea intellegebat suspendisse puto ctas? Oblique? Solum elit mundi libris
aliquet similique dolore sapientem interdum dis elaboraret volutpat
diam interdum agam docendi primis.
<br />
Lorem Ipsum expetenda etiam! Voluptua pellentesque cu feugiat intellegat
ignota. Autem saperet percipitur voluptua omnis conceptam epicuri
eligendi option aliquyam impedit nam scelerisque semper integer postea
homero ultrices curae adipisci soluta pericula quo? Sint! Puto deseruisse
diceret eripuit atqui assentior pulvinar altera posidonium detracto,
tractatos? Constituam dicat convallis perpetua fastidii</div>
CSS code:
.postbody {
padding: 5px 15px;
text-align: justify;
}
.quotetitle {
margin: 10px 5px 0 5px;
padding: 4px;
border-width: 1px 1px 0 1px;
border-style: solid;
border-color: #A9B8C2;
color: #333333;
background-color: #A9B8C2;
font-size: 0.85em;
font-weight: bold;
}
.quotecontent {
margin: 0 5px 10px 5px;
padding: 5px;
border-color: #A9B8C2;
border-width: 0 1px 1px 1px;
border-style: solid;
font-weight: normal;
font-size: 1em;
line-height: 1.4em;
font-family:"Lucida Grande", "Trebuchet MS", Helvetica, Arial, sans-serif;
background-color: #FAFAFA;
color: #4B5C77;
}
.firstline {
text-indent: 1.1em;
display:inline-block;
}
JQuery code (First solution): http://jsfiddle.net/mykee/9VpjP/29/
$('.postbody').each(function(){
var container = $(this);
container.contents().filter(function() {
return this.nodeType == 8;
}).remove();
$("div.quotecontent br").remove();
if (container.filter("div", "a")){
var html = container.html().split('<br>');
container.html("");
for(var i in html)
{
if($.trim(html[i]))
container.append('<p class="gensmall"><span class="firstline">'+html[i]+"</span></p>");
}
// $(".firstline > a").unwrap();
$(".firstline > div").unwrap();
}
});
JQuery code (Second solution): http://jsfiddle.net/mykee/2AByk/12/
$('.postbody')
.contents()
.filter(function () {
return this.nodeType === 3;
})
.wrap(function () {
return $("<span>").addClass("firstline");
})
.end();
$("span.firstline div").unwrap();
$("span.firstline").filter(function () {
return $.trim($(this).html()) === '';
}).remove();
$('.postbody br').each(function () {
if ($(this).next().is('br')) {
$(this).next('br').remove();
$(this).next('br').remove();
}
});
My problem with first solution: split working with all content, and trim my div. If div include any br tag, then div container will wrong after unwrap. I put a remove to div for br tag, but this not solution :(
With second solution my problem is with filter nodeType: just plain text will wrapped to span, img or strong or any other html tag will outside span.
I need this results:
<div class="postbody" id="postdiv24216">
<p class="gensmall"><span class="firstline">Itt van a sima szöveg, ami jó hosszú és ezt kellene spanba zárni</span></p>
<div class="quotetitle">valaki írta:</div>
<div class="quotecontent">
<div class="quotetitle">Másvalaki írta:</div>
<div class="quotecontent">No <strong>meg ezt</strong> sem...
<br />
<!-- m --> <a class="postlink" href="http://m.youtube.com/watch?v=Dp_nePvLZQ0&feature=youtu.be&desktop_uri=%2Fwatch%3Fv%3DDp_nePvLZQ0%26feature%3Dyoutu.be">http://m.youtube.com/watch?v=Dp_nePvLZQ ... 3Dyoutu.be</a>
<!-- m -->
</div>
<br />Ez tök jó! ez idézet</div>
<p class="gensmall"><span class="firstline">Ez is tuti! <strong>Ez nem idézet</strong>, ezt is spanolni kell.</span></p>
<p class="gensmall"><span class="firstline">Lorem Ipsum constituam ad; Illum philosophia accusata id solum vocent
oportere corrumpit habemus donec minim offendit tritani tempus risus
sociis maecenas? Usu maiestatis exerci pellentesque exerci! Essent;
Sea intellegebat suspendisse puto ctas? Oblique? Solum elit mundi libris
aliquet similique dolore sapientem interdum dis elaboraret volutpat
diam interdum agam docendi primis.</span></p>
<p class="gensmall"><span class="firstline">Lorem Ipsum expetenda etiam! Voluptua pellentesque cu feugiat intellegat
ignota. Autem saperet percipitur voluptua omnis conceptam epicuri
eligendi option aliquyam impedit nam scelerisque semper integer postea
homero ultrices curae adipisci soluta pericula quo? Sint! Puto deseruisse
diceret eripuit atqui assentior pulvinar altera posidonium detracto,
tractatos? Constituam dicat convallis perpetua fastidii</span></p>
</div>
What's hard: this one post, and I have more post on one page. I use now first solution, but not a better.
How can I except any div in div.postbody, but wrap and indent first line on other texts?
You could apply padding-left to the entire .postbody, and then use negative margins to move the quotes to the left. That would give you a pure CSS solution.
http://jsfiddle.net/9VpjP/28/
The relevant changes are:
.quotetitle {
margin: 10px 5px 0 -20px;
}
.quotecontent {
margin: 0 5px 10px -20px;
}
.quotecontent .quotecontent,
.quotecontent .quotetitle {
margin-left: 5px;
}
.postbody {
padding-left: 20px;
}
In this case I've applied 20px padding/margin.
Tested only in Chrome.
I'm not familiar with phpbb so I can't promise this solution won't interfere with your broader layout, but with a bit of tweaking it should be solid.