Two images change places when hover CSS - javascript

I'm looking for an answer to my problem. I have one large image on the top and eight small images on the bottom of my page. I want to make it so when you hover the small image (it's also a link which goes to different place) the large image changes to this small image. So clearly explained, two images change/swap places. And when I unhover the large image changes back.
Here's the picture so you know what I'm talking about!
And I'm looking for CSS, React (if there is any useful components) or just JavaScript-solution (if else statement or something like that).
https://i.ibb.co/C5m5sH3/demonstration.png
Thank you for your time!

You can use jQuery for your case, capture the hover event and update main image source.
$(document).ready(function(){
$('.thumbnail').hover(function(e){
src = $(e.target).data('main');
$("#target_img").attr('src', src);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="main_image" style="width: 200px; height: 100px">
<img id="target_img" src="#"/>
</div>
<ul>
<li>
<img class="thumbnail" src="https://th.bing.com/th/id/OIP.wx64GmJDu2nd32eO_tieDgHaEK?pid=Api&rs=1" data-main="https://th.bing.com/th/id/OIP.wx64GmJDu2nd32eO_tieDgHaEK?pid=Api&rs=1" width="50px" height="50px"/>
</li>
<li>
<img class="thumbnail" src="https://1.bp.blogspot.com/_138avbqsoJQ/S31zZz9qPZI/AAAAAAAABNQ/ARDHrOa5_pg/s400/Loch_Lomond.JPG" data-main="https://1.bp.blogspot.com/_138avbqsoJQ/S31zZz9qPZI/AAAAAAAABNQ/ARDHrOa5_pg/s400/Loch_Lomond.JPG" width="50px" height="50px"/>
</li>
</ul>

Use mouseover and mouseout event listeners to change the background image of your big div.
The below snippet explains it all -
function change(e){
document.getElementById("main").style.backgroundImage = `url(${e.target.src})`;
}
let imgs = document.getElementsByTagName("img");
for(let i = 0; i<imgs.length; i++){
imgs[i].addEventListener("mouseover", function(){
change(event);
});
imgs[i].addEventListener("mouseout", function(){
document.getElementById("main").style.backgroundImage = `url("https://cdn.pixabay.com/photo/2020/11/28/11/03/advent-5784271__340.jpg")`;
});
}
#main{
height: 150px;
width: 150px;
border: 3px dashed red;
background-image: url("https://cdn.pixabay.com/photo/2020/11/28/11/03/advent-5784271__340.jpg");
}
img{
height: 50px;
width: 50px;
}
<div id="main"></div>
<img src="https://cdn.pixabay.com/photo/2020/03/24/11/21/winter-4963715__340.jpg">
<img src="https://cdn.pixabay.com/photo/2019/12/10/19/15/new-years-eve-4686590__340.jpg">
<img src="https://cdn.pixabay.com/photo/2020/11/17/15/44/cup-5752775__340.jpg">
<img src="https://cdn.pixabay.com/photo/2019/05/18/13/34/branches-4211837__340.jpg">
Currently I don't know what is the structure of your html, but you can tweak this solution to fit your case.

I have created an example of the swap effect that you specified, and created a code pen of it using colors instead:
https://codepen.io/DaudWaqas/pen/xxEgxLm
<section class="main" id="main" style="background-color: #000"></section>
<div>
<Section style="background-color: orange" onmouseover="grabAndSwap(event)"></section>
<Section style="background-color: cyan" onmouseover="grabAndSwap(event)"></section>
<Section style="background-color: maroon" onmouseover="grabAndSwap(event)"></section>
<Section style="background-color: #444" onmouseover="grabAndSwap(event)"></section>
</div>
<div>
<Section style="background-color: #ff0000" onmouseover="grabAndSwap(event)"></section>
<Section style="background-color: #00ff00" onmouseover="grabAndSwap(event)"></section>
<Section style="background-color: #0000ff" onmouseover="grabAndSwap(event)"></section>
<Section style="background-color: magenta" onmouseover="grabAndSwap(event)"></section>
</div>
CSS:
.main {
height: 30vh;
width: 100%;
}
section {
height: 15vh;
width: 25%;
float: left;
}
div {
height: 15vh;
width: 100%;
}
JS:
const main = document.getElementById('main');
function grabAndSwap(event) {
var toSwapWith = event.target;
var mainColor = main.style.backgroundColor;
console.log(mainColor);
var otherColor = toSwapWith.style.backgroundColor;
console.log(otherColor);
main.style.backgroundColor = otherColor;
toSwapWith.style.backgroundColor = mainColor;
}

You can capture mouseover in Javascript and simply swap the background-image and swap back on mouseout.
const picEls= document.getElementsByClassName('small');
const largeEl = document.getElementsByClassName('large')[0];
for (let i=0; i<picEls.length; i++) {
picEls[i].addEventListener('mouseover', hovered);
picEls[i].addEventListener('mouseout', hovered);
}
function hovered(event) {
const bg = event.target.style.backgroundImage;
this.style.backgroundImage = largeEl.style.backgroundImage;
largeEl.style.backgroundImage = bg;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.pic {
border-style: solid;
border-radius: 50%;
background-size: cover;
}
.large {
width: 40vw;
height: 30vw;
margin: 0 auto 0 auto;
}
.small {
display: inline-block;
width: 20vw;
height: 15vw;
margin: 2vw;
}
<div class="container">
<div class="large pic" style="background-image: linear-gradient(red,yellow);"></div>
<div class="small pic" style="background-image: linear-gradient(red,green);"></div>
<div class="small pic" style="background-image: linear-gradient(green,blue);"></div>
<div class="small pic" style="background-image: linear-gradient(blue,red);"></div>
<div class="small pic" style="background-image: linear-gradient(cyan,yellow);"></div>
<div class="small pic" style="background-image: linear-gradient(yellow,magenta);"></div>
<div class="small pic" style="background-image: linear-gradient(magenta,cyan);"></div>
<div class="small pic" style="background-image: linear-gradient(cyan,red);"></div>
<div class="small pic" style="background-image: linear-gradient(yellow, green);"></div>
</div>

Related

How can I implement this horizontal search result bar?

I essentially have a horizontal div that populates content from omdb API. It dynamically generates a bunch of search results, and displays them all; however the overflow: hidden is active.
I have 2 questions:
I have two custom "buttons" that I made with an empty div and icon. I gave it a bit of a box-shadow to give it the illusion that it's hovering. Is it better practice to use a button element instead, or does it matter?
My main question is this: I want to be able to navigate back and forth between my search results using my arrow buttons. What would be the best way to implement this? The only thing I can think of is using the buttons to adjust the left or right margins of my search results. (ie. pressing the left button would adjust the margin-left of my results with a negative margin, and the right arrow would adjust it with a positive margin)
However, this feels crude and not very accurate. Meaning with a few extra clicks, the content could be pushed out of the view entirely (either by accident or on purpose).
Is there a way to set this up more efficiently?
Here is some code as an example:
const leftArrow = document.querySelector("#left-arrow");
const rightArrow = document.querySelector("#right-arrow");
const marginSelector = document.querySelector("#nav-margin");
var marginValue = -20;
leftArrow.addEventListener('click', () => {
marginSelector.style.marginLeft = marginValue + "px";
marginValue += -20;
});
.scrollbar-container {
width: 800px;
display: flex;
border: 1px #5e9af9 solid;
position: relative;
top: 100px;
overflow: hidden;
margin: auto;
align-items: center;
}
.result-container {
display: inline-block;
margin: 2px;
}
img {
display: inline-block;
vertical-align: middle;
position: relative;
}
.nav-button {
position: absolute;
width: 50px;
height: 50px;
background: rgba(230, 232, 237, .5);
text-align: center;
margin: auto 0;
}
.left-arrow {
left: 1%;
}
.right-arrow {
right: 1%;
}
.margin-start {}
<script src="https://use.fontawesome.com/releases/v5.0.6/js/all.js"></script>
<div class="scrollbar-container">
<div id="nav-margin" class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div id="left-arrow" class="nav-button left-arrow">
<i class="fas fa-angle-left fa-3x"></i>
</div>
<div id="left-arrow" class="nav-button right-arrow">
<i class="fas fa-angle-right fa-3x"></i>
</div>
</div>
I've written script to move back and forth the search results. You just need to check and adjust the marginLeft value for your marginSelector. I've added transition into the CSS of #nav-margin so that it looks smooth. marginValue is been initialized with 0. max-width of container has been set to 500px for convenience. When you change your max-width do not forget to change it in addEventListener for rightArrow. You can also make the value inside if condition to dynamic so that it actually takes the value from .scrollbar-container.
Let me know if you have any queries.
const leftArrow = document.querySelector("#left-arrow");
const rightArrow = document.querySelector("#right-arrow");
const marginSelector = document.querySelector("#nav-margin");
var marginRightValue = 0;
rightArrow.addEventListener('click', () => {
if(-(marginRightValue) <= (500+20))
marginRightValue += -100;
marginSelector.style.marginLeft = marginRightValue + "px";
});
leftArrow.addEventListener('click', () => {
if(marginRightValue < 0)
marginRightValue += 100;
marginSelector.style.marginLeft = marginRightValue + "px";
});
.scrollbar-container {
max-width: 500px;
display: flex;
border: 1px #5e9af9 solid;
position: relative;
top: 100px;
overflow: hidden;
margin: auto;
align-items: center;
}
#nav-margin{
transition: all 1s;
}
.result-container {
display: inline-block;
margin: 2px;
}
img {
display: inline-block;
vertical-align: middle;
position: relative;
}
.nav-button {
position: absolute;
width: 50px;
height: 50px;
background: rgba(230, 232, 237, .5);
text-align: center;
margin: auto 0;
cursor: pointer;
}
.left-arrow {
left: 1%;
}
.right-arrow {
right: 1%;
}
.margin-start {}
<script src="https://use.fontawesome.com/releases/v5.0.6/js/all.js"></script>
<div class="scrollbar-container">
<div id="nav-margin" class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div class="result-container">
<img src="https://i.imgur.com/dA3tjxl.gif">
</div>
<div id="left-arrow" class="nav-button left-arrow">
<i class="fas fa-angle-left fa-3x"></i>
</div>
<div id="right-arrow" class="nav-button right-arrow">
<i class="fas fa-angle-right fa-3x"></i>
</div>
</div>
I'm not entirely sure if this would be the best response, but:
Point 1 - I don't think it matters here. A <button> is meant for a form, from a semantics point of view. For more context, read: https://css-tricks.com/use-button-element/
Point 2 - I can already scroll/swipe from left to right (in your code demo when I run the snippet), using my mouse/trackpad. So having extra buttons to do that job seems unnecessary. I would think rather to make a Javascript carousel (or slider) like effect when clicking the right button takes me to the next "slide", or the next chunk of your results. You could then disable buttons when there is no more content on the right (or left), or have them cycle back to the beginning. Effectively you want to think of a fixed width "slide" window (responsive for different viewports) and "slide" accordingly. Does that make sense for your problem?

dashed line on img after height auto

I am currently working on an application where I have a notification panel with different cattegories. The categories are divided by images and dashed lines, but how can I set the height of that dashed line to auto so it changes its height automatically when an new notification is added.
Here is a FIDDLE which represents the problem.
Normally I have this as my html:
<div class="departure-wrapper">
<div class="ui-grid-a">
<div class="ui-block-a">
<span class="departure-img">
<img class="image" src="img/icons/car.png">
</span>
</div>
<div class="ui-block-b">
<h4>Vertrek</h4>
<div class="departure-notification-append"></div>
</div>
</div>
</div>
Where I append with js the new added notifications to the departure-notification-append class
if (category === 'vertrek'){
departureHtml = `
${departureHtml}
<div class='notification-item' style='${style}'>
<div class='ui-grid-a notification-grid'>
<div class='ui-block-a'>
<img class='notification-image' id='${id}' src='${imgPath}'>
</div>
<div class='ui-block-b'>
<span class='notification-text'>${shortmessage}</span>
</div>
</div>
</div>`;
$('.departure-notification-append').empty().prepend(departureHtml);
}
So my question is how can I set the dashed lines to height auto, when I do now the height of the dashed line is 1px or something. I'll hope someone can help me out on this.
use :afrer on parent div like below
.departure-wrapper:after {
content: '';
display: block;
position: absolute;
top: 88px;
left: 60px;
width: 0;
height: 100%;
border: 1px dashed white;
}
try this http://jsfiddle.net/7uygyvwo/

playing fadein/fadeout slider on tab button click

I have created a Fadein/Fadeout slider. Left button and right button are working fine but I want to play slider by clicking on tab buttons.
JSfiddle
HTML
<p id="slide1_controls">
<div class="block-icon icon-s1">
<img class="block-img icon-s1" src="../_images/building_icon1.png" data-hover-image="../_images/building_icon1_hover.png" data-selected="false" />
</div>
<div class="block-icon icon-s2">
<img class="block-img icon-s2" src="../_images/building_icon2.png" data-hover-image="../_images/building_icon2_hover.png" data-selected="false" />
</div>
<div class="block-icon icon-s3">
<img class="block-img icon-s3" src="../_images/building_icon3.png" data-hover-image="../_images/building_icon3_hover.png" data-selected="false" />
</div>
<div class="block-icon icon-s4">
<img class="block-img icon-s4" src="../_images/building_icon4.png" data-hover-image="../_images/building_icon4_hover.png" data-selected="false" />
</div>
</p>
<div class="slider-text-context" id="target">
<div class="slide-01 fade-texts active">tab1</div>
<div class="slide-02 fade-texts">tab2</div>
<div class="slide-03 fade-texts">tab3</div>
<div class="slide-04 fade-texts">tab4</div>
</div>
CSS
.fade-texts {
width: 100%;
height: 259px;
left: 0px;
position: absolute;
}
.slider-btn-area {
position: absolute;
z-index: 8;
margin-left: auto;
margin-right: auto;
left: 25%;
top: 54%;
width: 50%;
}
#target > div {
display:none;
}
#target div:nth-child(1) {
display:block;
}
.tab-area {
position: absolute;
left: 25%;
top: 30%;
}
Javascript
$(".icon-s2").click(function() {
activeElem = $("#target .slide-02");
activeElem.removeClass('active').fadeOut(0);
if (!activeElem.is(':first-child')) {
activeElem.removeClass('active').fadeOut(0).prev().addClass('active').fadeIn(400);
}
}
$(".icon-s3").click(function() {
activeElem = $("#target .slide-03");
activeElem.removeClass('active').fadeOut(0);
if (!activeElem.is(':first-child')) {
activeElem.removeClass('active').fadeOut(0).prev().addClass('active').fadeIn(400);
}
}
When I press the tab it does not work to try to appear a DIV.
Your code made no sense. The way it looked was that the images had to be clicked in order to fadeIn/Out the tabs. I believe it should be the other way. I cleaned up the markup, and simplified the classes, ids, styles, etc...
Here's the DEMO
HTML
<div id="slides">
<div id="slide1" class="slide active">
<img class="img" src="http://placehold.it/150x50/000/Fff.png&text=FIRST" />
</div>
<div id="slide2" class="slide">
<img class="img" src="http://placehold.it/150X50/048/Fee.png&text=SECOND" />
</div>
<div id="slide3" class="slide">
<img class="img" src="http://placehold.it/150X50/fa8/375.png&text=THIRD" />
</div>
<div id="slide4" class="slide">
<img class="img" src="http://placehold.it/150X50/9a7/a10.png&text=FOURTH" />
</div>
</div>
<div class="tab-area" id="controls">
<div id="tab1" class="tab">1</div>
<div id="tab2" class="tab">2</div>
<div id="tab3" class="tab">3</div>
<div id="tab4" class="tab">4</div>
</div>
CSS
.slide {
display:none;
}
.active {
display: block;
}
.tab {
width: 16px;
height: 16px;
display: inline-block;
margin: 0 10px;
outline: 1px solid black;
text-align: center;
cursor: pointer;
}
jQuery/JavaScript
$(function () {
$('.tab').on('click', function (event) {
var tabID = event.target.id;
//console.log('tabID: '+tabID);
var order = tabID.split('b').pop();
//console.log('order: '+order);
var pos = parseInt(order, 10);
var slideID = 'slide'+pos;
//console.log('slideID: '+slideID);
var act = document.getElementById(slideID);
//console.log('act: '+act.id);
$('.slide').fadeOut(0).removeClass('active');
$(act).addClass('active').fadeIn(750);
});
});

scaling images in a fixed width div with equal distance between them

So, I didn't write this but now I'm trying to fix it...
I have a fixed width div which displays 5 images across it. These images are all the same size, but we want to scale them based on a css class. This is being done in drupal so actually scaling the images would be tricky and the current solution was to scale them in CSS. The problem is that when doing this, the spacing between each image is not equal.
A picture is worth a thousand words so here is a fiddle with the current implementation: http://jsfiddle.net/jCa7j/1/
And a graphical view of what I'm talking about:
So the goal here is to have this same output, but have an equal distance between each image. I've tried a lot of things and have had little luck... I've found methods for doing this with just text, or with fixed width images, but nothing that seems to do the trick here. I've also tried putting a width in pixels on .field-content and then width 100% on img so that the divs are all the same width as the scaled image but with that I still haven't been able to figure out how to get them equidistant.
I suppose doing this in javascript is an option as well. I'd prefer straight css but if it's impossible we can do it with javascript.
Any input?
Current example html:
<div id="container">
<div class="field field-1">
<div class="field-content">
<a href="/">
<img src="http://placehold.it/135x150" width="135" height="150" />
</a>
</div>
</div>
<div class="field field-2">
<div class="field-content">
<a href="/">
<img src="http://placehold.it/135x150" width="135" height="150" />
</a>
</div>
</div>
<div class="field field-3">
<div class="field-content">
<a href="/">
<img src="http://placehold.it/135x150" width="135" height="150" />
</a>
</div>
</div>
<div class="field field-4">
<div class="field-content">
<a href="/">
<img src="http://placehold.it/135x150" width="135" height="150" />
</a>
</div>
</div>
<div class="field field-5">
<div class="field-content">
<a href="/">
<img src="http://placehold.it/135x150" width="135" height="150" />
</a>
</div>
</div>
And current example css:
#container {
width: 730px;
}
.field {
width: 142px;
display: inline-block;
text-align: center;
}
.field img {
height: auto;
}
.field-1 img {
width: 70%;
}
.field-2 img {
width: 93%;
}
.field-3 img {
width: 100%;
}
.field-4 img {
width: 91%;
}
.field-5 img {
width: 79%;
}
This should be what you're after:
#container {
width: 730px;
}
.field {
display: inline-block;
text-align: center;
}
.field-1 {
width: 115px;
}
.field-2 {
width: 125px;
}
.field-3 {
width: 135px;
}
.field-4 {
width: 125px;
}
.field-5 {
width: 115px;
}
.field img {
height: auto;
width: 100%;
}
I've simplified things a bit.
FIDDLE
CSS
#container {
width: 730px;
border: 0px solid black;
}
.field {
width: 142px;
float: left;
text-align: center;
margin-left: 2px;
}
Then you just play with the margin-left, container size/position, image size etc.

