I am making a page where there should be content on the left side and commercials in divs on the right side. The height of the left sides div is unknown. I want to add as many commercial divs as possible on the right side without making the height of the right side taller than the left side.
I have set the right sides div height equal to left sides height and then I have added overflow: hidden on the right sides div so that the commercial divs are being cut off. I don't want my commercial divs to be cut off so I would like to remove the one that is being cut off.
Here is my code https://jsfiddle.net/p9dmzoa3/
You can try below code, this will remove all those commercials DIV, which are getting cut-off :
$(document).ready(function() {
$(".right_side").css("height", $(".left_side").height());
$commercialDivs = $(".right_side").children("div.commercials");
$rightSideDivHeight = $(".right_side").height();
$tempHeight = 0;
for(var i=0;i<$commercialDivs.length;i++){
$tempHeight += $commercialDivs[i].clientHeight;
if($tempHeight>$rightSideDivHeight){
$commercialDivs[i].remove();
}
}
});
Something like this should do the thing.
$(document).ready(function() {
$(".right_side").css("height", $(".left_side").height());
var j = $(".right_side").children("div").length;
for (var i = 1; i < j; i++) {
if ((($('.right_side').offset().top + $(".right_side").height()) - ($('.right_side div:last-child').offset().top + $(".right_side div:last-child").height())) < 0) {
$(".right_side div:last-child").remove();
} else {
break;
}
}
});
div.left_side {
display: inline-block;
}
div.right_side {
display: inline-block;
float: right;
overflow: hidden;
}
div.left_side_content {
height: 30px;
margin-top: 10px;
background-color: green;
}
div.commercials {
height: 50px;
margin-top: 10px;
background-color: forestgreen;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="content" style ="width: 430px; background-color: lightblue; padding: 5px;">
<div class="left_side" style ="width: 200px; background-color: tomato; padding: 5px;">
<div class="left_side_content">content</div>
<div class="left_side_content">content</div>
</div>
<div class="right_side" style ="width: 200px; background-color: orange; padding: 5px;">
<div class="commercials">commercials</div>
<div class="commercials">commercials</div>
<div class="commercials">commercials</div>
<div class="commercials">commercials</div>
<div class="commercials">commercials</div>
<div class="commercials">commercials</div>
</div>
</div>
Related
The following code contains 2 buttons and their respective drop-down contents.
When I click the first button, the other moves by itself. How do I stop this from happening?
var coll = document.getElementsByClassName("button");
var i;
for (i = 0; i < coll.length; i++) {
coll[i].addEventListener("click", function() {
this.classList.toggle("active");
var content = this.nextElementSibling;
if (content.style.display === "block")
content.style.display = "none";
else
content.style.display = "block";
});
}
.content {
display: none;
}
<button type="button" class="button" style="position: static; left: 100;">For Copper Rollers</button>
<div class="content" style=" width: 48%; background-color: lightblue; padding: 10px; border-radius: 10px; margin-right: 5px; ">
</div>
<button class="button" type="button" style="position: static; left: 175px; ">For Rubber Rollers</button>
<div class="content" style="margin-left:50%; float: left; width: 48%; background-color: lightblue; padding: 10px; border-radius: 10px;">
</div>
If you assign position:absolute you can do some rudimentary calculations in Javascript to determine the position the content should appear at. Is this more or less the desired effect?
document.querySelectorAll('button').forEach(( bttn, index )=>bttn.addEventListener('click',function(e){
this.classList.toggle("active");
// get the bounding box for the button so we can
// get a suitable height offset for content
let bb=this.getBoundingClientRect();
// find the content and toggle display state
let div=this.nextElementSibling;
div.style.display=div.style.display=='block' ? 'none' : 'block';
// find the current style properties for the content
let style=getComputedStyle( div );
let bbd=div.getBoundingClientRect();
// calculate x / y positions for content
let x=( Math.ceil( bbd.width ) + parseInt( style.paddingLeft ) - parseInt( style.marginLeft ) ) * index;
let y=Math.ceil( bb.height ) + Math.ceil( bb.bottom );
// apply those positions to the content
div.style.top=`${y}px`;
div.style.left=`${x}px`;
// identify content by parent
div.textContent=this.textContent.replace('For ','');
}));
body{
width:100%;
height:100vh;
}
button.button{
padding:0.25rem;
}
/*
assign the absolute position
to the content divs but let
javascript calculate x/y positions.
*/
.content {
position:absolute;
display: none;
width: calc( 50% - 3rem );
background-color:lightblue;
padding:1rem;
border-radius:10px;
border:1px solid grey;
float:none;
clear:none;
margin:0 0.25rem;
}
.content:first-of-type{
background:pink;
}
.active{
color:green
}
<!--
let css do the styling and positioning as `inline` styles
make updating a pain in the proverbial
-->
<button type="button" class="button">For Copper Rollers</button>
<div class="content"></div>
<button class="button" type="button">For Rubber Rollers</button>
<div class="content"></div>
I would go with making the dropdown content have a position: asolute (css), that way it won't affect any other elements on the page.
PS: make sure to keep accessibility in mind when making dropdowns, your current snippet unfortunately isn't.
I'm trying to create a text changing animation in which four words cycle through a fixed underlined space. I've gotten the text changing piece done using a simple js script, but I'm having trouble positioning the underline. I've tried using hr to no avail and I've gotten close using an inline svg, however I can't figure out how to position the SVG so that it's underneath the text. I've tried adjusting the position in CSS using the SVG id and I've also tried adjusting the position of the SVG directly in the svg code.
var text = ["Repurposed", "Remnant ", "Scrap", "Upcycled "];
var counter = 0;
var elem = $("#greeting");
setInterval(change, 3000);
function change() {
elem.fadeOut(function(){
elem.html(text[counter]);
counter++;
if(counter >= text.length) { counter = 0; }
elem.fadeIn();
});
}
#layer_1 {
display: block;
padding-bottom: 20%;
padding-top: 0;
text-align: right;
margin-left: 40%;
margin-top: 0;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
<div class="col-6">
<div class="text-change" id='greeting'>Upcycled</div>
<div class="liner">
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400.52 4.84"><defs><style>.cls-1{fill:none;stroke:#fff;stroke-miterlimit:10;stroke-width:3px; padding-left: 25%;}</style></defs><line class="cls-1" y1="2.84" x2="200.51" y2="2"/></svg>
</div>
</div>
<div class="col-6">
<div class="text-change-right">Materials</div>
</div>
</div>
Probably not what you are after... but when I see jQuery, I try to write something without
var titles = ["Repurposed", "Remnant", "Scrap", "Upcycled"];
var div = document.querySelector(".greeting div:first-child");
setInterval(change, 200);
function change() {
titles.unshift(div.innerHTML = titles.pop());// pop last title, insert at front
}
.greeting {
width: 50vw;
font:30px Arial;
}
.greeting div {
background: pink;
text-align: center;
}
.greeting div:first-child {
border-bottom: 1px solid green;
}
<div class="greeting">
<div>Upcycled</div>
<div>Materials</div>
</div>
Here's a method using real underlines.
The underline is extended by using the ::after pseudo-element to add non-breaking whitespace after the text. To make the underline look fixed-width, we turn off text wrapping, and ensure any extra spaces are hidden using overflow: hidden.
You just need to make sure you include enough \0000a0 (non-breaking space) characters to ensure the text overflows the column. If that seems a bit ugly, you could perhaps try stretching the spaces horizontally instead using one of the techniques in this question.
var text = ["Repurposed", "Remnant ", "Scrap", "Upcycled "];
var counter = 0;
var elem = $("#greeting");
setInterval(change, 3000);
function change() {
elem.fadeOut(function(){
elem.html(text[counter]);
counter++;
if(counter >= text.length) { counter = 0; }
elem.fadeIn();
});
}
body {
font-size: 36px;
}
.row {
display: flex;
}
.col-6 {
width: 300px;
}
.text-change-container {
overflow: hidden;
}
.text-change {
display: inline;
text-decoration: underline;
white-space: nowrap;
}
.text-change::after {
display: inline;
content: '\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0';
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
<div class="col-6 text-change-container">
<div class="text-change" id='greeting'>Upcycled</div>
</div>
<div class="col-6">
<div class="text-change-right">Materials</div>
</div>
</div>
I want to transition the background colour of a fixed header element on scroll. So as a user scrolls down a full page block website, the header subtly changes to complement the block colours. I have almost achieved this on a Pen, however I can't quite work out how to measure how much has been scrolled as a flag for when to change.
Some extra info: The scroll amount to change at is 400px. The background colours are stored and fetched in an array. For reference my jQuery code is below:
$(document).ready(function(){
var bgArray = ["#252525","#333333","#454545","#777777"];
var scrollHeight = 400;
var scrolled = $(window).scrollTop(); //What is this measuring?
$(window).scroll(function() { //Can these conditions be neatened into one function?
if(scrolled < scrollHeight) {
$('header').css('background', bgArray[0]);
}
if(scrolled > scrollHeight) { // i.e more than 400px
$('header').css('background', bgArray[1]);
}
// and so on (800, 1200...)
})
})
Please refer to the Pen for full code. Any suggestions are greatly appreciated!
Updated Solution (2019)
To set a background for the header based on the current block in view below the header while scrolling:
because header has fixed position, we can get the amount by which window has scrolled by using $header.offset().top,
(index of the current block in view) is the ratio of (the amount by which window has scrolled) to the (height of each block),
now adjusting for the height of the header, the index of the current block in view is Math.floor(($header.offset().top + headerHeight) / sectionHeight).
See simplified demo below:
$(function() {
var $header = $('header'),
$window = $(window),
bgArray = ["#252525", "red", "blue", "green"],
headerHeight = 50,
sectionHeight = 400;
$window.scroll(function() {
$header.css('background', bgArray[Math.floor(($header.offset().top + headerHeight)
/ sectionHeight)]);
});
});
:root {
--header: 50px; /* header height */
--block: 400px; /* block height */
}
* {
box-sizing: border-box; /* include padding in width / height calculations */
}
body {
margin: 0; /* reset default margin of body */
}
header {
height: var(--header); /* sets height of header */
position: fixed;
top: 0;
left: 0;
width: 100%;
color: #FFF;
padding: 12px 0;
background: #252525; /* initial background */
transition: background 1s ease;
}
.container {
margin: 0 auto;
}
.wrap>div {
height: var(--block); /* sets height of each block */
text-align: center;
}
p {
margin: 0; /* reset margin of p */
}
.block-1 {
background: #27AACC;
color: #FFF;
}
.block-2 {
background: #668E99;
color: #FFF;
}
.block-3 {
background: #4AFFC1;
color: #444;
}
.block-4 {
background: #FF8F8A;
color: #FFF;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>
<div class="container">
Website Title.
</div>
</header>
<div class="wrap">
<div class="block-1">
<div class="container">
<p>This pen was made to solve a problem on a project...</p>
</div>
</div>
<div class="block-2">
<div class="container">
<p>...I needed a sticky header with thr right bg colour.</p>
</div>
</div>
<div class="block-3">
<div class="container">
<p>But this conflicted with the footer, which was the same colour...</p>
</div>
</div>
<div class="block-4">
<div class="container">
<p>So the solution was to subtley change the header's bg on scroll</p>
</div>
</div>
</div>
Original Solution
Check the top of each block with respect to how much the window has been scrolled (scrollTop) using $(window).scrollTop() > $('.block-1').offset().top. So now we can use this to change color on entering the block - see demo below:
$(document).ready(function() {
var $header = $('header'),
$window = $(window),
bgArray = ["#252525", "#333333", "#454545", "#777777"],
headerHeight = $header.outerHeight();
$window.scroll(function() {
for (var i = 1; i < 5; i++) {
if ($window.scrollTop() + headerHeight > $('.block-' + i).offset().top) {
$header.css('background', bgArray[i - 1]);
}
}
});
});
#import url('https://fonts.googleapis.com/css?family=Roboto:300,400,700');
body {
font-family: 'Roboto', sans-serif;
font-size: 30px;
font-weight: 300;
margin-top: 0;
}
header {
width: 100%;
height: 50px;
line-height: 50px;
position: fixed;
font-size: 24px;
font-weight: 700;
color: #FFF;
padding: 12px 0;
margin: 0;
background: #252525;
transition: background 1s ease;
}
.wrap {
padding-top: 74px;
margin: 0;
}
.container {
width: 960px;
margin: 0 auto;
overflow: hidden;
}
.block-1,
.block-2,
.block-3,
.block-4 {
height: 400px;
text-align: center;
}
p {
margin-top: 185px;
}
.block-1 {
background: #27AACC;
color: #FFF;
}
.block-2 {
background: #668E99;
color: #FFF;
}
.block-3 {
background: #4AFFC1;
color: #444;
}
.block-4 {
background: #FF8F8A;
color: #FFF;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>
<div class="container">
Website Title.
</div>
</header>
<div class="wrap">
<div class="block-1">
<div class="container">
<p>This pen was made to solve a problem on a project...</p>
</div>
</div>
<div class="block-2">
<div class="container">
<p>...I needed a sticky header with thr right bg colour.</p>
</div>
</div>
<div class="block-3">
<div class="container">
<p>But this conflicted with the footer, which was the same colour...</p>
</div>
</div>
<div class="block-4">
<div class="container">
<p>So the solution was to subtley change the header's bg on scroll</p>
</div>
</div>
</div>
Note that this solution needlessly loops through the sections on each scroll update called by the browser - and I don't like the look of it.
you are using scrolled as a fixed variable you should use it directly in your condition
this will make it dynamic for all elements inside wrap div
$(document).ready(function(){
var bgArray = ["#252525","#333333","#454545","#777777"];
$(window).scroll(function() {
for(var i = 1; i < bgArray.length; i++) {
if ($(window).scrollTop() > $('.wrap div:nth-child(' + i + ')').offset().top) {
$('header').css('background', bgArray[i-1]);
}
}
});
})
Try Like this:
$(document).ready(function(){
var bgArray = ["#252525","#333333","#454545","#777777"];
var scrollHeight = 400;
$(window).scroll(function() {
var scrolled = $(window).scrollTop();
var index=Number((scrolled/scrollHeight).toFixed());
if(bgArray[index]!=undefined)
$('header').css('background', bgArray[index]);
});
})
This is current scroll, so it should be inside: $(window).scrollTop()
I have this code.
<div class="mes-all">
<div class="mes" id="1">test1</div>
</div>
<button id="add">Send</button>
And on every submit some .mes divs prepending to .mes-all div.But I want it not scroll auto,I want it maintain position same as before prepending divs above.
I have looked for solution in even this site,but couldn't find.
I can't control height() or scrollTop(), I don't know this functions very well,that's why I can't figure out the problem.
I have jsfiddle https://jsfiddle.net/83xq3b3L/
js:
var $elem = $('#list');
var height = $elem.height();
$("#add").on("click",function(){
var id=parseInt($(".mes:first").attr("id"))+1;
$(".mes-all").prepend('<div class="mes" id="'+id+'">test'+id+'</div>');
height+=30;
$(".mes-all").animate({scrollTop: height+"px"});
});
HTML:
<div id = "list" class="mes-all">
<div class="mes" id="1">test1</div>
</div>
<button id="add">Send</button>
One approach is to get the scrollHiehgt of the parent div and then scrollTop to that height.
So you code might look like this:
$("#add").on("click", function() {
var id = parseInt($(".mes:first").attr("id")) + 1;
$(".mes-all").prepend('<div class="mes" id="' + id + '">test' + id + '</div>');
var divHiehgt = $('.mes-all')[0].scrollHeight;
$('.mes-all').scrollTop(divHiehgt);
});
.mes-all {
overflow: auto;
height: 300px;
border: 1px solid;
}
.mes {
height: 30px;
padding: 5px;
border: 1px solid red;
text-align: center;
vertical-align: middle;
padding-top: 15px;
background: #ebebeb;
}
button {
width: 100%;
height: 50px;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="mes-all">
<div class="mes" id="1">test1</div>
</div>
<button id="add">Send</button>
Or jsFiddle:
https://jsfiddle.net/j8jaz10k/1/
I have something like the below:
<div id="left">
left
</div>
<div id="right">
right
</div>
With .css properties:
#left {
width: 60%;
float: left
min-height: ###
max-height: 1000px;
}
#right {
width: 40%;
float: right;
min-height: ###
max-height: 1000px;
}
Notice the ### for both <div> CSS min-height properties. I'd like something like the below (some pseudo JS):
var leftheight = document.getElementById(left);
var rightheight = document.getElementById(right);
if (leftheight.currentHeight > rightheight.currentHeight) {
rightheight.style.min-height = leftheight.currentHeight;
} else if (rightheight.currentHeight > leftheight.currentHeight) {
leftheight.style.min-height = rightheight.currentHeight;
}
Basically I want:
if (current height of left > current height of right) {
min-height of right = current height of left
} else if (current height of right > current height of left) {
min-height of left = current height of right
}
//ie. both left and right have the same min-heights, whichever is larger
My Javascript is wrong, and it's something I'm learning just now. Is there a method I can use to get my desired results?
You can do this:
if (leftheight.currentHeight > rightheight.currentHeight) {
rightheight.style.minHeight = leftheight.currentHeight;
} else if (rightheight.currentHeight > leftheight.currentHeight) {
leftheight.style.minHeight = rightheight.currentHeight;
}
It's actually minHeight not min-height.
There is no need for javascript here, you can achieve this by adding a container with overflow: hidden and adding positive and negative margins to the left and right divs:
<div id="container">
<div id="left">left</div>
<div id="right">right<br /><br /><br /><br />Foobar</div>
</div>
#container {
width: 75%; /* amend this as required */
overflow: hidden;
}
#left {
width: 60%;
float: left;
max-height: 1000px;
background-color: #C00;
padding-bottom: 1000px;
margin-bottom: -1000px;
}
#right {
width: 40%;
float: right;
max-height: 1000px;
background-color: #0C0;
padding-bottom: 1000px;
margin-bottom: -1000px;
}
Example fiddle
As a rule, javascript should never be used solely for layout purposes. What would happen to your page if someone has javascript turned off?
you can use jquery
var leftheight = $('#left').height();
var rightheight =$('#right').height();
if (leftheight > rightheight) {
$('#right').css('min-height',leftheight+"px")
}
else if (rightheight > leftheight) {
$('#left').css('min-height',rightheight + "px")
}
using jquery
$(function(){ //ready function to make sure document is ready
var $leftdiv=$('#left'),
$rightdiv=$('#right'),
$leftHeight=$('#left').height(),
$rightHeight=$('#right').height();
if ( $leftHeight > $rightHeight) {
$rightdiv.css('min-height':$leftHeight + "px");
} else if ( $rightHeight > $leftHeight) {
$leftdiv.css('min-height':$rightHeight + "px");
}
});