let el = $('.switch');
let cur = el.find('.current');
let options = el.find('.options li');
let content = $('#content');
// Open language dropdown panel
el.on('click', function(e) {
el.addClass('show-options');
setTimeout(function() {
el.addClass('anim-options');
}, 50);
setTimeout(function() {
el.addClass('show-shadow');
}, 200);
});
// Close language dropdown panel
options.on('click', function(e) {
e.stopPropagation();
el.removeClass('anim-options');
el.removeClass('show-shadow');
let newLang = $(this).data('lang');
cur.find('span').text(newLang);
content.attr('class', newLang);
setLang(newLang);
options.removeClass('selected');
$(this).addClass('selected');
setTimeout(function() {
el.removeClass('show-options');
}, 600);
});
// Save selected options into Local Storage
function getLang() {
let lang;
if (localStorage.getItem('currentLang') === null) {
lang = cur.find('span').text();
} else {
lang = JSON.parse(localStorage.getItem('currentLang')).toLowerCase();
}
// console.log(lang);
cur.find('span').text(lang);
options.parent().find(`li[data-lang="${lang}"]`).addClass('selected');
content.attr('class', lang);
}
getLang();
function setLang(newLang) {
localStorage.setItem('currentLang', JSON.stringify(newLang).toLowerCase());
content.attr('class', newLang);
// console.log('New language is: ' newLang);
}
@import url("https://fonts.googleapis.com/css?family=Playfair Display:400,900|Noto Sans:400,400i,700&subset=latin-ext");
:root {
font-size: 100%;
--base-font-size: calc(15px .5vw);
--ratio: 1.18;
--h6: calc(var(--base-font-size) * var(--ratio));
--h5: calc(var(--h6) * var(--ratio));
--h4: calc(var(--h5) * var(--ratio));
--h3: calc(var(--h4) * var(--ratio));
--h2: calc(var(--h3) * var(--ratio));
--h1: calc(var(--h2) * var(--ratio));
}
body {
font-family: "Noto Sans", Arial, sans-serif;
font-size: 1.2rem;
font-size: var(--base-font-size);
line-height: 1.6;
color: #313436;
}
#content {
max-width: 48rem;
margin: 0 auto;
text-align: left;
padding: 1rem 2rem;
}
#content:not(.en) [data-lang=en], #content:not(.sv) [data-lang=sv]{
display: none;
}
#content.en [data-lang=en],#content.sv [data-lang=sv]{
display: block;
}
h1 {
font-family: "Playfair Display", "Noto Sans", Arial, sans-serif;
font-weight: 900;
font-size: var(--h1);
line-height: calc(var(--h1) * 1.2);
}
h2 {
font-size: var(--h2);
line-height: calc(var(--h2) * 1.2);
}
h3 {
font-size: var(--h3);
line-height: calc(var(--h3) * 1.3);
}
h4 {
font-size: var(--h4);
line-height: calc(var(--h4) * 1.3);
}
h5 {
font-size: var(--h5);
line-height: calc(var(--h5) * 1.4);
}
h6 {
font-size: var(--h6);
line-height: calc(var(--h6) * 1.5);
}
.main-header {
background-color: #3498DB;
color: #FFFFFF;
height: 56px;
display: flex;
padding: 0 2rem;
box-shadow: 0 2px 12px -4px rgba(0, 0, 0, 0.4);
}
.main-header h1 {
font-size: 1.25rem;
line-height: 1.35;
font-family: "Noto Sans", Arial, sans-serif;
}
.main-header .switch {
margin-left: auto;
}
.switch {
position: relative;
cursor: pointer;
display: flex;
align-items: center;
}
.current {
text-transform: uppercase;
height: 42px;
position: relative;
z-index: 1;
font-size: 1rem;
text-align: center;
line-height: 42px;
display: flex;
background-color: rgba(0, 0, 0, 0);
transition: all 0.2s ease-out;
border-radius: 3px;
padding: 0 0.2em 0 0.7em;
}
.current span {
display: inline-block;
line-height: 1;
padding: 0.7em 0.2em 0 0;
}
.current .arrow {
display: inline-block;
width: 20px;
height: 20px;
}
.current:hover {
background-color: rgba(0, 0, 0, 0.1);
}
.options {
position: absolute;
right: 0;
top: 0.6em;
z-index: 0;
opacity: 0;
transition: all 0.36s ease-out;
display: none;
overflow: hidden;
box-shadow: 0 0 0 0 rgba(0, 0, 0, 0);
}
.switch.show-options .options {
display: block;
z-index: 5;
}
.switch.anim-options .options {
opacity: 1;
}
.switch.show-shadow .options {
box-shadow: 0 2px 12px -4px rgba(0, 0, 0, 0.4);
}
.options-list {
color: #313436;
margin: 0;
padding: 0.4rem 0.8em;
position: relative;
z-index: 5;
}
.options-list li {
list-style: none;
padding: 0;
margin: 0;
padding: 0.75em;
border-bottom: 1px solid #E1E4E6;
transform: translateX(10px);
transition: all 0.24s ease-out;
transition-delay: 0.1s;
opacity: 0;
font-size: 1rem;
line-height: 1.3;
white-space: nowrap;
}
.options-list li:last-child {
border-bottom: none;
}
.options-list li:nth-child(1) {
transition-delay: 0.1s;
}
.options-list li:nth-child(2) {
transition-delay: 0.15s;
}
.options-list li:nth-child(3) {
transition-delay: 0.2s;
}
.options-list li:nth-child(4) {
transition-delay: 0.25s;
}
.options-list li:nth-child(5) {
transition-delay: 0.3s;
}
.options-list li.selected {
color: #3498DB;
}
.switch.anim-options .options-list li {
transform: translateX(0);
opacity: 1;
}
#trans-circle {
width: 80px;
height: 80px;
position: absolute;
top: -80px;
right: -80px;
padding: 0;
margin: 0;
border: none;
z-index: 1;
transition: all 0.4s ease-out;
transform: scale(0.5);
overflow: hidden;
}
#trans-circle svg {
max-width: 100%;
max-height: 100%;
}
.switch.anim-options #trans-circle {
transform: scale(9);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
<!-- partial:index.partial.html -->
<header >
<h1 data-lang="en">Language Switch</h1>
<h1 data-lang="sv">Språkbyte</h1>
<div >
<div >
<span>en</span>
<em ><svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18"><title>ic_arrow_drop_down_18px</title>
<g fill="#FFFFFF">
<path d="M5 8l4 4 4-4z"></path>
</g>
</svg></em>
</div>
<div >
<ul >
<li data-lang="en">English</li>
<li data-lang="sv">Svenska</li>
</ul>
<div id="trans-circle"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120"> <g id="circle" fill="none" fill-rule="evenodd"> <circle id="bg" cx="60" cy="60" r="60" fill="#FFFFFF"/> </g> </svg>
</div>
</div>
</header>
<main id="content" >
<h1 data-lang="en">Design</h1>
<h1 data-lang="sv">konstruktion</h1>
</main>
I want the "dropdown Menu" to close when I click anywhere on the page with the mouse?
You can run the "snipper code" in the example by making it full page.
CodePudding user response:
You could solve this by adding an event listener to the window object and check if the clicked element is outside the .switch
element. For that you could give the event to the handler function:
$(window).on('click', function(event) {...});
, check with the is()
function if it or its parents()
don't have the class .switch
:
if (!$(event.target).is('.switch') && !$(event.target).parents().is('.switch'))
and if true, remove the class .show-options
:
el.removeClass('show-options');
all together:
$(window).on('click', function(event) {
if (!$(event.target).is('.switch') && !$(event.target).parents().is('.switch')) {
el.removeClass('show-options');
}
});
Working example:
let el = $('.switch');
let cur = el.find('.current');
let options = el.find('.options li');
let content = $('#content');
// Open language dropdown panel
el.on('click', function(e) {
el.addClass('show-options');
setTimeout(function() {
el.addClass('anim-options');
}, 50);
setTimeout(function() {
el.addClass('show-shadow');
}, 200);
});
$(window).on('click', function(event) {
if (!$(event.target).is('.switch') && !$(event.target).parents().is('.switch')) {
el.removeClass('show-options');
}
});
// Close language dropdown panel
options.on('click', function(e) {
e.stopPropagation();
el.removeClass('anim-options');
el.removeClass('show-shadow');
let newLang = $(this).data('lang');
cur.find('span').text(newLang);
content.attr('class', newLang);
setLang(newLang);
options.removeClass('selected');
$(this).addClass('selected');
setTimeout(function() {
el.removeClass('show-options');
}, 600);
});
// Save selected options into Local Storage
function getLang() {
let lang;
if (localStorage.getItem('currentLang') === null) {
lang = cur.find('span').text();
} else {
lang = JSON.parse(localStorage.getItem('currentLang')).toLowerCase();
}
// console.log(lang);
cur.find('span').text(lang);
options.parent().find(`li[data-lang="${lang}"]`).addClass('selected');
content.attr('class', lang);
}
getLang();
function setLang(newLang) {
localStorage.setItem('currentLang', JSON.stringify(newLang).toLowerCase());
content.attr('class', newLang);
// console.log('New language is: ' newLang);
}
@import url("https://fonts.googleapis.com/css?family=Playfair Display:400,900|Noto Sans:400,400i,700&subset=latin-ext");
:root {
font-size: 100%;
--base-font-size: calc(15px .5vw);
--ratio: 1.18;
--h6: calc(var(--base-font-size) * var(--ratio));
--h5: calc(var(--h6) * var(--ratio));
--h4: calc(var(--h5) * var(--ratio));
--h3: calc(var(--h4) * var(--ratio));
--h2: calc(var(--h3) * var(--ratio));
--h1: calc(var(--h2) * var(--ratio));
}
body {
font-family: "Noto Sans", Arial, sans-serif;
font-size: 1.2rem;
font-size: var(--base-font-size);
line-height: 1.6;
color: #313436;
}
#content {
max-width: 48rem;
margin: 0 auto;
text-align: left;
padding: 1rem 2rem;
}
#content:not(.en) [data-lang=en], #content:not(.sv) [data-lang=sv]{
display: none;
}
#content.en [data-lang=en],#content.sv [data-lang=sv]{
display: block;
}
h1 {
font-family: "Playfair Display", "Noto Sans", Arial, sans-serif;
font-weight: 900;
font-size: var(--h1);
line-height: calc(var(--h1) * 1.2);
}
h2 {
font-size: var(--h2);
line-height: calc(var(--h2) * 1.2);
}
h3 {
font-size: var(--h3);
line-height: calc(var(--h3) * 1.3);
}
h4 {
font-size: var(--h4);
line-height: calc(var(--h4) * 1.3);
}
h5 {
font-size: var(--h5);
line-height: calc(var(--h5) * 1.4);
}
h6 {
font-size: var(--h6);
line-height: calc(var(--h6) * 1.5);
}
.main-header {
background-color: #3498DB;
color: #FFFFFF;
height: 56px;
display: flex;
padding: 0 2rem;
box-shadow: 0 2px 12px -4px rgba(0, 0, 0, 0.4);
}
.main-header h1 {
font-size: 1.25rem;
line-height: 1.35;
font-family: "Noto Sans", Arial, sans-serif;
}
.main-header .switch {
margin-left: auto;
}
.switch {
position: relative;
cursor: pointer;
display: flex;
align-items: center;
}
.current {
text-transform: uppercase;
height: 42px;
position: relative;
z-index: 1;
font-size: 1rem;
text-align: center;
line-height: 42px;
display: flex;
background-color: rgba(0, 0, 0, 0);
transition: all 0.2s ease-out;
border-radius: 3px;
padding: 0 0.2em 0 0.7em;
}
.current span {
display: inline-block;
line-height: 1;
padding: 0.7em 0.2em 0 0;
}
.current .arrow {
display: inline-block;
width: 20px;
height: 20px;
}
.current:hover {
background-color: rgba(0, 0, 0, 0.1);
}
.options {
position: absolute;
right: 0;
top: 0.6em;
z-index: 0;
opacity: 0;
transition: all 0.36s ease-out;
display: none;
overflow: hidden;
box-shadow: 0 0 0 0 rgba(0, 0, 0, 0);
}
.switch.show-options .options {
display: block;
z-index: 5;
}
.switch.anim-options .options {
opacity: 1;
}
.switch.show-shadow .options {
box-shadow: 0 2px 12px -4px rgba(0, 0, 0, 0.4);
}
.options-list {
color: #313436;
margin: 0;
padding: 0.4rem 0.8em;
position: relative;
z-index: 5;
}
.options-list li {
list-style: none;
padding: 0;
margin: 0;
padding: 0.75em;
border-bottom: 1px solid #E1E4E6;
transform: translateX(10px);
transition: all 0.24s ease-out;
transition-delay: 0.1s;
opacity: 0;
font-size: 1rem;
line-height: 1.3;
white-space: nowrap;
}
.options-list li:last-child {
border-bottom: none;
}
.options-list li:nth-child(1) {
transition-delay: 0.1s;
}
.options-list li:nth-child(2) {
transition-delay: 0.15s;
}
.options-list li:nth-child(3) {
transition-delay: 0.2s;
}
.options-list li:nth-child(4) {
transition-delay: 0.25s;
}
.options-list li:nth-child(5) {
transition-delay: 0.3s;
}
.options-list li.selected {
color: #3498DB;
}
.switch.anim-options .options-list li {
transform: translateX(0);
opacity: 1;
}
#trans-circle {
width: 80px;
height: 80px;
position: absolute;
top: -80px;
right: -80px;
padding: 0;
margin: 0;
border: none;
z-index: 1;
transition: all 0.4s ease-out;
transform: scale(0.5);
overflow: hidden;
}
#trans-circle svg {
max-width: 100%;
max-height: 100%;
}
.switch.anim-options #trans-circle {
transform: scale(9);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
<!-- partial:index.partial.html -->
<header >
<h1 data-lang="en">Language Switch</h1>
<h1 data-lang="sv">Språkbyte</h1>
<div >
<div >
<span>en</span>
<em ><svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18"><title>ic_arrow_drop_down_18px</title>
<g fill="#FFFFFF">
<path d="M5 8l4 4 4-4z"></path>
</g>
</svg></em>
</div>
<div >
<ul >
<li data-lang="en">English</li>
<li data-lang="sv">Svenska</li>
</ul>
<div id="trans-circle"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120"> <g id="circle" fill="none" fill-rule="evenodd"> <circle id="bg" cx="60" cy="60" r="60" fill="#FFFFFF"/> </g> </svg>
</div>
</div>
</header>
<main id="content" >
<h1 data-lang="en">Design</h1>
<h1 data-lang="sv">konstruktion</h1>
</main>