Array in JavaScript is undefined - javascript

I am very new to JavaScript but have good experience with C and java. For whatever reason my code below will not fill in the array with values other than undefined. I'm trying to simply fill an array with a random set of numbers for a blackjack game
let randomSuite;
let randomNum
let count = 0;
var cards = new Array(56);
window.onload = function main(){
const suites = [
"H",
"D",
"S",
"C"
];
for(let i = 0 ; i < 56 ; i++){
randomNum = (Math.random * 12) + 1;
randomSuite = Math.random * 3;
cards.push = randomNum;
console.log(cards[i]);
count++;
}
alert(cards[1]);
}
function hitFunc(){
alert("works " + cards[0]);
}
*{
margin: 0;
padding : 0;
font-family: sans-serif;
}
.main{
width: 100%;
height: 100vh;
background-color:black;
}
.img1{
position: relative;
z-index: -1;
margin: 10px auto 20px;
display: block;
width: 75%;
height: 75%;
}
.img2{
position: relative;
z-index: 1;
margin: 10px auto 20px;
display: block;
bottom: 200px;
right: 400px;
width: 7%;
height: 7%;
}
.hitButton {
z-index: 1;
position: relative;
text-align: center;
left: 225px;
bottom: 550px;
}
.center {
display: block;
margin-left: auto;
margin-right: auto;
width: 50%;
color: aliceblue;
object-position: center;
}
Here's what I have. The alerts are used to show that the function is being completed. Any help is appreciated Please leave an explanation as well. This is my first post on stack overflow let me know if there's anyway to improve the quality of my post.

Math.random is a function; use Math.random()
Same for push, use cards.push(randomNum)
You were defining an array with 56 spots new array(56) but since you're using push you'll need to create an empty array so you're pussing to the desired index. Otherwise, instead of push, just set it on the index: cards[i] = randomNum
No need for the count variable since the loop iterator (i) has the same value
let randomSuite;
let randomNum
var cards = new Array();
window.onload = function main(){
const suites = [
"H",
"D",
"S",
"C"
];
for(let i = 0 ; i < 56 ; i++){
randomNum = (Math.random() * 12) + 1;
randomSuite = Math.random() * 3;
cards.push(randomNum);
}
console.log(cards)
}
*{
margin: 0;
padding : 0;
font-family: sans-serif;
}
.main{
width: 100%;
height: 100vh;
background-color:black;
}
.img1{
position: relative;
z-index: -1;
margin: 10px auto 20px;
display: block;
width: 75%;
height: 75%;
}
.img2{
position: relative;
z-index: 1;
margin: 10px auto 20px;
display: block;
bottom: 200px;
right: 400px;
width: 7%;
height: 7%;
}
.hitButton {
z-index: 1;
position: relative;
text-align: center;
left: 225px;
bottom: 550px;
}
.center {
display: block;
margin-left: auto;
margin-right: auto;
width: 50%;
color: aliceblue;
object-position: center;
}

Call functions with parenthesis
Math.random() and push() are functions not variables therefore you need to call them using ().
push() will append to the array
push() will append a value to the array. You already initialize an array with 10 values. Pushing new values will increase the array size but not add values in the first 10 spots.
const array = new Array(10);
for(let i = 0; i < 10; i++){
array.push(i);
}
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Solution
You should instead use array[i] = value; to set a value on a given position.
const array = new Array(10);
for(let i = 0; i < 10; i++){
array[i] = i;
}
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
If you want to have a more functional way of doing this as is typical for JavaScript you could use map():
const array = [...new Array(10)].map((_, index) => index);
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Related

"Progress" bar with both value and acceptable ranges

