Programatically setting images widths based on container width - javascript

I have a series of images i'd liike to output per row. I ned these image to take up the ful width of each row in question. The only way I can think to to do this is by calculating the combined widths of the images vs container width. Then use the pecenateg difference to reduce the image widths.
I have this working nearly 100% as expected, but the images do not quite fill the space in some cases. There must be a flaw in my logic as this should always fit the space based on the calculations.
As you can see from the example below, the images do not quite line up in the righthand side. I think the flaw in my logic is on this line return imageWidths + (60 * imgs.length);
Demo: http://jsfiddle.net/rev3tsuf/5/
JS:
function processImageRows(className, containerWidth) {
let imgWidths = getImageWidthCombines(className);
// initiate image width setting if too large for container
if (imgWidths > containerWidth) {
let percent = Math.ceil((containerWidth / imgWidths) * 100);
getImageWidthCombines(className, percent);
}
}
function getImageWidthCombines(className, percent = false) {
// loop through images for given row and return combined width
let imgs = document.querySelectorAll(`#image-wrapper .${ className } img.set-img`);
let imageWidths = 0;
imgs.forEach(function(el, index) {
if (percent) {
// if percentage is set that means we now set the widths as opposed to return their value
el.style.width = `${Math.floor(el.width * (percent / 100))}px`;
} else {
el.style.width = null;
imageWidths += el.offsetWidth;
}
});
// ??? needs 60 added otherwsie doesn't get right percentage.
return imageWidths + (60 * imgs.length);
}
HTML:
<div class="container">
<div class="row row-1">
<div class="col-auto">
<img src="https://via.placeholder.com/400x473.png" />
</div>
... more images
</div>
<div class="row row-2">
<div class="col-auto">
<img src="https://via.placeholder.com/473x473.png" />
</div>
... more images
</div>
<div class="row row-3">
<div class="col-auto">
<img src="https://via.placeholder.com/578x473.png" class="set-img" />
</div>
... more images
</div>
</div>
I also have a window resize event that triggers the above process, but i've left that out of the example in order to keep it simple.
Any help would be greatly appreciated. It's taken me two days to get this far, and half a day stuck on this one issue, now i'm completely stuck with nothing more to try.

