Elements to switch each other on hover - javascript

I am trying to make #switch visible after the .content element is hovered and to make #caption disappear.
Like the element IDs suggest, the #switch element should replace the caption on hover. I used Javascript to work that out, but onmouseover and onmouseout functions did not work with .content and #caption and #switch are abruptly shifting on hover.
document.getElementById('caption').onmouseover = function() {
displaySwitch()
};
document.getElementById('switch').onmouseout = function() {
hideSwitch()
};
function displaySwitch() {
document.getElementById('caption').style.display = "none";
document.getElementById('switch').style.display = "inline-block";
}
function hideSwitch() {
document.getElementById('switch').style.display = "none";
document.getElementById('caption').style.display = "block";
}
body {
margin: 50px;
}
.content {
height: 500px;
width: 100%;
border: 3px solid black;
}
#caption {
font-size: 3em;
}
#switch {
/* The element is hidden in advance. */
display: none;
}
<div class="content">
<a id="caption">Lorem Ipsum</a>
<div id="switch">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla ornare libero et vestibulum pellentesque. In accumsan et est dapibus viverra.</p>
</div>
</div>

As per your requirement 'to make #switch visible after the .content element is hovered and to make #caption disappear', added new id box to content element. And bind onmouseover and onmouseout events to box element.
Please verify the output, is it as per your requirement or I did something different?
document.getElementById('box').onmouseover = function() {
displaySwitch()
};
document.getElementById('box').onmouseout = function() {
hideSwitch()
};
function displaySwitch() {
document.getElementById('caption').style.display = "none";
document.getElementById('switch').style.display = "inline-block";
}
function hideSwitch() {
document.getElementById('switch').style.display = "none";
document.getElementById('caption').style.display = "block";
}
body {
margin: 50px;
}
.content {
height: 500px;
width: 100%;
border: 3px solid black;
}
#caption {
font-size: 3em;
}
#switch {
/* The element is hidden in advance. */
display: none;
}
<div class="content" id="box">
<a id="caption">Lorem Ipsum</a>
<div id="switch">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla ornare libero et vestibulum pellentesque. In accumsan et est dapibus viverra.</p>
</div>
</div>

Related

Cant close div by pressing outside div