Here is exhaustive topic on SO about how to create progress bar. I would like to improve this "widget" to display acceptable range markers. It may be vertical lines or something else.
For example, value range may be [-50;50], but acceptable range is [-25;25]. So can someone point me out how to modify, for example, the first answer from topic mentioned above to get what I described here.
Here is first suggested answer from the topic:
#progressbar {
background-color: black;
border-radius: 13px;
/* (height of inner div) / 2 + padding */
padding: 3px;
}
#progressbar>div {
background-color: orange;
width: 40%;
/* Adjust with JavaScript */
height: 20px;
border-radius: 10px;
}
<div id="progressbar">
<div></div>
</div>
Here is how I see my widget. Red parts of bar - acceptable range.
Clarification
So firstly, as mentioned in my comment, this doesn't really sound like a progress bar. As implied by the name, progress bars are meant to show progress, and so things like negative values don't make sense.
It sounds like you want something like the HTML Range Input, though you mentioned you only want to display data (which you could still technically do by setting the disabled attribute on a range input).
Possible Solution
Ultimately it looks like you just want CSS to display a range (not a progress bar). This can be achieved with pure CSS, but I should mention there are a few quirks based on the requirements you have outlined.
You could set all the values by hand, based on whatever range and value you wish to display, but I assume this isn't desirable. So the next thing to do would be to utilize CSS variables and the CSS calc() function to set everything for you (based on some initial data).
The one weird thing is displaying the text for things like the range and values. Because we are using CSS variables to hold our values and perform calculations, it would be nice to use those same values to display the text. But CSS variables cannot be converted between types and so a value of say 2 is a number (not text or a string), and this means the value of 2 cannot be displayed as text using the CSS content property. Because of this I have 2 sets of variables. The first set is the number, used for calculations to set the widths. The second set is the -text version, used to display the text under your range bar.
.rangeBar {
background: #EEE;
height: 2em;
padding: .2em;
border: 1px solid #CCC;
border-radius: 1em;
box-sizing: border-box;
position: relative;
--min-value: 0;
--min-value-text: '0';
--max-value: 4.5;
--max-value-text: '4.5';
--min-range: 1;
--min-range-text: '1';
--max-range: 3;
--max-range-text: '3';
--value: 2;
--value-text: '2';
}
.rangeBar::before {
content: var(--min-value-text);
position: absolute;
top: 100%;
left: 0;
color: #888;
}
.rangeBar::after {
content: var(--max-value-text);
position: absolute;
top: 100%;
right: 0;
color: #888;
}
.rangeBar .value {
background: #0A95FF;
width: calc(var(--value)/var(--max-value)*100%);
height: 100%;
border-radius: 1em;
position: relative;
z-index: 1;
}
.rangeBar .value::after {
content: var(--value-text);
position: absolute;
top: 100%;
right: 0;
color: #888;
}
.rangeBar .minRange {
background: #E74C3C;
width: calc(var(--min-range)/var(--max-value)*100%);
height: 100%;
border-radius: 1em;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
position: absolute;
top: 0;
left: 0;
z-index: 2;
}
.rangeBar .minRange::after {
content: var(--min-range-text);
position: absolute;
top: 100%;
right: 0;
color: #888;
}
.rangeBar .maxRange {
background: #E74C3C;
width: calc((var(--max-value) - var(--max-range))/var(--max-value)*100%);
height: 100%;
border-radius: 1em;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
position: absolute;
top: 0;
right: 0;
z-index: 2;
}
.rangeBar .maxRange::after {
content: var(--max-range-text);
position: absolute;
top: 100%;
left: 0;
color: #888;
}
<div class="rangeBar">
<div class="minRange"></div>
<div class="value"></div>
<div class="maxRange"></div>
</div>
Additional Notes
There are possibly a few ways to simplify the CSS for this and automatically take care of some of the issues with this, but would require JavaScript (which is outside of the scope of this question). There has been no indication as to how any of the data or values for this range bar will be set, and so JavaScript was avoided for this question.
EDIT
Because OP updated the original question to include JavaScript, I am adding an additional solution. This mostly works the same but instead uses a JavaScript function called _CreateRange that takes 5 parameters (min value, max value, min range, max range, and value) and creates a new element on the page that uses those parameters/values. This makes things a little simpler as you only need to enter those values once (rather than once for the number value and once for the text value) and you can also use this to dynamically create or load ranges on the page (depending on where the data for these ranges is coming from).
// These are just example values you can modify
let value = 2,
minValue = 0,
maxValue = 4.5,
minRange = 1,
maxRange = 3;
const _CreateRange = (mnV, mxV, mnR, mxR, v) => {
let r = document.createElement("div");
r.className = "rangeBar";
r.innerHTML = `<div class="minRange"></div><div class="value"></div><div class="maxRange"></div>`;
r.style.setProperty("--min-value", mnV);
r.style.setProperty("--min-value-text", JSON.stringify(mnV+""));
r.style.setProperty("--max-value", mxV);
r.style.setProperty("--max-value-text", JSON.stringify(mxV+""));
r.style.setProperty("--min-range", mnR);
r.style.setProperty("--min-range-text", JSON.stringify(mnR+""));
r.style.setProperty("--max-range", mxR);
r.style.setProperty("--max-range-text", JSON.stringify(mxR+""));
r.style.setProperty("--value", v);
r.style.setProperty("--value-text", JSON.stringify(v+""));
document.querySelector("#bar").append(r);
}
// This is where the function to create the range is called
// We are using our default example values from earlier, but you can pass in any values
_CreateRange(minValue, maxValue, minRange, maxRange, value);
.rangeBar {
background: #EEE;
height: 2em;
padding: .2em;
border: 1px solid #CCC;
box-sizing: border-box;
position: relative;
margin: 0 0 2em;
}
.rangeBar::before {
content: var(--min-value-text);
position: absolute;
top: 100%;
left: 0;
color: #888;
}
.rangeBar::after {
content: var(--max-value-text);
position: absolute;
top: 100%;
right: 0;
color: #888;
}
.rangeBar .value {
background: #0A95FF;
width: calc(var(--value)/var(--max-value)*100%);
height: 100%;
position: relative;
z-index: 1;
}
.rangeBar .value::after {
content: var(--value-text);
position: absolute;
top: 100%;
right: 0;
color: #888;
margin: .2em 0 0;
}
.rangeBar .minRange {
background: #E74C3C;
width: calc(var(--min-range)/var(--max-value)*100%);
height: 100%;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
position: absolute;
top: 0;
left: 0;
z-index: 2;
}
.rangeBar .minRange::after {
content: var(--min-range-text);
position: absolute;
top: 100%;
right: 0;
color: #888;
}
.rangeBar .maxRange {
background: #E74C3C;
width: calc((var(--max-value) - var(--max-range))/var(--max-value)*100%);
height: 100%;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
position: absolute;
top: 0;
right: 0;
z-index: 2;
}
.rangeBar .maxRange::after {
content: var(--max-range-text);
position: absolute;
top: 100%;
left: 0;
color: #888;
}
<div id="bar"></div>