EDIT
To adjust your work just customize CSS class as below:
.row {
margin-right: -4px;
margin-left: -4px;
}
.row .col-auto:first-child{
margin-left: 0!important; /* ADDED */
}
.row .col-auto:last-child{
margin-right: 0 !important; /* ADDED */
}
.row .col-auto{
margin-left: auto; /* ADDED */
margin-right:auto; /* ADDED */
}
.col-auto {
padding-right: 4px !important; /* ADDED !important */
padding-left: 4px !important; /* ADDED !important */
padding-bottom: 8px;
position: relative;
overflow: hidden;
cursor: pointer;
}
DEMO with JS CODE your code:
function processImageRows(className, containerWidth) {
let imgWidths = getImageWidthCombines(className);
// initiate image width setting if too large for container
if (imgWidths > containerWidth) {
let percent = Math.ceil((containerWidth / imgWidths) * 100);
getImageWidthCombines(className, percent);
}
}
function getImageWidthCombines(className, percent = false) {
// loop through images for given row and return combined width
let imgs = document.querySelectorAll(`#image-wrapper .${ className } img.set-img`);
let imageWidths = 0;
imgs.forEach(function(el, index) {
if (percent) {
// if percentage is set that means we now set the widths as opposed to return their value
el.style.width = `${Math.floor(el.width * (percent / 100))}px`;
} else {
el.style.width = null;
imageWidths += el.offsetWidth;
}
});
// ??? needs 60 added otherwsie doesn't get right percentage.
return imageWidths + (60 * imgs.length);
}
// this is called after each image load
function checkLoadingProgress() {
let containerWidth = document.getElementById('image-wrapper').clientWidth;
let imgsTotal = 0;
let imgsLoaded = 0;
// loop through rows
['row-1', 'row-2', 'row-3'].forEach(function(el, index) {
imgsTotal = document.querySelectorAll(`#image-wrapper .${el} img.set-img`).length;
imgsLoaded = document.querySelectorAll(`#image-wrapper .${el} img.set-img.image-loaded`).length;
// only process is all images have loaded for the given row
if (imgsLoaded > 0 && imgsLoaded == imgsTotal) {
processImageRows(el, containerWidth);
}
});
// finally all images have loaded. Updated loading class on container
let allImgsTotal = document.querySelectorAll(`#image-wrapper img.set-img`).length;
let allImgsLoaded = document.querySelectorAll(`#image-wrapper img.set-img.image-loaded`).length;
if (allImgsTotal == allImgsLoaded) {
document.getElementById('image-wrapper').classList.add('image-loaded');
document.getElementById('image-wrapper').classList.remove('image-loading');
}
}
// bind onload event to images
let imgs = document.querySelectorAll('img.set-img');
imgs.forEach(function(el, index) {
el.addEventListener('load', function() {
this.classList.add('image-loaded');
checkLoadingProgress();
}, false);
});
body {
margin: 10px;
}
.row {
margin-right: -4px;
margin-left: -4px;
}
.row .col-auto:first-child{
margin-left: 0!important; /* ADDED */
}
.row .col-auto:last-child{
margin-right: 0 !important; /* ADDED */
}
.row .col-auto{
margin-left: auto; /* ADDED */
margin-right:auto; /* ADDED */
}
.col-auto {
padding-right: 4px !important; /* ADDED !important */
padding-left: 4px !important; /* ADDED !important */
padding-bottom: 8px;
position: relative;
overflow: hidden;
cursor: pointer;
}
.image-wrapper.images-loading .col-auto {
position: absolute;
top: 0;
left: 0;
}
.image-wrapper.images-loaded .col-auto img {
max-width: 100%;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#4.5.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx" crossorigin="anonymous"></script>
<div class="container">
<div id="image-wrapper" class="images-loading">
<div class="row row-1">
<div class="col-auto">
<img src="https://via.placeholder.com/400x473.png" class="set-img" />
</div>
<div class="col-auto">
<img src="https://via.placeholder.com/578x473.png" class="set-img" />
</div>
<div class="col-auto">
<img src="https://via.placeholder.com/578x473.png" class="set-img" />
</div>
<div class="col-auto">
<img src="https://via.placeholder.com/400x473.png" class="set-img" />
</div>
</div>
<div class="row row-2">
<div class="col-auto">
<img src="https://via.placeholder.com/473x473.png" class="set-img" />
</div>
<div class="col-auto">
<img src="https://via.placeholder.com/1042x473.png" class="set-img" />
</div>
<div class="col-auto">
<img src="https://via.placeholder.com/473x473.png" class="set-img" />
</div>
</div>
<div class="row row-3">
<div class="col-auto">
<img src="https://via.placeholder.com/578x473.png" class="set-img" />
</div>
<div class="col-auto">
<img src="https://via.placeholder.com/474x473.png" class="set-img" />
</div>
<div class="col-auto">
<img src="https://via.placeholder.com/578x473.png" class="set-img" />
</div>
</div>
</div>
</div>
BEFORE EDIT:
From the point you know the container size or use flex box, no need to have js, you can simply use CSS by fixing a container as below:
.flexible-container{
max-height: 100%;
overflow:hidden;
position: relative;
}
And then set img with class w-100 and the below CSS:
.flexible-container img{
position: absolute;
left:50%;
top:50%;
transform: translate(-50%, -50%);
}
Images size will be respected and won't be stretch as the extra height will be hidden by container overflow: hidden;.
With class col so automatic width as you seems to have you are grid, pretty much either use grid directly or customize flex class as below:
.flex-15{
flex:1 1 15% !important;
}
.flex-30{
flex:1 1 30% !important;
}
DEMO:
.row-1, .row-2, .row-3{
height: 20vh;
margin-bottom: 10px;
}
.flexible-container{
max-height: 100%;
overflow:hidden;
position: relative;
}
.flexible-container img{
position: absolute;
left:50%;
top:50%;
transform: translate(-50%, -50%);
margin: 1px;
}
.flex-15{
flex:1 1 15% !important;
}
.flex-30{
flex:1 1 30% !important;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
<div class="container">
<div class="row row-1">
<div class="col flexible-container">
<img class="w-100" src="https://via.placeholder.com/400x473.png" />
</div>
<div class="col flex-15 flexible-container">
<img class="w-100" src="https://via.placeholder.com/578x473.png" />
</div>
<div class="col flex-15 flexible-container">
<img class="w-100" src="https://via.placeholder.com/578x473.png" />
</div>
<div class="col flexible-container">
<img class="w-100" src="https://via.placeholder.com/400x473.png" />
</div>
</div>
<div class="row row-2">
<div class="col flexible-container">
<img class="w-100" src="https://via.placeholder.com/473x473.png" class="set-img" />
</div>
<div class="col flexible-container flex-30">
<img class="w-100" src="https://via.placeholder.com/1042x473.png" class="set-img" />
</div>
<div class="col flexible-container">
<img class="w-100" src="https://via.placeholder.com/473x473.png" class="set-img" />
</div>
</div>
<div class="row row-3">
<div class="col flexible-container flex-15">
<img class="w-100" src="https://via.placeholder.com/578x473.png" class="set-img" />
</div>
<div class="col flexible-container">
<img class="w-100" src="https://via.placeholder.com/473x473.png" class="set-img" />
</div>
<div class="col flexible-container flex-15">
<img class="w-100" src="https://via.placeholder.com/578x473.png" class="set-img" />
</div>
</div>
</div>

Related

Modal Window on card click JS CSS PHP

So I have 6 cards on my html. Each one on click need to pop up a modal window (this modal window is the card with more informations, so each modal window is corresponding to one card).
I dont know how to do that. After a day searching on the web I'm here to ask your help.
I have tried to make the html animal_card, and my modal appart. Then all the content will change with php.
And the Javascript need to change the modal window css property to absolute on click.
Someone know how to do that with Javascript ?
HTML :
<div class="animal_card">
<div class="card_title">
<h3>title</h3>
</div>
<div class="card_image">
<img src="image.img" alt="">
</div>
<div class="card_text">
<div class="card_info">
<div class="card_info_age">
<h4>Age</h4>
<p>14</p>
</div>
<div class="card_info_gender">
<h4>Gender :</h4>
<p>Female</p>
</div>
</div>
<h4>Who am I</h4>
<p>Description Text</p>
</div>
</div>
<div class="bg-modal">
<div class="modal-content">
<div class="modal-animal">
<h1>Animal Name</h1>
<button class="close" onclick="closeModal()">&times</button>
<div><img src="img/greciaprofile.jpg" alt=""></div>
<div class="animal-informations">
<div class="left">
<label for="">Age</label>
<p>14</p>
<label for="">Sexe</label>
<p>Female</p>
</div>
<div class="right">
<label for="">Description</label>
<p>
Text
</p>
</div>
</div>
<div>
<button class="main">Adopt</button>
<button class="secondary">Support</button>
</div>
</div>
</div>
</div>
CSS :
.bg-modal {
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.7);
position: absolute;
top: 0;
left: 0;
display: flex;
justify-content: center;
}
.modal-content {
position: absolute;
margin-top: 5rem;
width: 75vw;
background-color: $white;
border-radius: 15px;
}
Javascript :
const cards = document.querySelectorAll('.animal_card');
const modal = document.getElementsByClassName('bg-modal');
const onCardClick = async (e) => {
const card = e.currentTarget;
modal.style.position = 'absolute';
}
cards.forEach(card => card.addEventListener('click', onCardClick));
function closeModal() {
modal[0].style.position = 'none';
}
const cards = document.querySelectorAll('.animal_card');
const modal = document.getElementsByClassName('bg-modal');
const getKeyMap = (modal) => {
if (modal) {
let i;
let keyMap = {};
for (i = 0; i < modal.length; i++) {
const item = modal[i];
const key = item.getAttribute('key');
keyMap[key] = item;
}
return keyMap;
}
return null;
};
const modalMap = getKeyMap(modal);
const onCardClick = async (e) => {
const card = e.currentTarget && e.currentTarget.getAttribute('key') || null;
const selectedModal = modalMap[card] || null;
if (selectedModal) {
selectedModal.style.position = 'absolute';
}
}
cards.forEach(card => card.addEventListener('click', onCardClick));
.bg-modal {
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.7);
/* position: absolute; */
top: 0;
left: 0;
display: flex;
justify-content: center;
}
.modal-content {
position: absolute;
margin-top: 5rem;
width: 75vw;
background-color: $white;
border-radius: 15px;
}
<div key="5" class="animal_card">
<div class="card_title">
<h3>title</h3>
</div>
<div class="card_image">
<img src="image.img" alt="">
</div>
<div class="card_text">
<div class="card_info">
<div class="card_info_age">
<h4>Age</h4>
<p>14</p>
</div>
<div class="card_info_gender">
<h4>Gender :</h4>
<p>Female</p>
</div>
</div>
<h4>Who am I</h4>
<p>Description Text</p>
</div>
</div>
<div class="bg-modal" key="5">
<div class="modal-content">
<div class="modal-animal">
<h1>Animal Name</h1>
<button class="close">&times</button>
<div><img src="img/greciaprofile.jpg" alt=""></div>
<div class="animal-informations">
<div class="left">
<label for="">Age</label>
<p>14</p>
<label for="">Sexe</label>
<p>Female</p>
</div>
<div class="right">
<label for="">Description</label>
<p>
Text
</p>
</div>
</div>
<div>
<button class="main">Adopt</button>
<button class="secondary">Support</button>
</div>
</div>
</div>
</div>
So the direct answer using your example is modal on the onCardClick is returning a collection, not a single element. So selecting the first one modal[0] will fix the position update. I attached an example.
If you are going to show different modals based on the card you click on, you generally need to have a method to track them. Really depends on how you want to do that, based on ids, or index position or so on. Anyways, let me know if this helps.

