I'm trying to change the css position from fixed to static and viceversa, based on pixel scrolled...
The script works fine as espected, but at the point to change css position, there is a sort of lag.
If i scroll slow till at the point of switch, from the console i see the position switch fast from fixed to static and from static to fixed.
Anyway, look in the snippet, scroll near the end, and see what happen... I'm not able to figure out the reason. Hope in your help! Thanks!
Open the snipped in fullscreen to see better!
$(window).scroll(function() {
var scrolled = $(window).scrollTop();
var add_px = $('body').height();
var px_scroll = scrolled + add_px;
var tot = $(document).height();
var ftr = $('#footer').css("margin-bottom");
ftr = ftr.replace('px','');
ftr = ftr.replace('-','');
var total = tot - ftr;
if ( px_scroll > total ) {
$('#act_btns').css({'position':'static'});
} else {
$('#act_btns').css({'position':'fixed'});
}
});
html, body { height: 100%; margin:0; padding: 0; }
#main_container {
position: relative;
width: 100%;
height: auto;
min-height: 100%;
text-align: center;
}
#act_btns {
position: fixed;
margin: 0 auto;
left: 0;
right: 0;
bottom: 50px;
}
#act_btns input {
color: #fff;
border: 0px;
width: 100px;
height: 40px;
margin: 0 5px;
box-shadow: 0 0 5px 5px #000;
}
#footer {
position: absolute;
bottom: 0;
margin-bottom: -200px;
width: 100%;
background: rgba(0, 0, 0, 0.8);
padding: 10px 7px 15px 7px;
box-sizing: border-box;
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<html>
<body>
<div id="main_container">
<div style="position:relative;margin:0 auto 20px;width:80%;height:2500px;background:#ccc;"></div>
<div id="act_btns">
<input type="submit" name="save_list" id="save_btn" value="Salva">
<input type="submit" name="reset_list" id="rst_btn" value="Reset">
</div>
<div id="footer"><p id="copyright">Copyright © 2016 - 2021</p></div>
</div>
</body>
</html>
The problem you are facing is: You calculate the total value on every change of the scroll position. So when you scroll and change the position of the element from fixed to static you will add the height (60px) to total. (This is visible if you console.log(scrolled, total)). Because fixed position elements do not take up any space.
The most simple fix is to calculate the total when the page is loaded. And then, if it doesn't change you're good to go with that height forever. So the only change I did from your code is to move the calculation of total outside of the scroll function.
var tot = $(document).height();
var ftr = $('#footer').css("margin-bottom");
ftr = ftr.replace('px','');
ftr = ftr.replace('-','');
var total = tot - ftr;
$(window).scroll(function() {
var scrolled = $(window).scrollTop();
var add_px = $('body').height();
var px_scroll = scrolled + add_px;
if ( px_scroll > total ) {
$('#act_btns').css({'position':'static'});
} else {
$('#act_btns').css({'position':'fixed'});
}
});
html, body { height: 100%; margin:0; padding: 0; }
#main_container {
position: relative;
width: 100%;
height: auto;
min-height: 100%;
text-align: center;
}
#act_btns {
position: fixed;
margin: 0 auto;
left: 0;
right: 0;
bottom: 50px;
}
#act_btns input {
color: #fff;
border: 0px;
width: 100px;
height: 40px;
margin: 0 5px;
box-shadow: 0 0 5px 5px #000;
}
#footer {
position: absolute;
bottom: 0;
margin-bottom: -200px;
width: 100%;
background: rgba(0, 0, 0, 0.8);
padding: 10px 7px 15px 7px;
box-sizing: border-box;
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<html>
<body>
<div id="main_container">
<div style="position:relative;margin:0 auto 20px;width:80%;height:2500px;background:#ccc;"></div>
<div id="act_btns">
<input type="submit" name="save_list" id="save_btn" value="Salva">
<input type="submit" name="reset_list" id="rst_btn" value="Reset">
</div>
<div id="footer"><p id="copyright">Copyright © 2016 - 2021 VirtualCode.Net</p></div>
</div>
</body>
</html>
This could lead to some problems if you are loading images and what not which may take up more space (height) when completely loaded and the calculation already happened. To never face that issue you can wrap the calculation inside
$(window).load(function(){
// add total calculation code here
});
Related
I'm having a hard time figuring out why the code below doesn't work as expected.
What I'm trying to achieve is same functionality with position:sticky whereas when the scrolled reaches the top of the #second-header then fixes its position below the #header which is also fixed, however, the height of the #header is unknown which is I believe can be calculated using the function outerHeight(true) on JQuery.
Then after reaching out to the bottom of the #second-header-container, remove the fixed position of #second-header turning it back to normal position.
Due to browser compatibility issues and other customization, I cannot simply use the position:sticky of css.
It looks like my logic is wrong, and I need help.
jQuery(document).ready(function(){
var $document = jQuery(document);
var header = jQuery('#header');
var second_header = jQuery('#second-header-container').find('#second-header');
var second_header_container = jQuery('#second-header-container');
var second_header_offset = second_header.offset().top;
var second_header_container_offset = second_header_container.offset().top;
jQuery(window).scroll(function(){
var top_margin = header.outerHeight(true);
var second_header_height = second_header.outerHeight(true);
var second_header_container_height = second_header_container.outerHeight(true);
if( jQuery(window).scrollTop() > (second_header_offset - second_header_height) && jQuery(window).scrollTop() < second_header_container_height) {
second_header.addClass('fixer');
second_header.css({position:'fixed', top:top_margin, 'z-index':'999999'});
} else {
second_header.removeClass('fixer');
second_header.css({position:'relative', top:'0px', 'z-index':'0'});
}
});
});
*{
color: #FFFFFF;
padding: 0;
margin: 0;
}
.fixer{
position: fixed;
width: 100%;
}
#header, .banner, #second-header, .contents{
padding: 5px;
}
#header{
position: fixed;
width: 100%;
height: 74px;
z-index: 99999;
background-color: #000000;
}
.banner{
padding-top: 84px;
height: 200px;
background-color: #583E5B;
}
#second-header-container{
min-height: 300px;
background-color: #775F5E;
}
#second-header{
padding-bottom: 10px;
padding-top: 10px;
background-color: #4C3D3C;
}
.contents{
min-height: 200px;
background-color: #97A36D;
}
.footer{
background-color: #80A379;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header id="header">HEADER</header>
<div class="banner">BANNER</div>
<div id="second-header-container">
<div id="second-header">SECOND-HEADER</div>
<!--Other contents and elements...-->
</div>
<div class="contents">OTHER...</div>
<footer class="contents footer">FOOTER</footer>
To achieve this you need first check if the scroll height is near the second div header and within the height of the second div. Then add a class that make it stick below the main header. I have created a sticky class and added it while scrolling conditions are met.
Please check below code
jQuery(document).ready(function() {
var headerHeight = $('#header').outerHeight(true);
var secondHeaderContainer = $('#second-header-container');
const secondHeaderTopPos = secondHeaderContainer.offset().top;
const secondHeaderContainerHeight = $(secondHeaderContainer).height();
$(window).scroll(function() {
const scrollTop = $(this).scrollTop();
const secondContainerHeightEnd = secondHeaderContainerHeight + secondHeaderTopPos - $('#second-header').height() - headerHeight;
if (((secondHeaderTopPos - headerHeight) <= scrollTop) && (secondContainerHeightEnd >= scrollTop)) {
$('#second-header').addClass('sticky').css('top', headerHeight);
} else {
$('#second-header').removeClass('sticky');
}
});
});
* {
color: #FFFFFF;
padding: 0;
margin: 0;
}
.sticky {
position: fixed;
width: 100%;
top: 0;
left: 0;
}
.fixer {
position: fixed;
width: 100%;
}
#header,
.banner,
#second-header,
.contents {
padding: 5px;
}
#header {
position: fixed;
width: 100%;
height: 74px;
z-index: 99999;
background-color: #000000;
}
.banner {
padding-top: 84px;
height: 200px;
background-color: #583E5B;
}
#second-header-container {
min-height: 300px;
background-color: #775F5E;
}
#second-header {
padding-bottom: 10px;
padding-top: 10px;
background-color: #4C3D3C;
}
.contents {
min-height: 200px;
background-color: #97A36D;
}
.footer {
background-color: #80A379;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header id="header">HEADER</header>
<div class="banner">BANNER</div>
<div id="second-header-container">
<div id="second-header">SECOND-HEADER</div>
<!--Other contents and elements...-->
</div>
<div class="contents">OTHER...</div>
<footer class="contents footer">FOOTER</footer>
I made a copy of JSbin for practice, JSbin link here, actual site link here.
This is just a practice for making the front-end of websites as I just started learning web dev little over a week ago. You can put in html, css and javascript in the editboxes, and a page spit out in Output just like the actual JSbin.
But the problem is that you can resize the divs pass other divs.
My idea to prevent this from happening is:
1. get the editboxes' current positions
2. store the left/right position of the editbox if resized to 10% window width
3. set the min/max left and right for the draggable div
And hence the question. How do I set the max-left/right for the draggable.
Also, any idea on why the draggable before Output div is diificult to drag to the right.
Edit: How the site is structured. When you drag the .drag (.resize in my JSbin code), it changes its left and right div's left and right. And the draggables are contained in the #main's div.
<div id="main>
<div id="HTML"></div>
<div class="drag"></div> //drag this left and right to change the right of the HTML and left of CSS
<div id="CSS"></div>
<div class="drag"></div> //drag this left and right to change the right of the Css and left of JavaScript
<div id="JavaScript"></div>
<div class="drag"></div> //drag this left and right to change the right of the JavaScript and left of Output
<div id="Output"></div>
</div>
By taking advantage of jQuery Ui's built in draggable event which gives us position information and also allows us to set position on drag.
I came up with the following solution:
var dragDistance = 100;
$(".resize").draggable({
axis: "x",
containment: "parent",
drag: function( event, ui){
ui.position.left = Math.min( ui.position.left, ui.helper.next().offset().left + ui.helper.next().width()-dragDistance);
ui.position.left = Math.max(ui.position.left, ui.helper.prev().offset().left + dragDistance);
resize();
}
});
I removed your onDrag function in the process so it wouldn't interfere.
See the bin here:
JSBin
NOTES:
I haven't looked into it and maybe its just a JSBin issue because I can't reproduce it in your live site. But if the boundary lines disappear while you are dragging the code won't work. You'll probably have to increase the drag distance to the point where the lines don't disappear while dragging.
You may notice you have difficulty dragging the Output box that seems to be caused by the Iframe you have inside. If I comment out the IFrame I can drag it just fine. I haven't looked for a solution but perhaps experiment with some padding or margins so that the Iframe is not pegged so closely against the border. Or maybe if you detached it from the DOM while dragging that would fix it.
Use containment
Constrains dragging to within the bounds of the specified element or
region.
For Eg:
$( ".selector" ).draggable({
containment: "parent"
});
Click Here For a Demo
You could manually keep track of the position of each of the windows in the dragging() function, and only call the resize() method if they don't overlap:
function dragging(event) {
var CSS_left = parseInt($("#CSS").css("left"));
var JavaScript_left = parseInt($("#JavaScript").css("left"));
var Output_left = parseInt($("#Output").css("left"));
var offset = 100;
var checkOverlap1 = $(event.target).is("#1")
&& event.clientX + offset <= JavaScript_left
&& event.clientX >= offset;
var checkOverlap2 = $(event.target).is("#2")
&& event.clientX + offset <= Output_left
&& event.clientX - offset >= CSS_left;
var checkOverlap3 = $(event.target).is("#3")
&& event.clientX - offset >= JavaScript_left
&& event.clientX <= codeboxWidth - offset;
if (checkOverlap1 || checkOverlap2 || checkOverlap3) {
resize(event);
}
}
Here's the complete example - I also refactored/simplified your "resize" function.
var codeboxWidth = $("#codebox").width();
$(document).ready(function() {
$("#codebox").height($(window).height() - $("#topbar").height());
$(".content").height($("#codebox").height());
$(".editbox").height($(".content").height() - $(".contentheader").height());
$("#HTML").css("left", 0);
$("#HTML").css("right", "75%");
$("#CSS").css("left", "25%");
$("#CSS").css("right", "50%");
$("#JavaScript").css("left", "50%");
$("#JavaScript").css("right", "25%");
$("#Output").css("left", "75%");
$("#Output").css("right", 0);
});
function resize(event) {
if ($(event.target).is("#1")) {
$("#CSS").css("left", event.clientX);
$("#HTML").css("right", codeboxWidth - event.clientX);
}
if ($(event.target).is("#2")) {
$("#JavaScript").css("left", event.clientX);
$("#CSS").css("right", codeboxWidth - event.clientX);
}
if ($(event.target).is("#3")) {
$("#Output").css("left", event.clientX);
$("#JavaScript").css("right", codeboxWidth - event.clientX);
}
}
$(".resize").draggable({
axis: "x"
});
function dragging(event) {
var CSS_left = parseInt($("#CSS").css("left"));
var JavaScript_left = parseInt($("#JavaScript").css("left"));
var Output_left = parseInt($("#Output").css("left"));
var offset = 100;
var checkOverlap1 = $(event.target).is("#1")
&& event.clientX + offset <= JavaScript_left
&& event.clientX >= offset;
var checkOverlap2 = $(event.target).is("#2")
&& event.clientX + offset <= Output_left
&& event.clientX - offset >= CSS_left;
var checkOverlap3 = $(event.target).is("#3")
&& event.clientX - offset >= JavaScript_left
&& event.clientX <= codeboxWidth - offset;
if (checkOverlap1 || checkOverlap2 || checkOverlap3) {
resize(event);
}
}
body {
margin: 0;
padding: 0;
overflow-y: hidden;
overflow-x: hidden;
background: #F7F7F7;
font-family: Arial;
}
#topbar {
margin: 0;
padding: 0;
width: 100%;
height: 35px;
background: #EEEEEE;
position: relative;
}
h2 {
margin: 2px 0 0 0;
padding: 0;
float: left;
position: absolute;
}
#control {
width: 100%;
margin: 8px 0 0 0;
padding: 0;
position: absolute;
text-align: center;
}
.option {
margin: 0 -5px 0 0;
padding: 5px 10px 5px 10px;
text-align: center;
border-top: 1px solid #CCC;
border-bottom: 1px solid #CCC;
border-left: 1px solid #CCC;
text-decoration: none;
font-size: 0.9em;
color: black;
}
.option:first-child {
border-bottom-left-radius: 5px;
border-top-left-radius: 5px;
}
.option:last-child {
border-right: 1px solid #CCC;
border-bottom-right-radius: 5px;
border-top-right-radius: 5px;
}
.option:hover {
background: #dee5e5;
}
.opactive {
background: #EBF3FF;
}
.opinactive {
background: 0;
}
.active {
display: block;
}
.inactive {
display: none;
}
#codebox {
margin: 0;
padding: 0 width: 100%;
position: static;
top: 35px;
background: white;
}
.content {
margin: 0;
padding: 0;
min-width: 10%;
max-width: 100%;
position: absolute;
float: left;
color: #6DCAFC;
background: #F7F7F7;
overflow: hidden;
}
.resize {
top: 35px;
bottom: 0px;
width: 1px;
margin-left: 0;
height: 100%;
right: auto;
opacity: 0;
position: absolute;
cursor: ew-resize;
border-left-width: 1px;
border-left-style: solid;
border-left-color: rgba(218, 218, 218, 0.498039);
z-index: 99999;
background: #666;
}
.contentheader {
margin: 0;
padding: 0;
background: transparent;
position: relative;
}
.selectedcontent {
background: white;
}
.contentbox {
width: 100%;
height: 100%;
background: transparent;
position: relative;
box-sizing: border-box;
border-right: 1px solid darkgrey;
overflow: hidden;
}
.editbox {
width: 100%;
height: 100%;
background: transparent;
overflow: hidden;
}
.textareabox {
background: transparent;
min-width: 100%;
max-width: 100%;
min-height: 100%;
max-height: 100%;
border: none;
outline: none;
resize: none;
}
<!DOCTYPE html>
<html>
<head>
<title>Project 04</title>
<link rel="stylesheet" type="text/css" href="styles.css">
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
</head>
<body>
<div id="topbar">
<h2>Code Runner</h2>
<div id="control">
HTML
CSS
JavaScript
Output
</div>
</div>
<div id="codebox">
<div id="HTML" class="content active">
<div class="contentbox">
<div class="contentheader">HTML</div>
<div class="editbox" id="HTMLeditbox">
<textarea id="HTMLcode" class="textareabox"></textarea>
</div>
</div>
</div>
<div class="resize active" id="1" style="left: 25%" ondrag="dragging(event)"></div>
<div id="CSS" class="content active">
<div class="contentbox">
<div class="contentheader">CSS</div>
<div class="editbox" id="CSSeditbox">
<textarea id="CSScode" class="textareabox"></textarea>
</div>
</div>
</div>
<div class="resize active" id="2" style="left: 50%" ondrag="dragging(event)"></div>
<div id="JavaScript" class="content active">
<div class="contentbox">
<div class="contentheader">JavaScript</div>
<div class="editbox" id="JavaScripteditbox">
<textarea id="JavaScriptcode" class="textareabox"></textarea>
</div>
</div>
</div>
<div class="resize active" id="3" style="left: 75%" ondrag="dragging(event)"></div>
<div id="Output" class="content active">
<div class="contentbox">
<div class="contentheader">Output</div>
<div class="editbox" id="Outputbox">
</div>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script type="text/javascript" src="jscript.js"></script>
</body>
</html>
Here's a JSBin based on your example.
I have a form that I am using to calculate the sum and average of an array of numbers. I am using a button to trigger the form to appear and then users can add extra input fields to enter as many values as they wish. When they click the 'Calc' button, they receive an alert of the sum and average. This much is working fine. The problem is when I click the trigger again to close and then to reopen the form, the same number of input fields as the user selected appear and, despite having been able to clear their values, I have not been able to empty the associated array. Thus, when the user inputs values the second time and attempts to perform the calculation, the previous values are being added to these new ones.
On top of this, I would like for the the dynamically added inputs to appear one on top of the other and for the '.remove-field' div (or at least the icon it contains) to appear to the right of each input field. I have tried various display values, positioning, etc. but nothing seems to produce a consistent look.
Here is my HTML markup:
<button class="form-launch" data-icon="">AVG</button>
<div class="form-space">
<form role="form" action="/wohoo" method="POST" class="form-add-remove">
<label class="label">Average Calculation</label>
<div id="horizontal_bar"></div>
<div class="multi-field-wrapper">
<div class="add-field"><i class="fa fa-plus-circle"></i></div>
<div class="multi-fields">
<div class="multi-field">
<input type="text" name="stuff[]" class="input-field"/>
<div class="remove-field"><i class="fa fa-minus-circle"></i></div>
</div>
</div>
</div>
<button type="button" class="check">Calc</button>
</form>
</div>
My CSS:
.form-launch {
position: absolute;
top: 20px;
left: 20px;
}
.form-space {
opacity: 0;
}
.form-add-remove {
font-family: "DJB Chalk It Up";
color: #FFF;
font-size: 30px;
width: 600px;
height: 300px;
padding: 20px;
border: 2px solid #FFF;
border-radius: 25px;
box-shadow: 0px 0px 10px 5px #000;
background: transparent url("http://mrlambertsmathpage.weebly.com/files/theme/blackboard.jpeg") repeat-y scroll left center;
text-align: center;
vertical-align: middle;
display: inline-flex;
-moz-box-pack: center;
justify-content: center;
align-items: center;
-moz-box-orient: vertical;
opacity: 1;
position: absolute;
top: 50%;
left: 50%;
margin-left: -300px;
margin-top: -125px;
display: inline-block;
}
.label {
position: absolute;
top: 20px;
left: 20px;
}
#horizontal_bar {
position: absolute;
top: 60px;
left: 0px;
width: 95%;
height: 4px;
border-radius: 2px;
background: #00A2E8 none repeat scroll 0% 0%;
margin: 2.5%;
box-shadow: 0px 0px 6px 3px #000, 0px 0px 1px #000 inset;
}
.multi-field-wrapper {
height: 130px;
width: 90%;
padding: 20px;
margin-left: 0px;
margin-top: 80px;
border: 2px dashed rgba(255, 255, 255, 0.1);
border-radius: 10px;
transition: all 1.5s ease-in-out 0.5S;
overflow-y: scroll;
}
.multi-field-wrapper:hover {
border: 2px solid rgba(255, 255, 255, 0.1);
transition: all 1.5s ease-in-out 0s;
}
.multi-field {
display: inline-block;
}
.add-field {
position: absolute;
right: 20px;
bottom: 20px;
}
i {
color: #00a2e8;
}
.calc {
position: absolute;
left: 20px;
bottom: 20px;
}
input {
font-family: "Borders Divide, But Hearts Shall Conquer";
border-radius: 5px;
border: 2px inset rgba(0, 0, 0, 0.4);
width: 100px;
text-align: right;
padding-right: 10px;
}
And my jQuery:
var launchCount = 0;
var arr = [],
sum = 0;
$('.form-launch').click(function() {
launchCount++;
if ((launchCount % 2) == 1) {
$('.form-space').css('opacity', '1');
// Initialize Average Form
$('.multi-field-wrapper').each(function() {
var $wrapper = $('.multi-fields', this);
$(".add-field", $(this)).click(function(e) {
$('.multi-field:first-child', $wrapper).clone(true).appendTo($wrapper).find('input').val('').focus();
});
$('.multi-field .remove-field', $wrapper).click(function() {
if ($('.multi-field', $wrapper).length > 1)
$(this).parent('.multi-field').remove();
});
});
$(".calc").click(function() {
$("input[type=text]").each(function() {
arr.push($(this).val());
sum += parseInt($(this).val());
});
var n = arr.length;
var AVG = (sum / n);
alert(sum + "," + AVG);
});
// End Average Form
} else if ((launchCount % 2) == 0) {
$('.form-space').css('opacity', '0');
$('.form-add-remove').find("input[type=text]").val('');
if ($('.multi-field', $wrapper).length > 1) {
$(this).parent('.multi-field').remove(); // does not seem to work!
}
arr = []; // also does not seem to work
}
});
I have commented a few lines at the bottom of my jQuery to illustrate what I have tried. I also looked at setting the array length to 0, but I was not able to get that to work either.
Obviously, this is a work in progress. My jsfiddle is here: http://jsfiddle.net/e3b9bopz/77/
Can you try this?
$(".calc").click(function() {
$("input[type=text]").each(function() {
arr.push($(this).val());
sum += parseInt($(this).val());
});
var n = arr.length;
var AVG = (sum / n);
alert(sum + "," + AVG);
arr = []; # How about putting your reset here?
sum = 0; # reinitialized the sum
});
I think you need to reset the arr after you make a calculation.
Not exactly what you need, but move $(".check").click out of $('.form-launch').click, and wrap the whole thing in a jquery ready.
$(function() {
$(".check").click(function() {
$("input[type=text]").each(function() {
arr.push($(this).val());
sum += parseInt($(this).val());
});
var n = arr.length;
var AVG = (sum / n);
alert(sum + "," + AVG);
arr = [];
});
})
JSFiddle
I'm currently working on this small project that randomly displays a div (#box) of 100px width and height. I want this div to appear ONLY in another div (#boxBorder) so it appears to be limited to a specific area on the page.
Here is the content of my HTML:
<h1>Test your reactions!</h1>
<p id="directions">Click the shape as fast as you can!</p>
<p id="scoreC">Click score: <span id="cScore">0</span>s</p>
<p id="scoreT">Total score: <span id="tScore">0</span>s</p>
<div id="boxBorder"></div>
<div id="box"></div>
Here is the CSS:
#boxBorder {
height: 500px;
width: 500px;
margin: 20px auto;
left: 0;
right: 0;
background-color: white;
border: 1px black solid;
position: absolute;
z-index: 0;
}
#box {
margin: 0 auto;
height: 100px;
width: 100px;
background-color: red;
display: none;
border-radius: 50px;
position: relative;
z-index: 1;
}
h1 {
margin: 15px 0 0 0;
}
#directions {
margin: 0;
padding: 5px;
font-size: 0.8em;
}
#scoreT, #scoreC {
font-weight: bold;
margin: 10px 50px 0 0;
}
#tScore, #cScore {
font-weight: normal;
}
h1, #directions, #scoreT, #scoreC {
width: 100%;
text-align: center;
}
And lastly, the javascript function for random position:
//Get random position
function getRandomPos() {
var pos = Math.floor((Math.random() * 500) + 1);
console.log("POS: " + pos + "px");
return pos + "px";
}
Which I call within a timeout method:
setTimeout(function() {
createdTime = Date.now();
console.log("make box: " + createdTime);
document.getElementById("box").style.top=getRandomPos();
document.getElementById("box").style.left=getRandomPos();
document.getElementById("box").style.backgroundColor=getRandomColor();
document.getElementById("box").style.borderRadius=getRandomShape();
document.getElementById("box").style.display="block";
}, rTime);
I'm not very skilled in positioning and I can't seem to get these two divs to align so that the #box div can recognize the size of the #boxBorder div and stay within those limits. Any help would be appreciated!
Couple things wrong here:
You need the box div nested inside the borderBox div if you want to use the relative positioning.
<div id="boxBorder">
<div id="box"></div>
</div>
The randomPos function needs to take into account the size of the box, so only multiply by 400 instead of 500.
function getRandomPos() {
var pos = Math.floor((Math.random() * 400));
return pos + "px";
}
Set the style to inline-block, not block for the box.
Use setInterval instead of setTimeout to have it repeat.
var rTime = 1000;
function getRandomPos() {
var pos = Math.floor((Math.random() * 400));
console.log("POS: " + pos + "px");
return pos + "px";
}
function getRandomColor() {
return ['#bf616a', '#d08770', '#ebcb8b', '#a3be8c', '#96b5b4', '#8fa1b3', '#b48ead'][(Math.floor(Math.random() * 7))];
}
function randomizeBox() {
createdTime = Date.now();
console.log("make box: " + createdTime);
document.getElementById("box").style.top = getRandomPos();
document.getElementById("box").style.left = getRandomPos();
document.getElementById("box").style.backgroundColor = getRandomColor();
}
setInterval(randomizeBox, rTime);
#boxBorder {
height: 500px;
width: 500px;
margin: 20px auto;
left: 0;
right: 0;
background-color: white;
border: 1px black solid;
position: absolute;
z-index: 0;
}
#box {
margin: 0 auto;
height: 100px;
width: 100px;
border-radius: 50px;
position: relative;
z-index: 1;
display: inline-block;
}
h1 {
margin: 15px 0 0 0;
}
#directions {
margin: 0;
padding: 5px;
font-size: 0.8em;
}
#scoreT,
#scoreC {
font-weight: bold;
margin: 10px 50px 0 0;
}
#tScore,
#cScore {
font-weight: normal;
}
h1,
#directions,
#scoreT,
#scoreC {
width: 100%;
text-align: center;
}
<h1>Test your reactions!</h1>
<p id="directions">Click the shape as fast as you can!</p>
<p id="scoreC">Click score: <span id="cScore">0</span>s</p>
<p id="scoreT">Total score: <span id="tScore">0</span>s</p>
<div id="boxBorder">
<div id="box"></div>
</div>
I need a 'Page section' to stick in place for (x) amount of scrolling and then move onto the next section. I've tried putting them into the child theme but nothing... Can someone tell me a good way to do wthis that's not Javascript heavy?
CSS
.isSticky {
top: 0;
position: fixed;
}
HTML
<div>
<section id="top"></section>
<section id="test2"></section>
<section id="bottom"></section>
</div>
JS
$(document).ready(function () {
var el = $('#test2');
var elTop = el.position().top;
$(window).scroll(function () {
var windowTop = $(window).scrollTop();
if (windowTop >= elTop) {
el.addClass('isSticky');
} else {
el.removeClass('isSticky');
}
This answer might not be 100% pragmatic, due to current lack of support, but soon you will be able to use the position: sticky property of CSS, currently supported in Firefox and prefixed in Safari/iOS (Caniuse).
The feature was previously enabled in Chrome, but then subsequently removed in the interest of re-doing it more efficiently.
html, body {
margin: 0;
}
body * {
margin: 20px;
padding: 20px;
}
.header {
margin: 0;
padding: 20px;
background: #000;
}
.header span {
display: block;
color: #fff;
margin: 0 auto;
text-align: center;
padding: 0;
}
.placeholder {
border: 1px solid black;
margin: 0 auto;
text-align: center;
height: 300px;
}
.slider {
background: #006264;
color: white;
font-weight: bold;
margin: 0 auto;
position: sticky;
top: 0px;
}
<div class="header"><span>This is a header</span></div>
<div class="placeholder">This div holds place</div>
<div class="slider">This should slide up and then stick.</div>
<div class="placeholder">This div holds place</div>
<div class="placeholder">This div holds place</div>
<div class="placeholder">This div holds place</div>
<div class="placeholder">This div holds place</div>