Increment array up to max items

I've written this code. It rotates two divs like a card flip using css transform every 1000ms and displays new text in the div, which is drawn from an array. It runs infinitely.
But once the array reaches its end I get an 'undefined' value because the i++ is incrementing on the final array item. I have been going crazy trying to figure out how to prevent that. Any help?
Codepen: https://codepen.io/warpigs666/pen/OJpBKdy
<style>
#flip-card {
width: 100px;
height: 50px;
}
#flip-card-inner {
position: relative;
width: 100%;
height: 100%;
transition: transform 0.6s;
transform-style: preserve-3d;
}
#textDiv1 {
background-color: lightblue;
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
text-align: center;
}
#textDiv2 {
background-color: lightcoral;
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
text-align: center;
transform: rotateX(180deg);
}
</style>
<body>
<div id="flip-card">
<div id="flip-card-inner">
<div id="textDiv1">
one
</div>
<div id="textDiv2">
set via script
</div>
</div>
</div>
<script>
var flipCard = document.getElementById('flip-card');
var flipCardInner = document.getElementById('flip-card-inner');
var textDiv1 = document.getElementById('textDiv1');
var textDiv2 = document.getElementById('textDiv2');
var wordArray = ["one", "two", "three", "four", "five"]
var i = 1;
function flipText(){
textDiv2.innerHTML = wordArray[i];
flipCardInner.style.transform = "rotateX(180deg)";
setTimeout(
function() {
textDiv1.innerHTML = wordArray[i++];
flipCardInner.style.transform = "rotateX(360deg)";
}, 1000
);
if (i<wordArray.length){
i++;
}
else {i=0;}
}
var flipIt = setInterval(flipText, 2000);
</script>
</body>
This is a job for setInterval
var flipCard = document.getElementById('flip-card');
let flipCardInner = document.getElementById('flip-card-inner');
let textDiv1 = document.getElementById('textDiv1');
let textDiv2 = document.getElementById('textDiv2');
let wordArray = ["one", "two", "three", "four", "five"];
let i = 0;
let timerVal = 1000;
function getI(i) {
if (i < wordArray.length - 1) return i + 1;
else return 0;
}
let ctr = 1,
useDiv; // ctr and useDiv will help to toggle between divs in our loop and also increment the transform number
textDiv1.innerHTML = wordArray[i]; // initialize
function flipText() {
i = getI(i);
useDiv = (useDiv == textDiv2) ? textDiv1 : textDiv2;
useDiv.innerHTML = wordArray[i];
flipCardInner.style.transform = "rotateX(" + (ctr * 180) + "deg)";
ctr++;
}
let interval
window.onload = function() {
// we'll still delay the beginning of the infinite loop, but then we set it to an interval, so it runs forever.
// if you need to stop it in your code, just use clearInterval(interval)
setTimeout(() => {
interval = setInterval(() => flipText(), timerVal);
}, timerVal);
}
#flip-card {
width: 100px;
height: 50px;
perspective: 100px;
}
#flip-card-inner {
position: relative;
width: 100%;
height: 100%;
transition: transform 0.6s;
transform-style: preserve-3d;
}
#textDiv1 {
background-color: lightblue;
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
text-align: center;
}
#textDiv2 {
background-color: lightcoral;
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
text-align: center;
transform: rotateX(180deg);
}
<div id="flip-card">
<div id="flip-card-inner">
<div id="textDiv1">
</div>
<div id="textDiv2">
</div>
</div>
</div>
The issue is as follows, you are incrementing i twice, when it should just be one time:
function() {
textDiv1.innerHTML = wordArray[i++]; ==> Here
flipCardInner.style.transform = "rotateX(360deg)";
}, 1000
);
if (i<wordArray.length){
i++; ==> And here
}
else {i=0;}
}
remove the increment on wordArray[i++], should not give you error.
Also make it i < wordArray.length -1
I don't think this is the ideal way of this job but sticking to your context perhaps like this;
var flipCard = document.getElementById('flip-card'),
flipCardInner = document.getElementById('flip-card-inner'),
textDiv1 = document.getElementById('textDiv1'),
textDiv2 = document.getElementById('textDiv2'),
wordArray = ["one", "two", "three", "four", "five"],
i = 0;
function flipText(){
textDiv2.innerHTML = wordArray[++i % wordArray.length];
flipCardInner.style.transform = "rotateX(180deg)";
setTimeout(function(){
textDiv1.innerHTML = wordArray[++i % wordArray.length];
flipCardInner.style.transform = "rotateX(360deg)";
}, 1000);
}
var flipIt = setInterval(flipText, 2000);
#flip-card { width: 100px;
height: 50px;
}
#flip-card-inner { position: relative;
width: 100%;
height: 100%;
transition: transform 0.6s;
transform-style: preserve-3d;
}
#textDiv1 { background-color: lightblue;
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
text-align: center;
}
#textDiv2 { background-color: lightcoral;
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
text-align: center;
transform: rotateX(180deg);
}
<div id="flip-card">
<div id="flip-card-inner">
<div id="textDiv1">
one
</div>
<div id="textDiv2">
set via script
</div>
</div>
</div>