Cannot read property 'innerHTML' of null using Tabbis

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Tabbis</title>
<link rel="stylesheet" href="../assets/css/dist/style-default.css">
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
<style>
/* Reset */
#import url('https://fonts.googleapis.com/css?family=Quicksand:600&display=swap');
* {
margin: 0;
font-family: quicksand;
}
body {
padding: 4rem;
background: #eee;
#media screen and (max-width: 460px) {
padding: 0;
}
}
.gallerycontainer{
position: relative;
/*Add a height attribute and set to largest image's height to prevent overlaying*/
}
.thumbnail img{
border: 1px solid white;
margin: 0 5px 5px 0;
}
.thumbnail:hover{
background-color: blue;
}
.thumbnail:hover img{
border: 1px solid blue;
}
.thumbnail span{ /*CSS for enlarged image*/
position: fixed;
background-color: transparent;
padding: 5px;
right: 0;
/*border: 1px dashed gray;*/
visibility: hidden;
color: black;
text-decoration: none;
}
.thumbnail span img{ /*CSS for enlarged image*/
border-width: 0;
padding: 2px;
}
.thumbnail:hover span{ /*CSS for enlarged image*/
visibility: visible;
top: 50px;
left: 500px; /*position where enlarged image should offset horizontally */
z-index: 50;
}
</style>
</head>
<body>
<div data-tabs>
<button>INDEX</button>
<button>NORTH</button>
<button>SOUTH</button>
<button>EXTENSION</button>
</div>
<div data-panes>
<!-- Index Tab -->
<div>INDEX</div>
<!-- North Tab -->
<div>
<!-- NE Tabs -->
<div data-tabs>
<button>EAST</button>
<button>WEST</button>
<button>TN</button>
</div>
<div data-panes>
<div>
<div data-tabs>
<button>DNE</button>
<button>HNE</button>
<button>KNE</button>
<button>ENE</button>
<button>WNE</button>
<button>ANE</button>
<button>QNE</button>
<button>BNE</button>
<button>SNE</button>
<button>FNE</button>
<button>XNE</button>
<button>NNE</button>
<button>CNE</button>
<button>ACN</button>
<button>YNE</button>
<button>PB3</button>
</div>
<div data-panes>
<button>DNE JPGs HERE</button>
<button>HNE</button>
<button>KNE</button>
<button>ENE</button>
<button>WNE</button>
<button>ANE</button>
<button>QNE</button>
<button>BNE</button>
<button>SNE</button>
<button>FNE</button>
<button>XNE</button>
<button>NNE</button>
<button>CNE</button>
<button>ACN</button>
<button>YNE</button>
<button>PB3</button>
</div>
</div>
<!-- NW Tabs -->
<div>
<div data-tabs>
<button>DNW</button>
<button>HNW</button>
<button>KNW</button>
<button>ENW</button>
<button>WNW</button>
<button>ANW</button>
<button>QNW</button>
<button>BNW</button>
<button>SNW</button>
<button>FNW</button>
<button>XNW</button>
<button>NNW</button>
<button>CNW</button>
<button>ACN</button>
<button>YNW</button>
<button>PB1</button>
</div>
<div data-panes>
<button>DNW JPGs HERE</button>
<button>HNW</button>
<button>KNW</button>
<button>ENW</button>
<button>WNW</button>
<button>ANW</button>
<button>QNW</button>
<button>BNW</button>
<button>SNW</button>
<button>FNW</button>
<button>XNW</button>
<button>NNW</button>
<button>CNW</button>
<button>ACN</button>
<button>YNW</button>
<button>PB1</button>
</div>
</div>
<!-- TN Tab -->
<div>Pane TN</div>
</div>
</div>
<!-- SOUTH -->
<div>
<div data-tabs>
<button>EAST</button>
<button>WEST</button>
<button>TS</button>
</div>
<div data-panes>
<!-- SE Tabs -->
<div>
<div data-tabs>
<button>DSE</button>
<button>HSE</button>
<button>KSE</button>
<button>ESE</button>
<button>WSE</button>
<button>ASE</button>
<button>QSE</button>
<button>BSE</button>
<button>SSE</button>
<button>FSE</button>
<button>XSE</button>
<button>NSE</button>
<button>CSE</button>
<button>ACS</button>
<button>YSE</button>
<button>PB4</button>
</div>
<div data-panes>
<button>DSE JPGs HERE</button>
<button>HSE</button>
<button>KSE</button>
<button>ESE</button>
<button>WSE</button>
<button>ASE</button>
<button>QSE</button>
<button>BSE</button>
<button>SSE</button>
<button>FSE</button>
<button>XSE</button>
<button>NSE</button>
<button>CSE</button>
<button>ACS</button>
<button>YSE</button>
<button>PB4</button>
</div>
</div>
<!-- SW Tabs -->
<div>
<div data-tabs>
<button>DSW</button>
<button>HSW</button>
<button>KSW</button>
<button>ESW</button>
<button>WSW</button>
<button>ASW</button>
<button>QSW</button>
<button>BSW</button>
<button>SSW</button>
<button>FSW</button>
<button>XSW</button>
<button>NSW</button>
<button>CSW</button>
<button>ASN</button>
<button>YSW</button>
<button>PB2</button>
</div>
<div data-panes>
<button>DSW</button>
<button>HSW</button>
<button>KSW</button>
<button>ESW</button>
<button>WSW</button>
<button>ASW</button>
<button>QSW</button>
<button>BSW</button>
<button>SSW</button>
<button>FSW</button>
<button>XSW</button>
<button>NSW</button>
<button>CSW</button>
<button>ASN</button>
<button>YSW</button>
<button>PB2</button>
</div>
</div>
<!-- TS Tab -->
<div>Pane TS</div>
</div>
</div>
<!-- EXTENSION -->
<div>
<div data-tabs>
<button>EAST</button>
<button>WEST</button>
<button>TSX</button>
</div>
<div data-panes>
<!-- SEX Tabs -->
<div>
<div data-tabs>
<button onclick="onClick()">DSEX</button>
<button onclick="onClick()">HSEX</button>
<button onclick="onClick()">KSEX</button>
<button>ESEX</button>
<button>WSEX</button>
<button>ASEX</button>
<button>QSEX</button>
<button>BSEX</button>
<button>SSEX</button>
<button>FSEX</button>
<button>XSEX</button>
<button>NSEX</button>
<button>CSEX</button>
<button>ACSX</button>
<button>YSEX</button>
<button>PB8</button>
</div>
<div data-panes>
<button>
<div id="dsex">DSEX</div>
</button>
<button>
<div id="hsex>">HSEX</div>
</button>
<button>
<div id="ksex>"></div>
</button>
<button>ESEX</button>
<button>WSEX</button>
<button>ASEX</button>
<button>QSEX</button>
<button>BSEX</button>
<button>SSEX</button>
<button>FSEX</button>
<button>XSEX</button>
<button>NSEX</button>
<button>CSEX</button>
<button>ACSX</button>
<button>YSEX</button>
<button>PB8</button>
</div>
</div>
<!-- SWX Tabs -->
<div>
<div data-tabs>
<button>DSWX</button>
<button>HSWX</button>
<button>KSWX</button>
<button>ESWX</button>
<button>WSWX</button>
<button>ASWX</button>
<button>QSWX</button>
<button>BSWX</button>
<button>SSWX</button>
<button>FSWX</button>
<button>XSWX</button>
<button>NSWX</button>
<button>CSWX</button>
<button>ASNX</button>
<button>YSWX</button>
<button>PB6</button>
</div>
<div data-panes>
<button>DSWX</button>
<button>HSWX</button>
<button>KSWX</button>
<button>ESWX</button>
<button>WSWX</button>
<button>ASWX</button>
<button>QSWX</button>
<button>BSWX</button>
<button>SSWX</button>
<button>FSWX</button>
<button>XSWX</button>
<button>NSWX</button>
<button>CSWX</button>
<button>ASNX</button>
<button>YSWX</button>
<button>PB6</button>
</div>
</div>
<!-- TSX Tab -->
<div>Pane TS</div>
</div>
</div>
<script src='script.js'></script>
</div>
<script src="../assets/js/dist/tabbis.es6.js"></script>
<script>
tabbis({
memory: true
});
</script>
</body>
</html>
var elementaries = '../assets/elementaries/';
var elemLoc = [];
var dsex = [
"this.jpg",
"that.jpg"
];
var hsex = [
"this.jpg",
"that.jpg"
];
// ON click of quadrant (DSEX...) do this
function onClick() {
let id = event.srcElement.id; // returns the id of the button (tab 8-0)
let quadrant = document.getElementById(`${id}`).innerHTML.toLowerCase(); // returns the value of the button ie DSEX
getElemLoc(quadrant); // calls function to make an array of elementaries based on quadrant
loadElementaries(quadrant); // loads elementaries under proper tab
}
// Function makes an array of elementaries based on quadrant
var getElemLoc = (q) => {
elemLoc = [];
let elem = window[q];
elem.forEach(function (img) {
let loc = `${elementaries}${q}/${img}`;
elemLoc.push(loc);
})
};
// Loads elementaries to proper div based on quadrant.
var loadElementaries = (quad) => {
for (var i = 0; i < elemLoc.length; i++) {
document.getElementById(`${quad}`).innerHTML = document.getElementById(`${quad}`).innerHTML + `<a class="thumbnail" href="${elemLoc[i]}"><img src="${elemLoc[i]}" width="350px" height="250px" border="0" /><span><img src="${elemLoc[i]}" width="900" height="700" /><br /></span></a> <br />`;
}
};
When going to the tab Extension/East/DSEX my innerhtml code works perfectly, but if I try the hsex tab the inner html in loadElementaries fails. Does anyone have any idea what's going on. Maybe the way the DOM is loading between tabs?
document.getElementById(`${quad}`).innerHTML works for dsex tab but not hsex...
I'm at work so I'm limited to using client side JS/HTML/CSS so nodejs isn't an option unfortunately.