I want to show a div on link click and hide if click outside the div.
The script is not working.
I cant close side bar by pressing outside the div.
Here is my code
<body>
<div id="mySidenav" class="sidenav ">
×
ITEM 1
ITEM 2
ITEM 3
ITEM 4
</div>
<!-- Use any element to open the sidenav -->
<span onclick="openNav()" style="cursor: pointer; background: green; border: 1px solid black; padding: 5px;">Click me to get the right sidebar.</span>
<!-- Add all page content inside this div if you want the side nav to push page content to the right (not used if you only want the sidenav to sit on top of the page -->
<div id="main">
... rest of the content ...
</div>
</body>
This is my javascript functions :
<script type="text/javascript">
/* Simple appearence with animation AN-1*/
function openNav() {
document.getElementById("mySidenav").style.width = "934px";
document.body.style.backgroundColor = "rgba(0,0,0,0.4)";
}
function closeNav() {
document.getElementById("mySidenav").style.width = "0";
document.body.style.backgroundColor = "white";
}
$(document).mouseup(function(e){
var container = $("#mySidenav");
// If the target of the click isn't the container
if(!container.is(e.target) && container.has(e.target).length === 0){
container.hide();
}
});
/* Simple appearence with animation AN-1*/
</script>
<!-- container -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous">
</script>
</body>
Here's an example of how you can use event.stopPropagation(). This will allow you to have your $(document).click() function which will close the sideNav, and also prevent that from happening when someone clicks in the sideNav.
https://api.jquery.com/event.stoppropagation/
$(document).click(function() {
console.log('doc clicked');
})
$('.sideNav').click(function(e) {
console.log('box clicked');
e.stopPropagation();
})
.sideNav {
width: 200px;
height: 400px;
background-color: #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='sideNav'></div>
I got your mouseup handler working by changing container.hide() to closeNav().
Here is an example by modifying your code:
function openNav() {
document.getElementById("sidebar").style.width = "200px";
document.body.style.backgroundColor = "rgba(0,0,0,0.4)";
}
function closeNav() {
document.getElementById("sidebar").style.width = "75px";
document.body.style.backgroundColor = "white";
}
$(document).click(function(e) {
var container = $("#sidebar");
// If the target of the click isn't the container
if (!container.is(e.target) && !container.has(e.target).length) {
closeNav()
}
});
closeNav()
#sidebar {
background-color: #cccccc;
width: 75px;
height: 100%;
position: fixed;
transition: width 750ms;
}
.content {
margin-left: 75px;
display: flex;
height: 100vh;
}
body {
margin: 0;
transition: background-color 750ms;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="sidebar">
<button onclick="openNav()">Open</button>
<br/> Your sidebar content here!
</div>
<div class="content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Volutpat ac tincidunt vitae semper quis lectus nulla at volutpat. Accumsan in nisl nisi scelerisque eu ultrices. Ornare suspendisse
sed nisi lacus. Massa tempor nec feugiat nisl pretium fusce id velit.
</div>

creating accordion with js

started learning javascript and I'm now taking my first steps with the DOM.
I'm trying to create an accordion that has some text within each list item. The idea is when mouse is over the list item the element will show but an error for " Uncaught TypeError: Cannot read property 'display' of undefined at HTMLLIElement.show". even though I can see in the console that the variable has the elements.
window.onload = function() {
var list = document.querySelector("ul");
var listItems = document.querySelectorAll("li");
var text = document.querySelectorAll("p");
console.log(text);
for (var i = 0; i < listItems.length; i++) {
listItems[i].addEventListener("mouseover", show);
}
function show() {
if (text.style.display === "block") {
text.style.display = "none";
} else {
text.style.display = "block";
}
}
}
ul {
list-style: none;
margin-left: 30px;
width: 300px;
height: 300px;
}
li {
border: 1px solid red;
width: 298px;
height: 80px;
background-color: grey;
}
p {
display: none;
width: 299px;
height: 80px;
background-color: lightgrey;
}
<body>
<ul>
<li>
Home
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. </p>
</li>
<li>
Career
<p>Suspendisse potenti. Aenean sed ipsum libero. Praesent feugiat faucibus nisl id viverra. </p>
</li>
<li>
Contacts
<p>Nullam tristique ex eu libero sodales posuere.</p>
</li>
</ul>
</body>
You have 2 Choices :
The First One is Handling with the <p> Then you should iterate Over The All paragraph element because the text Variable is an Array !!
The Second One is Handling With li Then instead of Using text u Replace it By this and The this Keyword in This Case Will Refer to The li
First use this instead of text and the add another condition of display blank as at the first time the property is "" (empty) OR the reverse condition that checks the element is not display= none
and then you have to change the selector to querySelector of that perticular instance
window.onload = function() {
var list = document.querySelector("ul");
var listItems = document.querySelectorAll("li");
var text = document.querySelectorAll("p");
//console.log(text);
for (var i = 0; i < listItems.length; i++) {
listItems[i].addEventListener("mouseover", show);
}
function show() {
if (this.querySelector('p').style.display !== "none") {
this.querySelector('p').style.display = "block";
} else {
this.querySelector('p').style.display = "none";
}
}
}
ul {
list-style: none;
margin-left: 30px;
width: 300px;
height: 300px;
}
li {
border: 1px solid red;
width: 298px;
height: 80px;
background-color: grey;
}
p {
display: none;
width: 299px;
height: 80px;
background-color: lightgrey;
}
<body>
<ul>
<li>
Home
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. </p>
</li>
<li>
Career
<p>Suspendisse potenti. Aenean sed ipsum libero. Praesent feugiat faucibus nisl id viverra. </p>
</li>
<li>
Contacts
<p>Nullam tristique ex eu libero sodales posuere.</p>
</li>
</ul>
</body>

How to make an HTML element to expand on hover and overlay similar neighbor elements in the same flex container without moving them?

There are N cards of the same class, each with a different amount of text inside. All cards are in the same flex container (row, wrap). In some cards part of the text is hidden because it exceeds the dimension limits for the class. I want such cards to expand and show the entire content on mouse hover. So far I can make it either to overlay the text only (as in the image) or to expand while moving the neighbors. Instead, such card should overlay above neighbor cards without moving them.
Ideally, the hovered card should expand both horizontally (if possible, symmetrically, otherwise to the left or to the right only), and vertically downwards.
Here is a very simple example created for this question. Each card contains a random length substring of lorem ipsum.
JavaScript, generates cards with random amount of text:
'use strict';
const lorem = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ac auctor augue mauris augue neque gravida in fermentum et. Accumsan in nisl nisi scelerisque. Sed pulvinar proin gravida hendrerit lectus. Tortor id aliquet lectus proin nibh nisl condimentum. Erat pellentesque adipiscing commodo elit at imperdiet dui accumsan sit.';
const items = Array(30).fill(0)
.map(() => Math.ceil(lorem.length * Math.random()))
.map(idx => lorem.substring(0, idx))
.map(txt => `<div class="lorem-card">${txt}</div>`)
.join('');
const html = `<div class="cards-container">${items}</div>`;
document.body.innerHTML += html;
html is a skeleton only because the content is generated by JavaScript
<html>
<head>
<meta charset="utf-8">
<title>Cards demo</title>
<link rel="stylesheet" type="text/css" href="./cards.css">
</head>
<body>
</body>
<script src="./gen.js"></script>
</html>
And here is current CSS:
.cards-container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
align-items: flex-start;
align-content: space-between;
}
.lorem-card {
flex-grow: 1;
background-color: white;
border: 3px solid #008CBA;
padding: 15px;
margin: 15px;
max-width: 150px;
max-height: 200px;
overflow: hidden;
opacity: 1;
}
.lorem-card:hover {
flex-grow: 10;
height: auto;
width: auto;
overflow: visible;
border: 3px solid red;
z-index: 100;
}
https://jsfiddle.net/fpmuc5Lz/3/
So far, this is what I have concluded: it is impossible to not cause the other divs to move while overlaying an element with an initially not absolutely positioned element. As a result, I've decided to create a copy element that is absolutely positioned that has exactly the same width of the original element. This is what I changed in your JS:
'use strict';
const lorem = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ac auctor augue mauris augue neque gravida in fermentum et. Accumsan in nisl nisi scelerisque. Sed pulvinar proin gravida hendrerit lectus.';
const items = Array(30).fill(0)
.map(() => Math.ceil(lorem.length * Math.random()))
.map(idx => lorem.substring(0, idx))
.map(txt => `<div class="lorem-card"><div class="lorem-card--real">${txt}</div><div class="lorem-card--substitute">${txt}</div></div>`)
.join('');
const html = `<div class="cards-container">${items}</div>`;
document.body.innerHTML += html;
And your CSS:
.lorem-card {
position: relative;
flex-grow: 1;
max-width: 150px;
max-height: 200px;
margin: 15px;
overflow: hidden;
}
.lorem-card--real {
max-width: 150px;
max-height: 200px;
padding: 15px;
border: 3px solid #008CBA;
background: #FFF;
text-overflow: ellipsis;
}
.lorem-card--substitute {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
padding: 15px;
background: #FFF;
border: 3px solid #008CBA;
}
.lorem-card:hover {
overflow: visible;
}
.lorem-card:hover .lorem-card--real {
opacity: 0;
}
.lorem-card:hover .lorem-card--substitute{
height: auto;
overflow: visible;
border: 3px solid red;
z-index: 100;
}
The idea is to create a container for two Lorem cards. One that has a set width and height (200px and 150px at maximum) and one that can expand dynamically and overlay other elements without causing other divs to move (by using position: absolute). As can be seen, the effect is that the absolutely positioned element only expands vertically downwards. Furthermore, as height is set to auto, CSS transition does not work, which leads to the following suggestion.
My current idea, if you want it to expand both horizontally both ways and vertically downwards, is to compute the total width of the overall string (arranged in one horizontal line) and the height the largest character. Then, use some math to constraint the div's width and height ratio to 4:3 (while handling edge cases, e.g. specifying min-width and min-height) until you find an area that fits the whole text. This will allow you to have the exact width and height needed and as you can specify the exact width and height, you can also use CSS transition to smoothly expand the div.
Here is the new code: here
EDIT
After fiddling some more, here's the final code. In summary, what I added:
A dummy function that you can configure to decide how much the div should expand
Detection of whether an div needs to expand based on its TextNode's bounding rectangle
A smooth transition (the timeout logic has not been tested with edge cases)
Here's the full-working example:
'use strict';
const lorem = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ac auctor augue mauris augue neque gravida in fermentum et. Accumsan in nisl nisi scelerisque. Sed pulvinar proin gravida hendrerit lectus.';
const items = Array(30).fill(0)
.map(() => Math.ceil(lorem.length * Math.random()))
.map(idx => lorem.substring(0, idx))
.map(txt => `<div class="lorem-card"><div class="lorem-card--real">${txt}</div><div class="lorem-card--substitute">${txt}</div></div>`)
.join('');
const html = `<div class="cards-container">${items}</div>`;
document.body.innerHTML += html;
function getTextWidthAndHeight() {
return [210, 280]
}
let cards = document.querySelectorAll('.lorem-card')
let resetCardOverflow
for (let card of cards) {
card.addEventListener('mouseover', e => {
clearTimeout(resetCardOverflow)
card.style.overflow = 'visible'
// Configure "getTextWidthAndHeight" to fit the new rectangle size needs
let size = getTextWidthAndHeight()
let targetReal = card.querySelector('.lorem-card--real')
let targetSubstitute = card.querySelector('.lorem-card--substitute')
let textNode
for (let child of targetReal.childNodes) {
if (child.nodeName == '#text') {
textNode = child
break
}
}
// Get "height" of textNode's bounding box
let textHeight = 0;
let range = document.createRange();
range.selectNodeContents(textNode);
if (range.getBoundingClientRect) {
var rect = range.getBoundingClientRect();
if (rect) {
textHeight = rect.bottom - rect.top;
}
}
// If text exceeds box height (padding considered)
if (textHeight > 200 - 30) {
targetSubstitute.style.width = `${size[0]}px`
targetSubstitute.style.height = `${size[1]}px`
targetSubstitute.style.transform = `translateX(-30px)`
}
})
card.addEventListener('mouseleave', e => {
let targetSubstitute = card.querySelector('.lorem-card--substitute')
targetSubstitute.style.width = ''
targetSubstitute.style.height = ''
targetSubstitute.style.transform = ''
resetCardOverflow = setTimeout(() => {
card.style.overflow = ''
}, 200)
})
}
* {
box-sizing: border-box;
}
.cards-container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
align-items: flex-start;
align-content: space-between;
}
.lorem-card {
position: relative;
flex-grow: 1;
max-width: 150px;
max-height: 200px;
margin: 15px;
overflow: hidden;
}
.lorem-card--real {
max-width: 150px;
max-height: 200px;
padding: 15px;
border: 3px solid #008CBA;
background: #FFF;
overflow: hidden;
}
.lorem-card--substitute {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
padding: 15px;
background: #FFF;
border: 3px solid #008CBA;
transition: all .2s ease;
overflow: hidden;
}
.lorem-card:hover .lorem-card--real {
opacity: 0;
}
.lorem-card:hover .lorem-card--substitute{
border: 3px solid red;
z-index: 1000;
}
<html>
<head>
<meta charset="utf-8">
<title>Cards demo</title>
<link rel="stylesheet" type="text/css" href="./cards.css">
</head>
<body>
</body>
<script src="./gen.js"></script>
</html>
In case you need the JS fiddle code: here