Website code works fine on Chrome and Firefox, desktop or mobile, but does not work on Safari

A certain piece of my website works fine on Chrome and Firefox, but does not seem to work on Safari. I checked and all the people trying the website on iPhones had Javascript enabled. Is there something about my code that cannot be read by Safari? Are there any tools out there to test how code would be perceived on Safari that I can use with a windows computer?
Below is the code to the piece of my website. I had to replace all images and text with different content because I am forbidden to share the actual content. Essentially, this piece of the website would allow someone to input a certain metric in, via a slider bar, and see what something would look like with said metric. The slider bar seems to be movable, but images are not appearing, nor are they moving when viewing through Safari. As an additional note, I converted this code to https (what Wix refers to as all in one text block) and inserted it into my Wix website as an html element.
I realize that my JavaScript has quite a few redundancies, such as defining the same variable locally twice instead of defining it globally once. I'm looking to fix those later and get this working first (although this could be why it doesn't work on Safari?). I've never developed anything before, so any help at all would be much appreciated.
Update: I had a few people send me screenshots and the slider bar AND javascript are working, the images are just not showing up on Safari.
HTML
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content="">
<meta name="author" content="">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<!-- Box-->
<div class="wholething">
<div class="box">
<!-- Dude -->
<img class="img-square img-dude" src="https://i.pinimg.com/474x/ff/5a/74/ff5a741afd59d527f4492c593b329106--free-clipart-downloads-free-clipart-images.jpg" id="dude" </img>
<!-- Banana-->
<img class="img-square img-bn" src=" https://upload.wikimedia.org/wikipedia/commons/0/0a/Candy-clipart.svg" id="flag">
</img>
<div class="whitebox" id="whiteboxID">
</div>
<img class="gorilla" src="https://openclipart.org/download/249534/1464300474.svg" id="gorillaID" </img>
</div>
<h1 class="sliderlabel" id="sliderlabelID">Hunger level</h1>
<h1 class="sliderlabelinfo" id="sliderlabelinfoID">(drag to select)</h1>
<!-- Slider -->
<div class="slidecontainer">
<input type="range" min="3" max="10" value="5" step="0.1" class="slider" id="inchslider">
<output name="rangeVal" id="value"></output>
</div>
</div>
</body>
</html>
CSS
html {
overflow-y: hidden;
}
.wholething {
height: 100%;
width: 100%;
left: 0;
right: 0;
margin-left: auto;
margin-right: auto;
position: absolute;
}
.box {
background-color: #F5F4EF;
height: 60%;
width: 81.25%;
position: absolute;
left: 0;
right: 0;
margin-left: auto;
margin-right: auto;
border-radius: 5%;
}
.img-dude {
position: absolute;
top: 0;
bottom: 0;
margin-top: auto;
margin-bottom: auto;
margin-left: 20px;
height: 90%;
}
.img-bn {
position: absolute;
top: 0;
bottom: 0;
margin-top: auto;
margin-bottom: auto;
z-index: 2;
height: 10.125%;
}
.whitebox {
position: absolute;
background-color: #F5F4EF;
top: 0;
bottom: 0;
height: calc(15% + 15px);
width: calc(15% + 20px);
margin-top: auto;
margin-bottom: auto;
z-index: 1;
}
.gorilla {
position: absolute;
top: 0;
bottom: 0;
right: 0%;
margin-top: auto;
margin-bottom: auto;
z-index: 2;
height: 90%;
display: none;
}
.sliderlabel {
position: absolute;
left: 12.5%;
top: 61%;
font-size: 16px;
font-family: Arial;
font-weight: 900;
}
.sliderlabelinfo {
position: absolute;
left: 12.5%;
top: 66.5%;
font-size: 14px;
font-family: Arial;
font-weight: 500;
}
.slidervalue {
position: absolute;
top: 20px;
left: 28.5%;
}
.slidecontainer {
width: 75%;
position: absolute;
left: 0;
right: 0;
top: 90%;
margin-left: auto;
margin-right: auto;
}
.slider {
-webkit-appearance: none;
-moz-apperance: none;
width: 100%;
height: 10px;
background-image: -webkit-gradient( linear, left top, right top, color-stop(0.15, #4BD1A0), color-stop(0.15, #F5F4EF));
position: absolute;
outline: none;
opacity: 0.7;
-webkit-transition: .2s;
transition: opacity .2s;
border-radius: 5px;
left: 0;
right: 0;
margin-left: auto;
margin-right: auto;
}
.slider:hover {
opacity: 1;
box-shadow: 0 0 0 2px #4BD1A0;
}
.slider::-webkit-slider-thumb:hover+output {
display: block;
transform: translateX(-50%);
box-shadow: 0 0 0 2px #4BD1A0;
}
.slider:active {
opacity: 1;
box-shadow: 0 0 0 2px #4BD1A0;
}
.slider::-webkit-slider-thumb:active {
box-shadow: 0 0 0 2px #4BD1A0;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 25px;
height: 25px;
background: #F5F4EF;
cursor: pointer;
border-radius: 50%;
}
.slider::-moz-range-thumb {
width: 25px;
height: 25px;
background: #4CAF50;
cursor: pointer;
}
output {
position: absolute;
top: -50px;
left: calc(28.57% + 3.25px);
width: 80px;
height: 30px;
border: 1px solid #e2e2e2;
background-color: #4BD1A0;
border-radius: 10px;
color: white;
font-size: 14px;
line-height: 30px;
text-align: center;
vertical-align: middle;
display: block;
transform: translateX(-50%);
}
input[type=range]:hover+output {
display: block;
transform: translateX(-50%);
}
input[type=range]:active+output {
display: block;
transform: translateX(-50%);
}
input[type=range] {
background-image: -webkit-gradient(linear, left top, right top, color-stop(0.2857, #4BD1A0), color-stop(0.2857, #F5F4EF))
}
output:after {
content: "";
position: absolute;
width: 0;
height: 0;
border-top: 10px solid #4BD1A0;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
top: 100%;
left: 40%;
margin-top: -1px;
}
JavaScript
$(function() {
var element = document.getElementById('dude'),
style = window.getComputedStyle(element),
width = style.getPropertyValue('width'),
height = style.getPropertyValue('height');
var slicedwidth = width.slice(0, -2);
var slicedheight = height.slice(0, -2);
var widthmargarin = ((Number(slicedwidth) * 0.55) + 20).toString() + "px";
var heightmargarin = (Number(slicedheight) * 0.488).toString() + "px";
var whiteboxwidthmargarin = ((Number(slicedwidth) * 0.55) + 25).toString() + "px";
document.getElementById("flag").style.marginLeft = widthmargarin;
document.getElementById("flag").style.marginBottom = heightmargarin;
document.getElementById("value").innerHTML = "5 points";
document.getElementById("whiteboxID").style.marginLeft = whiteboxwidthmargarin;
});
function setIcon(x, y) {
var element = document.getElementById('dude'),
style = window.getComputedStyle(element),
width = style.getPropertyValue('width'),
left = style.getPropertyValue('left'),
height = style.getPropertyValue('height');
var slicedwidth = width.slice(0, -2);
var slicedheight = height.slice(0, -2);
var widthmargarin = ((Number(slicedwidth) * 0.55) + (((x - 5) / 100 * 4.6) * Number(slicedwidth)) + 20).toString() + "px";
var heightmargarin = ((Number(slicedheight) * 0.485) + (((y - 5) / 100 * 0.5) * Number(slicedheight))).toString() + "px";
document.getElementById("flag").style.marginLeft = widthmargarin;
document.getElementById("flag").style.marginBottom = heightmargarin;
document.getElementById("flag").style.transform = "rotate(" + (7 - (x * 1.3)) + "deg)";
document.getElementById("whiteboxID").style.marginLeft = (Number(widthmargarin.slice(0, -2)) + 5).toString() + "px";
document.getElementById("whiteboxID").style.transform = "rotate(" + (7 - (x * 1.5)) + "deg)";
}
var slider = document.getElementById("inchslider");
var output = document.getElementById("value");
output.innerHTML = slider.value;
slider.oninput = function() {
output.innerHTML = this.value;
var positionXslider = 0;
var positionYslider = 0;
if (this.value >= 5) {
positionXslider = output.innerHTML;
positionYslider = output.innerHTML;
document.getElementById("flag").src = "https://upload.wikimedia.org/wikipedia/commons/0/0a/Candy-clipart.svg";
} else if (this.value >= 4 && this.value < 5) {
positionXslider = 5;
positionYslider = 5;
document.getElementById("flag").src = "https://openclipart.org/download/284444/1502025489.svg";
} else if (this.value < 4) {
positionXslider = 5;
positionYslider = 5;
document.getElementById("flag").src = "https://image.shutterstock.com/image-vector/slice-pizza-on-white-background-260nw-597727904.jpg";
} else {
positionXslider = output.innerHTML;
positionYslider = output.innerHTML;
}
setIcon(positionXslider, positionYslider);
};
$('input[type="range"]').on('input', function() {
var val = ($(this).val() - $(this).attr('min')) / ($(this).attr('max') - $(this).attr('min'));
$(this).css('background-image',
'-webkit-gradient(linear, left top, right top, ' +
'color-stop(' + val + ', #4BD1A0), ' +
'color-stop(' + val + ', #F5F4EF)' +
')'
);
});
$('input[type="range"]').on('input', function() {
var control = $(this),
controlMin = control.attr('min'),
controlMax = control.attr('max'),
controlVal = control.val(),
controlThumbWidth = 25;
var range = controlMax - controlMin;
var position = ((controlVal - controlMin) / range) * 100;
var positionOffset = Math.round(controlThumbWidth * position / 100) - (controlThumbWidth / 2) + 2.25;
var output = control.next('output');
var controlValNumber = Number(controlVal)
var controlValLabel = 0;
if (controlValNumber >= 5) {
controlValLabel = controlVal.slice(0, 3);
} else if (controlValNumber >= 4 && controlValNumber < 5) {
controlValLabel = 4;
} else if (controlValNumber < 4) {
controlValLabel = 3;
}
if (controlValNumber >= 10) {
document.getElementById("gorillaID").style.display = "block";
} else {
document.getElementById("gorillaID").style.display = "none";
}
output
.css('left', 'calc(' + position + '% - ' + positionOffset + 'px)')
.text(controlValLabel + " points")
});

Call functions instead of reloading page

Basically I have this function that picks two different random images from a folder. At the moment I'm using onClick="window.location.reload() to run the function everytime you click.
Is there anyway I can call the funcion onClick without refreshing the page?
Thanks in advance.
body {
border: 0;
color: #000;
background: #fff;
margin: 0;
padding: 0;
font: 2.1vw/1.2em HelveticaNeue, Arial, sans-serif;
letter-spacing: .02em
}
.logo {
cursor: pointer;
position: fixed;
top: 0;
left: 0;
width: 100vw;
text-align: center;
z-index: 100
}
#one,
#two {
position: fixed;
width: 50vw;
top: 0;
display: table
}
#one {
left: 0;
text-align: right
}
#two {
right: 0;
text-align: left
}
.inner {
display: table-cell;
vertical-align: middle;
height: 100vh;
width: 100vw
}
<script>
var IMG = new Array()
IMG[0] = 'https://cdn.shopify.com/s/files/1/0224/5205/products/Siser_EasyWeed_Bright_Red_2048x.jpg?v=1523704262'
IMG[1] = 'http://thezilla.com/wp-content/uploads/2015/07/blue.png'
IMG[2] = 'http://d18nh7ureywlth.cloudfront.net/wp-content/uploads/6901-vibrant-green.jpg'
var j = 0
var p = IMG.length;
var preBuffer = new Array()
for (i = 0; i < p; i++) {
preBuffer[i] = new Image()
preBuffer[i].src = IMG[i]
}
var WI1 = Math.floor(Math.random() * p);
var WI2 = Math.floor(Math.random() * (p - 1));
if (WI2 >= WI1) {
WI2 += 1;
}
function showImage1() {
document.write('<img src="' + IMG[WI1] + '">');
}
function showImage2() {
document.write('<img src="' + IMG[WI2] + '">');
}
</script>
<div class=logo onClick="window.location.reload()"><span class=inner>( RANDOM DYPTICHS )</span></div>
<div id=one><span class=inner><script>showImage1();</script></span></div>
<div id=two><span class=inner><script>showImage2();</script></span></div>
Ideally, there is no need to use ajax either.
I simply used an addEventListener('click'...) and encapsulated your code.
Click on the screen and the images will change randomly.
To Note: Take into a habit of adding (;) where is needed, Javascript is not strict (unless using "use strict") on colons but it can cause a lot of bugs in the future. Also, use commas (' or ") in your attributes in HTML.
Read Javascript Style Guide written by W3 Schools, they do a
good job explaining to newbies about famous javascript conventions
around the globe.
var IMG = new Array(
'https://i.picsum.photos/id/562/200/200.jpg?hmac=F4ylYRNFPH6rDzYo48_NUieJXXI2yaMl9ElwGeFQHZo',
'https://i.picsum.photos/id/650/200/200.jpg?hmac=gu3C13pBxCSHokbnumczMYlmWRLt3CFGx1sDaPpfRnk',
'https://i.picsum.photos/id/67/200/200.jpg?hmac=sN5XCCMqqmBvgDbYmAowWy2VToCkSYP5igDL_iRxK3M');
function getRandomImagePair() {
var j = 0;
var p = IMG.length;
var preBuffer = new Array();
for (i = 0; i < p; i++) {
preBuffer[i] = new Image();
preBuffer[i].src = IMG[i];
}
WI1 = Math.floor(Math.random() * p);
WI2 = Math.floor(Math.random() * (p - 1));
if (WI2 >= WI1) {
WI2 += 1;
}
document.querySelector('#imgOne').src = IMG[WI1];
document.querySelector('#imgTwo').src = IMG[WI2];
}
getRandomImagePair();
document.querySelector('.logo .inner').addEventListener('click', e => {
getRandomImagePair();
});
body {
border: 0;
color: #000;
background: #fff;
margin: 0;
padding: 0;
font: 2.1vw/1.2em HelveticaNeue, Arial, sans-serif;
letter-spacing: .02em
}
.logo {
cursor: pointer;
position: fixed;
top: 0;
left: 0;
width: 100vw;
text-align: center;
z-index: 100;
}
#one,
#two {
position: fixed;
width: 50vw;
top: 0;
display: table
}
#one {
left: 0;
text-align: right
}
#two {
right: 0;
text-align: left
}
.inner {
display: table-cell;
vertical-align: middle;
height: 100vh;
width: 100vw
}
<div class='logo'><span class='inner'>( RANDOM DYPTICHS )</span></div>
<div id='one'><span class='inner'><img id="imgOne" src="#" /></span></div>
<div id='two'><span class='inner'><img id="imgTwo" src="#" /></span></div>