How to save the details of range slider in the local storage?

I am replicating this webpage https://www.modsy.com/project/furniture and I wrote the code On every slide there will be changing of image and phrase like that there are three phrases and images now I want to store the image and phrase in the local storage what the user has finalized
My html code is:
<div class="image mt-3 mb-3" id="sliderImages">
<img src="../static/images/1.jpg" width="400" height="180">
<img src="../static/images/2.jpg" width="400" height="180">
<img src="../static/images/3.jpg" width="400" height="180">
</div><br>
<div class="rangeslider">
<input type="range" min="1" max="3" value="1" class="myslider" id="sliderRange">
<div id="sliderOutput">
<div class="container">
<div class="row mt-4">
<div class="col-4">
<h6 class="display-6">Starting From Scratch</h6>
<p> I'm designing the room </p>
</div>
<div class="col-4">
<h6 class="display-6">Somewhere in Between</h6>
<p>I'm designing around a few pieces I already own</p>
</div>
<div class="col-4">
<h6 class="display-6">Mostly Furnished</h6>
<p>I want to put the finishing touches on my room</p>
</div>
</div>
</div>
<div class="container">
<div class="row mt-4">
<div class="col-4">
<h6 class="display-6">Starting From Scratch</h6>
<p> I'm designing the room </p>
</div>
<div class="col-4">
<h6 class="display-6">Somewhere in Between</h6>
<p>I'm designing around a few pieces I already own</p>
</div>
<div class="col-4">
<h6 class="display-6">Mostly Furnished</h6>
<p>I want to put the finishing touches on my room</p>
</div>
</div>
</div>
<div class="container">
<div class="row mt-4">
<div class="col-4">
<h6 class="display-6">Starting From Scratch</h6>
<p> I'm designing the room </p>
</div>
<div class="col-4">
<h6 class="display-6">Somewhere in Between</h6>
<p>I'm designing around a few pieces I already own</p>
</div>
<div class="col-4">
<h6 class="display-6">Mostly Furnished</h6>
<p>I want to put the finishing touches on my room</p>
</div>
</div>
</div>
</div>
<div class="row mb-3 mt-3">
<div class="col-4 mr-5">
« Home
</div>
<div class="col-4 ml-5">
Next » </div>
</div>
</div>
My CSS code is:
<style>
.rangeslider {
width: 50%;
margin: 0 auto;
position: absolute;
}
.myslider {
-webkit-appearance: none;
background: white;
width: 100%;
height: 20px;
opacity: 0.8;
margin-top: 180px;
}
.myslider::-webkit-slider-thumb {
-webkit-appearance: none;
cursor: pointer;
background: #000080;
width: 33%;
height: 20px;
}
.col-4 {
text-align: center;
}
.myslider:hover {
opacity: 1;
}
.image {
position: relative;
width: 400px;
margin: 0 auto;
}
.image>img {
position: absolute;
display: none;
}
.image>img.visible,
.image>img:first-child {
display: block;
}
#sliderOutput>div {
display: none;
}
#sliderOutput>div.visible,
#sliderOutput>div:first-child {
display: block;
}
#p1{
height: 10px;
}
</style>
My JS code is:
<script>
window.addEventListener('load', function() {
var rangeslider = document.getElementById("sliderRange");
var output = document.getElementById("sliderOutput");
var images = document.getElementById("sliderImages");
rangeslider.addEventListener('input', function() {
for (var i = 0; i < output.children.length; i++) {
output.children[i].style.display = 'none';
images.children[i].style.display = 'none';
}
i = Number(this.value) - 1;
output.children[i].style.display = 'block';
images.children[i].style.display = 'block';
});
});
</script>
My main requirement if the slider is in the first that phrase and image should be stored in local storage like that if it is in second that details should store.
There is no enough details about what json you want to store in the localStorage so that's why i am giving you the basic idea of how you can store a json in localStorage.
Basically you can't store json in localStorage directly but you can store that json in form of a stringand then converting that string(json) into json. Here is the basic example :
// setting json to localStorage
var jsonToBeStoredInLocalStorae = {
sliderImages = [
{path : 'image-path-here'},
{path : 'image-path-here'}
],
phrase : 'your image phrase'
};
localStorage.setItem('slider_json',JSON.stringify(jsonToBeStoredInLocalStorae ));
When you want to get that json from localStorage so you will do like this
//Here you are getting that json in `string` form from `localStorage` and parsing it to `json`
var localStorageJson = JSON.parse(localStorage.getItem('slider_json'));
In localStorage you can only save text strings, so if you want to save it is only one value per record, you insert a name and value to localStorage, but if you want to save an object, you must transform it to a text string with the function JSON.stringify