Animating content from a div that is displayed inside another div

Really new to jquery, so any help appreciated it.
Trying to solve a design challenge. I needed to display the content from a div inside another div, on hover of a third element.
Found some code that helped me put it together, but I wonder if there is a way to animate (slidedown, fadein, etc.) the content when is displayed.
Any idea how can I apply animation to the .html function when it displays the content?
var divContent = $("#explore-agility-content").html('');
$( ".industry" ).hover(
function() {
$("#explore-agility-content").html( $( this).find("#shortdesc").html() );
},
function() {
$("#explore-agility-content").html( divContent );
}
);
https://jsfiddle.net/rnwebdesigner/3wyrwd92/71/
Here are fadeIn fadeOut effects on hover and mouseout
check this fiddle
https://jsfiddle.net/parthjasani/3wyrwd92/72/
var divContent = $("#explore-agility-content").html('');
$(".industry").hover(
function () {
$("#explore-agility-content").html($(this).find("#shortdesc").html());
$("#explore-agility-content .wb").hide().fadeIn()
},
function () {
$("#explore-agility-content .wb").fadeOut(function () {
$("#explore-agility-content").html(divContent);
})
}
);
You can add and remove css classes which can contain several properties to be transitioned on mouse enter and leave..
See snippet below (solution 1)
$('.image').mouseenter(function(){
$(".text").addClass("animate")
});
$('.image').mouseleave(function(){
$(".text").removeClass("animate")
});
.image {
width: 50px;
height: 50px;
display: block;
background-color: red;
}
.text {
background-color: white;
padding:40px;
transition:all 0.5s;
}
.left {
display:block;
height:400px;
width: 400px;
background: url('http://i.stack.imgur.com/jGlzr.png') no-repeat 0 0 scroll;
background-color:#0C0C0C;
background-size: 100% 100%;
}
.animate{
opacity:1 !important;
padding-top:50px;
}
.noanimate{
opacity:0;
padding-top:-50px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="image"></div>
<div class="left">
<div class="text noanimate">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tincidunt consequat tristique. Curabitur vestibulum semper nulla id ornare.
</div>
</div>
Solution 2 - using hover function instead of mounseenter and leave
$('.image').hover(function(){
$(".text").toggleClass("animate")
});
.image {
width: 50px;
height: 50px;
display: block;
background-color: red;
}
.text {
background-color: white;
padding:40px;
transition:all 0.5s;
}
.left {
display:block;
height:400px;
width: 400px;
background: url('http://i.stack.imgur.com/jGlzr.png') no-repeat 0 0 scroll;
background-color:#0C0C0C;
background-size: 100% 100%;
}
.animate{
opacity:1 !important;
padding-top:50px;
}
.noanimate{
opacity:0;
padding-top:-50px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="image"></div>
<div class="left">
<div class="text noanimate">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tincidunt consequat tristique. Curabitur vestibulum semper nulla id ornare.
</div>
</div>

Display a Modal on button click using Jquery

I want to display my Modal on button click. Below is my code.
<input type="button" id="button1" value="Button" onclick="myFunction()"/>
<div id="openModal" class="modalDialog">
<div>
X
<h2>
Modal Box</h2>
<p>
Hello world</p>
</div>
</div>
This is my unfinished script.
<script type="text/javascript">
$(document).ready(function () {
});
</script>
show openModal div on button1 click.
$('#button1').on('click', function() {
$('#openModal').show();
});
No need of onclick="myFunction()" on button
Let's try...
Simple popup model created by using jquery, HTML, and CSS.
$(function() {
// Open Popup
$('[popup-open]').on('click', function() {
var popup_name = $(this).attr('popup-open');
$('[popup-name="' + popup_name + '"]').fadeIn(300);
});
// Close Popup
$('[popup-close]').on('click', function() {
var popup_name = $(this).attr('popup-close');
$('[popup-name="' + popup_name + '"]').fadeOut(300);
});
// Close Popup When Click Outside
$('.popup').on('click', function() {
var popup_name = $(this).find('[popup-close]').attr('popup-close');
$('[popup-name="' + popup_name + '"]').fadeOut(300);
}).children().click(function() {
return false;
});
});
body {
font-family:Arial, Helvetica, sans-serif;
}
p {
font-size: 16px;
line-height: 26px;
letter-spacing: 0.5px;
color: #484848;
}
/* Popup Open button */
.open-button{
color:#FFF;
background:#0066CC;
padding:10px;
text-decoration:none;
border:1px solid #0157ad;
border-radius:3px;
}
.open-button:hover{
background:#01478e;
}
.popup {
position:fixed;
top:0px;
left:0px;
background:rgba(0,0,0,0.75);
width:100%;
height:100%;
display:none;
}
/* Popup inner div */
.popup-content {
width: 500px;
margin: 0 auto;
box-sizing: border-box;
padding: 40px;
margin-top: 20px;
box-shadow: 0px 2px 6px rgba(0,0,0,1);
border-radius: 3px;
background: #fff;
position: relative;
}
/* Popup close button */
.close-button {
width: 25px;
height: 25px;
position: absolute;
top: -10px;
right: -10px;
border-radius: 20px;
background: rgba(0,0,0,0.8);
font-size: 20px;
text-align: center;
color: #fff;
text-decoration:none;
}
.close-button:hover {
background: rgba(0,0,0,1);
}
#media screen and (max-width: 720px) {
.popup-content {
width:90%;
}
}
<!DOCTYPE html>
<html>
<head>
<title> Popup </title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
</head>
<body>
<a class="open-button" popup-open="popup-1" href="javascript:void(0)"> Popup
Preview</a>
<div class="popup" popup-name="popup-1">
<div class="popup-content">
<h2>Model </h2>
<p>Model content will be here. Lorem ipsum dolor sit amet,
consectetur adipiscing elit. Aliquam consequat diam ut tortor
dignissim, vel accumsan libero venenatis. Nunc pretium volutpat
convallis. Integer at metus eget neque hendrerit vestibulum.
Aenean vel mattis purus. Fusce condimentum auctor tellus eget
ullamcorper. Vestibulum sagittis pharetra tellus mollis vestibulum.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<a class="close-button" popup-close="popup-1" href="javascript:void(0)">x</a>
</div>
</div>
</body>
</html>
Change show() to modal.show();
$('#button1').on('click', function() {
$('#openModal').modal('show');
});
You probably have to set visibility:hidden; to the div, and set it to visible onclick

Categories