Fit colliding elements in the container dynamically

I have absolutely positioned elements with different position.top and height generated from database.
All I'm trying to do is to un-collide these elements by shifting them to the right while adjusting width to fit inside the <body> container.
I'm having an issue applying 'left' position to the collided elements.
I use https://sourceforge.net/projects/jquerycollision/ to detect collision.
Here is how the final picture should look:
$('div').each(function() {
var name = $(this).text();
var hits = $(this).collision('div').not(this); // Find colliding elements
console.log(name + ' collides with: ' + hits.length + ' others');
if (hits.length > 0) {
var widthAll = 100 / (hits.length + 1);
// Shift colliding elements to the right with equal width
$(hits).add(this).each(function(i) {
var name = $(this).text();
$(this).css({ 'left': widthAll * i + '%', 'width': widthAll + '%' });
});
}
});
div {
position: absolute;
width: 10em;
font-size: 0.75em;
color: white;
}
.blue {
top: 0;
height: 80%;
background-color: blue;
}
.red {
top: 15%;
height: 5%;
background-color: red;
}
.yellow {
top: 17%;
height: 10%;
background-color: yellow;
color: black;
}
.green {
top: 30%;
height: 5%;
background-color: green;
}
.magenta {
top: 36%;
height: 3%;
background-color: magenta;
}
.cyan {
top: 50%;
height: 5%;
background-color: cyan;
color: black;
}
.brown {
top: 81%;
height: 5%;
background-color: brown;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://rawgit.com/dsbaars/jquery-collision/master/js/jquery-collision.min.js"></script>
<div class='blue'>blue</div>
<div class='red'>red</div>
<div class='yellow'>yellow</div>
<div class='green'>green</div>
<div class='magenta'>magenta</div>
<div class='cyan'>cyan</div>
<div class='brown'>brown</div>
I think I have completed your code as you have requested. The idea is,
First block of code shifts the divs to the right so that they don't overlap.
Second block makes the width of the divs evenly distributed according to size of the body.
Last block increases the width of rest of the divs to take remaining space.
"use strict";
var divs = $('div'),
mx = 0,
mxs = [0],
bw = $("body").outerWidth(),
steps = 1;
divs.each(function(i) {
for (var j = i + 1; j < divs.length; j++) {
if (!$(this).data("x")) $(this).data("x", 0);
if (j < divs.length) {
var hit = $(this).collision(divs[j]);
if (hit.length) {
hit = $(divs[j]);
hit.css("left", "+=" + Math.ceil($(this).outerWidth()));
hit.data("x", hit.position().left);
if (mx < hit.data("x")) {
mxs.push(mx = hit.data("x"));
steps++;
}
}
}
}
});
divs.each(function(i) {
let iw = $(this).outerWidth(),
fw = bw / steps;
$(this).outerWidth(fw);
for (var j = i + 1; j < divs.length; j++) {
$(this).collision(divs[j]).css("left", "+=" + Math.ceil((fw - iw) * mxs.indexOf($(divs[j]).data("x"))));
}
});
divs.each(function() {
var os = $(this).outerWidth(),
ts = bw - $(this).position().left;
$(this).outerWidth(ts);
if ($(this).collision(divs).not(this).length) {
$(this).outerWidth(os);
}
});
body {
margin: 0;
}
div {
position: absolute;
width: 10em;
font-size: 0.75em;
color: white;
left: 0;
}
.blue {
top: 0;
height: 80%;
background-color: blue;
}
.red {
top: 15%;
height: 5%;
background-color: red;
}
.yellow {
top: 17%;
height: 10%;
background-color: yellow;
color: black;
}
.green {
top: 20%;
height: 50%;
background-color: green;
}
.magenta {
top: 36%;
height: 3%;
background-color: magenta;
}
.cyan {
top: 50%;
height: 5%;
background-color: cyan;
color: black;
}
.brown {
top: 81%;
height: 5%;
background-color: brown;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/dsbaars/jquery-collision/master/js/jquery-collision.min.js"></script>
<div class='blue'>blue</div>
<div class='red'>red</div>
<div class='yellow'>yellow</div>
<div class='green'>green</div>
<div class='magenta'>magenta</div>
<div class='cyan'>cyan</div>
<div class='brown'>brown</div>
Above snippet is non-responsive. If you wish it to be responsive, then simply listen to resize event, change the value of bw and repeat code blocks 2 and 3.
As mentioned in the comments: jquery-collision.min.js had some unressolved bugs so, as suggested by Alex G, https://www.48design.de/de/news/2009/11/20/kollisionsabfrage-per-jquery-plugin-update-v11/ may be an alternative.

Categories

Resources