JS OnMouseOver-Event (DIV2) change BackgroundImage (DIV1)

i got a fullscreen-bg div which in my case got the ID #background-change.
In that fullscreen-bg i got 3 Divs called .fullscreen-column-1, .fullscreen-column-2 etc.
now i want to change the background-image of #background-change while the mouseoverevent is called on the columns.
My code looks like this, but it did not work.
<div id="background-change" data-midnight="dark" data-bg-mobile-hidden="" class="wpb_row vc_row-fluid vc_row full-width-content vc_row-o-full-height vc_row-o-columns-middle vc_row-o-equal-height vc_row-flex vc_row-o-content-middle standard_section first-section loaded" style="padding-top: 0px; padding-bottom: 0px; margin-left: -298px; width: 1841px; visibility: visible; min-height: 96.7579vh;"><div class="row-bg-wrap instance-0"><div class="inner-wrap"> <div class="row-bg " style="" data-color_overlay="" data-color_overlay_2="" data-gradient_direction="" data-overlay_strength="0.3" data-enable_gradient="false"></div></div> </div><div class="col span_12 dark left" style="min-height: 96.7579vh;">
<div class="vc_col-sm-4 fullscreen-column-1 wpb_column column_container vc_column_container col has-animation padding-10-percent instance-0 animated-in" data-border-radius="none" data-shadow="none" data-border-animation="" data-border-animation-delay="" data-border-width="none" data-border-style="solid" data-border-color="#000000" data-bg-cover="" data-padding-pos="all" data-has-bg-color="false" data-bg-color="" data-bg-opacity="1" data-hover-bg="" data-hover-bg-opacity="1" data-animation="fade-in-from-left" data-delay="500" style="padding-top: 184.094px; padding-bottom: 184.094px; opacity: 1; transform: translate(0px, 0px);"><a class="column-link" href="#"></a>
<div class="vc_column-inner">
<div class="wpb_wrapper">
<h2 style="font-size: 64px;color: #ffffff;text-align: center;font-family:Chivo;font-weight:400;font-style:normal" class="vc_custom_heading" id="testid">About</h2>
</div>
</div>
</div>
<div class="vc_col-sm-4 wpb_column column_container vc_column_container col no-extra-padding instance-1" data-border-radius="none" data-shadow="none" data-border-animation="" data-border-animation-delay="" data-border-width="none" data-border-style="solid" data-border-color="" data-bg-cover="" data-padding-pos="all" data-has-bg-color="false" data-bg-color="" data-bg-opacity="1" data-hover-bg="" data-hover-bg-opacity="1" data-animation="" data-delay="0">
<div class="vc_column-inner">
<div class="wpb_wrapper">
<h2 style="font-size: 64px;color: #ffffff;text-align: center;font-family:Chivo;font-weight:400;font-style:normal" class="vc_custom_heading">Work</h2>
</div>
</div>
</div>
<div class="vc_col-sm-4 wpb_column column_container vc_column_container col no-extra-padding instance-2" data-border-radius="none" data-shadow="none" data-border-animation="" data-border-animation-delay="" data-border-width="none" data-border-style="solid" data-border-color="" data-bg-cover="" data-padding-pos="all" data-has-bg-color="false" data-bg-color="" data-bg-opacity="1" data-hover-bg="" data-hover-bg-opacity="1" data-animation="" data-delay="0" style="min-height: 425px;">
<div class="vc_column-inner">
<div class="wpb_wrapper">
</div>
</div>
</div> `<div class="vc_col-sm-4 fullscreen-column-1 wpb_column column_container vc_column_container col has-animation padding-10-percent instance-0 animated-in" data-border-radius="none" data-shadow="none" data-border-animation="" data-border-animation-delay="" data-border-width="none" data-border-style="solid" data-border-color="#000000" data-bg-cover="" data-padding-pos="all" data-has-bg-color="false" data-bg-color="" data-bg-opacity="1" data-hover-bg="" data-hover-bg-opacity="1" data-animation="fade-in-from-left" data-delay="500" style="padding-top: 184.094px; padding-bottom: 184.094px; opacity: 1; transform: translate(0px, 0px);"><a class="column-link" href="#"></a>
<div class="vc_column-inner">
<div class="wpb_wrapper">
<h2 style="font-size: 64px;color: #ffffff;text-align: center;font-family:Chivo;font-weight:400;font-style:normal" class="vc_custom_heading" id="testid">About</h2>
</div>
</div>
</div>`
Here comes the js:
<script type="text/javascript">
document.getElementsByClassName("fullscreen-column-1").onmouseover = function() {
document.getElementById("background-change").style.backgroundImage = "url('https://mywebsite.de/uploads/image-1.jpg')";
};
</script>
any one got the solution? I cant get it to work, i feel dumb right now...
Solution: posted by: Rajan Patil
for (i = 0; i < document.getElementsByClassName("fullscreen-column-1").length; i++) {
document.getElementsByClassName("fullscreen-column-1")[i].onmouseover = function() {
document.getElementById("background-change").style.backgroundImage = "url('your-image-url')";
}
}
You do not need JavaScript for this. Use CSS instead.
.fullscreen-column-1 {
width: 400px;
height: 1000px;
background-image: url(https://picsum.photos/400/1000);
transition: 0.2s ease-in-out;
}
.fullscreen-column-1:hover {
background-image: url(https://picsum.photos/400/1002)
}
<div class="fullscreen-column-1"></div>
There is a typo. getElementsById should be getElementById
Also attach your event listener this way :
for (i = 0; i < document.getElementsByClassName("fullscreen-column-1").length; i++) {
document.getElementsByClassName("fullscreen-column-1")[i].onmouseover = function() {
document.getElementById("background-change").style.backgroundImage = "url('your-image-url')";
}
}

Creating a star rating from an image based on a float number?

recently I have wanted to turn a number into a star rating and I stumbled upon this post here: https://stackoverflow.com/a/1987545/1871869 which is exactly what I wanted to do. I have followed this explanation but I can't seem to get it to work on my local environment, and I was wondering if someone could help me out. Here is my attempt:
$.fn.stars = function() {
return $(this).each(function() {
// Get the value
var val = parseFloat($(this).html());
// Make sure that the value is in 0 - 5 range, multiply to get width
var size = Math.max(0, (Math.min(5, val))) * 16;
// Create stars holder
var $span = $('<span />').width(size);
// Replace the numerical value with stars
$(this).html($span);
});
}
$(function() {
console.log("Calling stars()");
$('.results-contents span.stars').stars();
});
.results {
font-size: 0;
padding-bottom: 16px;
}
.results-content {
font-size: 13px;
display: inline-block;
margin-left: 20px;
vertical-align: top;
}
.results .results-content span.stars span.stars span {
background: url('/resources/graphics/stars-icons.png') 0 -36px repeat-x;
width: 175px;
height: 80px;
}
.results .results-content span.stars {
max-width: 80px;
background-position: 0 0;
}
<script type="text/template" id="results-template">
<div class="results">
<div class="results-content">
<span class="stars">4.0</span>
</div>
</div>
</script>
Image of stars:
What I wanted to do was to simply have the empty stars show, and then based on the rating, show the orange stars on top of the empty stars so that I can show full and half star ratings. However, all I get is a number to show up. My console.log above seems to be called but it seems like the actual rendering of the image and calculation of the star rating is not working. Any help would be appreciated. Thanks!
You had multiple issues from CSS styles being wrong to your selector being wrong. Below is not perfect, but it is rendering.
$.fn.stars = function() {
return this.each(function() {
// Get the value
var val = parseFloat($(this).html());
// Make sure that the value is in 0 - 5 range, multiply to get width
var size = Math.max(0, (Math.min(5, val))) * 36.5;
// Create stars holder
var $span = $('<span> </span>').width(size);
// Replace the numerical value with stars
$(this).empty().append($span);
});
}
$(function() {
console.log("Calling stars()");
$('.results-content span.stars').stars();
});
.results {
font-size: 0;
padding-bottom: 16px;
}
.results-content {
font-size: 13px;
display: inline-block;
margin-left: 20px;
vertical-align: top;
background: url('https://i.stack.imgur.com/rwkqF.png') 0 0 repeat-x;
width: 185px;
height: 35px;
}
.results .results-content span.stars span {
background: url('https://i.stack.imgur.com/rwkqF.png') 0 -36px repeat-x;
display: inline-block;
height: 35px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="results">
<div class="results-content">
<span class="stars">0.0</span>
</div>
</div>
<div class="results">
<div class="results-content">
<span class="stars">0.5</span>
</div>
</div>
<div class="results">
<div class="results-content">
<span class="stars">1.0</span>
</div>
</div>
<div class="results">
<div class="results-content">
<span class="stars">1.5</span>
</div>
</div>
<div class="results">
<div class="results-content">
<span class="stars">2.0</span>
</div>
</div>
<div class="results">
<div class="results-content">
<span class="stars">2.0</span>
</div>
</div>
<div class="results">
<div class="results-content">
<span class="stars">2.5</span>
</div>
</div>
<div class="results">
<div class="results-content">
<span class="stars">3.0</span>
</div>
</div>
<div class="results">
<div class="results-content">
<span class="stars">3.5</span>
</div>
</div>
<div class="results">
<div class="results-content">
<span class="stars">4.0</span>
</div>
</div>
<div class="results">
<div class="results-content">
<span class="stars">4.5</span>
</div>
</div>
<div class="results">
<div class="results-content">
<span class="stars">5.0</span>
</div>
</div>

Categories

Resources