style each div with a different color using jquery or javascript

I have a home page with ul li div the div is a square box and i have 3x3 at the top.
The bottom section of my site is code generated mark up and i have something similar.
I would like to give each div "box" a color, currently they are all styled with css. Is there a way with jquery to check for ul li div and if the div exists then add a DIFFERENT colour to the inline style? I would need to store the colors in the script.
This is how i could start?:
$("div.box").css({"background-color": "color"});
Here is my example cut down markup:
<ul>
<li data-target="aboutme" data-target-activation="click" style="margin-top:0px" class="tile high me">
<div>
<h2>About Me</h2>
<h3></h3>
<img width="48" height="48" alt="" class="icon" src="images/icons/x.png">
</div>
</li>
<li data-target="aboutme" data-target-activation="click" style="margin-top:0px" class="tile high me">
<div>
<h2>Pane 2</h2>
<h3></h3>
<img width="48" height="48" alt="" class="icon" src="images/icons/x.png">
</div>
</li>
<li data-target="aboutme" data-target-activation="click" style="margin-top:0px" class="tile high me">
<div>
<h2>Pane 3</h2>
<h3></h3>
<img width="48" height="48" alt="" class="icon" src="images/icons/x.png">
</div>
</li>
</ul>
This is the css:
.tiles {
height: 95%;
margin: 0 auto;
min-height: 950px;
overflow: visible;
padding: 10px;
width: 957px;
}
.tile.high {
float: left;
height: 200px;
margin-top: -100px;
padding-left: 10px;
width: 23.6%;
}
li.tile div {
background-color: #00ABA9;
}
.tile div {
background-repeat: no-repeat;
height: 100%;
margin: 10px 10px 0;
overflow: hidden;
width: 100%;
}
Loop through div's and use different color on each:
// Declare colors you want to use
var myColors = [
'#f00', '#abc', '#123'
];
var i = 0;
$('div.box').each(function() {
$(this).css('background-color', myColors[i]);
i = (i + 1) % myColors.length;
});
Check online: http://jsfiddle.net/4NVRQ/
var
color = function(){
return '#' + Math.floor(Math.random()*16777215).toString(16);
},
$els = $('div.box'),
colorify = function(els){
els.each(function(){
$(this).css('backgroundColor', color());
});
};
colorify($els);

Categories

Resources