Stop lines from wrapping when using jquery animate - javascript

I have this fiddle set up: https://jsfiddle.net/xwb9594m/
As you can see when the slide menu gets toggled off, the content wraps as the menu shrinks. I'm trying to just get it to slide away off the side of the screen cleanly.
This is my JS:
$(document).ready(function() {
var menuBtn = $('.video-search-button'),
menu = $('.video-search-menu'),
close = $('.video-search-menu .close');
menuBtn.click(function(){
menu.animate({width: 'toggle'});
});
close.click(function(){
menu.animate({width: 'toggle'});
});
});
and my SCSS:
.video-search-menu {
display: none;
position: fixed;
top: 0;
right: 0;
width: auto;
height: 100%;
overflow: hidden;
background: #24637e;
background: rgba(36, 99, 126, 0.9);
color: #fff;
z-index: 101;
&-wrapper {
position: relative;
padding: 180px 50px 0 50px;
}
.close {
position: absolute;
width: 40px;
height: 40px;
top: 15px;
left: 15px;
z-index: 9999;
cursor: pointer;
&:before, &:after {
content: '';
position: absolute;
width: 100%;
top: 50%;
height: 2px;
background: #ffffff;
transform: rotate(45deg);
}
&:after {
transform: rotate(-45deg);
}
}
}

Add a CSS rule
p{
overflow: hidden;
white-space: nowrap;
}

I updated your jsFiddle
Or copy the code below:
$(document).ready(function() {
var menuBtn = $('.video-search-button'),
menu = $('.video-search-menu'),
close = $('.video-search-menu .close');
var right = (1 - menu.width()) - 1;
menu.css('right', right);
menuBtn.click(function(){
menu.animate({right: 0}).show();
});
close.click(function(){
menu.animate({right: right});
});
});
Update: Close menu on clicking again on the button
jsFiddle
Or copy the code below:
$(document).ready(function() {
var menuBtn = $('.video-search-button'),
menu = $('.video-search-menu'),
close = $('.video-search-menu .close');
var right = (1 - menu.width()) - 1;
menu.css('right', right);
menuBtn.click(function(){
if(menu.is(':visible')) {
close.trigger('click');
}
else {
menu.animate({right: 0}).show();
}
});
close.click(function(){
menu.animate({right: right}, function() {
menu.hide();
});
});
});
Update 2:
You can also save some lines of code for your close-"icon":
jsFiddle

Related

a href's not working from inside a modal popup NOT BOOTSTRAP, NOT JQUERY

The aside element is a modal popup with multiple a href links inside, none of which are working. I can right click and go to the link but clicking on it does nothing. The open modal is triggered by Javascript. There are no external libraries, plugins etc that could be causing conflict.
What am I missing here?
const overlay = document.querySelector(".overlay");
const card = document.querySelectorAll(".card");
card.forEach((card) => {
card.addEventListener("click", () => {
const cardId = card.getAttribute("data-card");
const modal = document.getElementById(`${cardId}`);
modal.classList.remove("hidden");
overlay.classList.remove("hidden");
const vScrollPos = window.scrollY;
document.body.style.position = "fixed";
document.body.style.top = `-${vScrollPos}px`;
const closeModal = function() {
modal.classList.add("hidden");
overlay.classList.add("hidden");
const scrollY = document.body.style.top;
document.body.style.position = "";
document.body.style.top = "";
window.scrollTo(0, parseInt(scrollY || "0") * -1);
};
const modalCloseBtn = modal.querySelector(".close-modal");
modalCloseBtn.addEventListener("click", () => {
closeModal();
});
overlay.addEventListener("click", closeModal);
document.addEventListener("keydown", function(e) {
if (e.key === "Escape" && !modal.classList.contains("hidden")) {
closeModal();
}
});
});
});
.hidden {
display: none;
}
.modal {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: calc(100vw - 16rem);
overflow-y: scroll;
max-height: calc(100vh - 16rem);
background-color: white;
padding: 6rem;
border-radius: 5px;
box-shadow: 0 3rem 5rem rgba(0, 0, 0, 0.3);
z-index: 10;
pointer-events: all;
cursor: pointer;
}
.overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.6);
backdrop-filter: blur(3px);
overflow-y: scroll;
z-index: 5;
}
.modal-title {
font-size: 2.4rem;
margin-bottom: 3rem;
}
.close-modal {
position: absolute;
top: 1.2rem;
right: 2rem;
font-size: 5rem;
color: #333;
cursor: pointer;
border: none;
background: none;
}
<article class="card" data-card="modal1">
<img class="card-img" src="img/card-thumb/cardImg.jpg" alt="card image">
<p class="card-title">open card modal</p>
</article>
<aside class="modal hidden" id="modal1">
<button class="close-modal">×</button>
<h5 class="modal-title">
<a href='https://www.google.com/' target='_blank' rel='noreferrer noopener nofollow'>WHY IS THIS LINK NOT OPENING?</a>
<h5>
</aside>
Ok. issue has been found and fixed.
I was using scrollIntoView to handle page nav and smooth scrolling and I imprecisely targeted all "a" elements before I wrote the code for this current section with "a" elements inside of modal containers. Solved issue by giving the page nav a's an additional class then targeting that class only for that section of JS code! Doooooh.

How to handle onclick null error for HTML added via JS?

I have markup that is added via JS that has an onclick action (it's a close button).
Essentially:
User clicks play button
A modal appears with the video and a close modal button (both which are added via JS)
As my close button (.modal--close) isn't on the page on load, I'm getting a Cannot set properties of null (setting 'onclick') (I think).
My thoughts are that the because the DOMContentLoaded event was already fired at this point, it is causing the error? But unsure how to resolve it.
Demo
if (document.readyState === "complete") {
ready();
} else {
document.addEventListener("DOMContentLoaded", ready);
}
function ready() {
if(document.querySelector(".open-video")){
document.querySelector(".open-video").onclick = function (e) {
e.preventDefault();
var modal = document.querySelector(".videoModal");
// get data
var triggerURL = this.getAttribute("href");
var triggerID = this.getAttribute("data-modal");
// update modal attributes with trigger data
modal.setAttribute("data-video", triggerURL);
modal.setAttribute("id", triggerID);
var modalID = '#'+ triggerID;
modal.classList.add("modal--open");
var html = '<div class="modal__wrapper"><iframe width="640" height="360" src="'+ triggerURL + '?rel=0&autoplay=1" frameborder="0" allowfullscreen></iframe></div><div class="modal__overlay"></div>';
modal.innerHTML = html;
return false;
}
}
// close modal
document.querySelector(".modal--close").onclick = function (e) {
e.preventDefault();
console.log("test");
}
}
.modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 99999;
overflow: hidden;
display: none;
padding: 70px 80px;
}
.modal--close {
position: fixed;
right: 50%;
top: 32px;
width: 16px;
height: 16px;
z-index: 999999;
pointer-events: auto !important;
}
.modal--close:hover:before, .modal--close:hover:after {
background-color: #F15A40;
}
.modal--close:before, .modal--close:after {
content: "";
position: absolute;
left: 15px;
height: 16px;
width: 2px;
background-color: #FFFFFF;
}
.modal--close:before {
transform: rotate(45deg);
}
.modal--close:after {
transform: rotate(-45deg);
}
.modal--open {
display: block;
}
.modal .modal__wrapper {
position: relative;
top: 50%;
transform: translateY(-50%);
max-height: 100%;
overflow: hidden;
z-index: 150;
}
.modal .modal__wrapper:before {
content: "";
display: block;
padding-top: 56.25%;
}
.modal .modal__wrapper iframe, .modal .modal__wrapper video {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
outline: none;
}
.modal .modal__overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #000000;
}
<a class="button--play open-video" data-modal="video--1" href="https://www.youtube.com/embed/NpEaa2P7qZI">Click me</a>
<div class="videoModal modal modal__post--modal">
<a id="modal_close" class="modal__close"></a>
<div class="modal__wrapper"></div>
<div class="modal__overlay"></div>
</div>
Edit
Have also tried moving the event listener after the markup has been added:
if (document.readyState === "complete") {
ready();
} else {
document.addEventListener("DOMContentLoaded", ready);
}
function ready() {
let video_btn = document.querySelector(".open-video");
let close_btn = document.querySelector(".modal--close");
let modal = document.querySelector(".videoModal");
if(video_btn){
video_btn.addEventListener("click", function (e) {
e.preventDefault();
// get data
var triggerURL = this.getAttribute("href");
var triggerID = this.getAttribute("data-modal");
// update modal attributes with trigger data
modal.setAttribute("data-video", triggerURL);
modal.setAttribute("id", triggerID);
var modalID = '#'+ triggerID;
modal.classList.add("modal--open");
var html = '<div class="modal__wrapper"><iframe width="640" height="360" src="'+ triggerURL + '?rel=0&autoplay=1" frameborder="0" allowfullscreen></iframe></div><div class="modal__overlay"></div>';
modal.innerHTML = html;
return false;
close_btn.addEventListener("click", function (e) {
e.preventDefault();
console.log("test");
});
});
}
}
With the above, the modal launches fine, but when I click .modal--close, nothing happens (no console.log and no console errors).
Edit 2
Have also tried moving the second event listener above the code snippet that adds the markup:
var html = '<div class="modal__wrapper"><iframe width="640" height="360" src="'+ triggerURL + '?rel=0&autoplay=1" frameborder="0" allowfullscreen></iframe></div><div class="modal__overlay"></div>';
close_btn.addEventListener("click", function (e) {
e.preventDefault();
console.log("test");
});
modal.innerHTML = html;
return false;
With the above however, when I click the .open-video button, I get the error Cannot read properties of null (reading 'addEventListener')
if (document.readyState === "complete") {
ready();
} else {
document.addEventListener("DOMContentLoaded", ready);
}
function ready() {
var modal = document.querySelector(".videoModal");
var triggerURL;
if(document.querySelector(".open-video")){
document.querySelector(".open-video").onclick = function (e) {
e.preventDefault();
// get data
triggerURL = this.getAttribute("href");
var triggerID = this.getAttribute("data-modal");
// update modal attributes with trigger data
modal.setAttribute("data-video", triggerURL);
modal.setAttribute("id", triggerID);
var modalID = '#'+ triggerID;
modal.classList.add("modal--open");
return false;
}
}
// close modal
var html = '<div class="modal__wrapper"><iframe width="640" height="360" src="'+ triggerURL + '?rel=0&autoplay=1" frameborder="0" allowfullscreen></iframe></div><div class="modal__overlay"></div>';
modal.innerHTML = html;
if(document.querySelector(".modal--close")){
document.querySelector(".modal--close").onclick = function (e) {
e.preventDefault();
console.log("test");
}
}
}
.modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 99999;
overflow: hidden;
display: none;
padding: 70px 80px;
}
.modal--close {
position: fixed;
right: 50%;
top: 32px;
width: 16px;
height: 16px;
z-index: 999999;
pointer-events: auto !important;
}
.modal--close:hover:before, .modal--close:hover:after {
background-color: #F15A40;
}
.modal--close:before, .modal--close:after {
content: "";
position: absolute;
left: 15px;
height: 16px;
width: 2px;
background-color: #FFFFFF;
}
.modal--close:before {
transform: rotate(45deg);
}
.modal--close:after {
transform: rotate(-45deg);
}
.modal--open {
display: block;
}
.modal .modal__wrapper {
position: relative;
top: 50%;
transform: translateY(-50%);
max-height: 100%;
overflow: hidden;
z-index: 150;
}
.modal .modal__wrapper:before {
content: "";
display: block;
padding-top: 56.25%;
}
.modal .modal__wrapper iframe, .modal .modal__wrapper video {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
outline: none;
}
.modal .modal__overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #000000;
}
<a class="button--play open-video" data-modal="video--1" href="https://www.youtube.com/embed/NpEaa2P7qZI">Click me</a>
<div class="videoModal modal modal__post--modal">
<a id="modal_close" class="modal__close"></a>
<div class="modal__wrapper"></div>
<div class="modal__overlay"></div>
</div>
Just wrap the code snippet that fires the issues with below function.
if(document.querySelector(".modal--close")){
}

creating toggle buttons to switch between div panels

My web application is made of various panels and a dashboard that has buttons to access each panel. So each button is a toggle between the purposed panel and the main panel.
For example, if we have 3 panels, panel1 is the default one and two buttons to toggle between other two panels the the default one:
button.panel2 should switch between panel1 and panel2
button.panel3 should switch between panel1 and panel3
I have almost achieved it but my code shows both panel2 and panel3 overlapping.
$(function () {
$(".panel2").on("click", function() {
var visibleObj = $('.mainSection div:visible');
var inVisibleObj = $('.mainSection div:hidden');
visibleObj.fadeOut(500, function() {
inVisibleObj.fadeIn(500);
});
});
$(".panel3").on("click", function() {
var visibleObj = $('.mainSection div:visible');
var inVisibleObj = $('.mainSection div:hidden');
visibleObj.fadeOut(500, function() {
inVisibleObj.fadeIn(500);
});
});
});
div.app {
margin:50px auto;
width: 400px;
height: 400px;
border-radius:10px;
overflow: hidden;
position: relative;
}
div.app > .blur {
width: 100%;
height: 100%;
background: url(http://goo.gl/0VTd9W);
-webkit-filter: blur(5px);
}
div.mainSection, div.dashboard{
position: absolute;
left: 0px;
text-align:center;
color:#fff;
font-size:20px;
}
div.mainSection{
width:100%;
height:85%;
background:rgba(0,0,0,0.5);
top:0;
}
div.dashboard{
width:100%;
height:15%;
background:rgba(255,0,0,0.5);
bottom:0;
}
div.mainSection > .panel1,
div.mainSection > .panel2,
div.mainSection > .panel3 {
width: 100%;
Height: 100%;
Background: rgba(0, 0, 0, 0.5);
position: absolute;
left: 0px;
top: 0px;
}
div.mainSection > .panel3 > p{
margin-top:80px;
}
.grid-button {
background: none;
border: none;
padding: 3px;
width: 100%;
}
.grid {
display: inline-block;
height: 4px;
position: relative;
width: 32px;
transition: all 0.3s ease-in-out;
}
.grid:after, .grid:before {
content: '';
position: absolute;
background-color: #FFF;
display: inline-block;
height: 4px;
left: 0;
width: 32px;
transition: all 0.3s ease-in-out;
}
.grid.open {
background-color: #FFF;
}
.grid.open:after {
top: 10px;
}
.grid.open:before {
top: -10px;
}
.grid.close {
background-color: transparent;
transform: scale(0.9);
}
.grid.close:after, .grid.close:before {
top: 0;
transform-origin: 50% 50%;
}
.grid.close:before {
transform: rotate(135deg);
}
.grid.close:after {
transform: rotate(45deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="app">
<div class="blur"></div>
<div class="mainSection">
<div class="panel1">Panel1</div>
<div class="panel2" style="display: none;">Panel2</div>
<div class="panel3" style="display: none;"><p>Panel3</p></div>
</div>
<div class="dashboard">
<button class="panel2">button1</button>
<button class="panel3">button2</button>
</div>
</div>
So I want to make button1 responsible to switch between panel 1 and 2. and button2 to switch between panel 1 and 3.
Any idea how to do it?
I think you need something like this. just these jquery code will be useful.
var currentPanel = 1;
$('.panelControlBtn').on("click", function() {
var ID = $(this).attr('data-id');
if (ID != currentPanel) {
$(".panel").fadeOut('fast', function() {
$("#panel" + ID).fadeIn('fast');
});
currentPanel = ID;
}
});
How about this? https://jsfiddle.net/oez0488h/53/
$("button.panel2").on("click", function() {
var visibleObj = $('.mainSection div:visible');
if ($("div.panel2").css("display") == "none") {
var inVisibleObj = $("div.panel2")
}
else {
var inVisibleObj = $("div.panel1")
}
visibleObj.fadeOut(500, function() {
inVisibleObj.fadeIn(500);
})
});
$("button.panel3").on("click", function() {
var visibleObj = $('.mainSection div:visible');
if ($("div.panel3").css("display") == "none") {
var inVisibleObj = $("div.panel3")
}
else {
var inVisibleObj = $("div.panel1")
}
visibleObj.fadeOut(500, function() {
inVisibleObj.fadeIn(500);
})
});

Why do the changes (to CSS properties) caused by JQuery event handler appear only momentarily?

JSFiddle here.
$(document).ready(function() {
var numberOfItems = $('.item').length;
if (numberOfItems > 4) {
$('.wrapper').mouseover(function() {
$('a.next-arrow').css('display', 'block');
});
$('.wrapper').mouseleave(function() {
$('a.next-arrow').css('display', 'none');
});
}
/**
*
**/
$('a.next-arrow').click(function() {
var i = 1;
while (i <= numberOfItems) { //1, 5
if ($('div.item' + i).css('display').toLowerCase() == 'inline-block') {
$('div.item' + i).css('display', 'none');
break;
}
i = i + 4;
}
});
});
* {
padding: 0px;
border: 0px none;
background: transparent none repeat scroll 0% 0%;
font-size: 100%;
vertical-align: baseline;
}
.wrapper {
position: relative;
white-space: nowrap;
overflow: hidden;
}
div.item {
/*position:absolute;*/
display: inline-block;
width: 25%;
height: 25vw;
}
.wheat {
background-color: wheat;
}
.pink {
background-color: pink;
}
.beige {
background-color: beige;
}
.gainsboro {
background-color: gainsboro;
}
.coral {
background-color: coral;
}
.crimson {
background-color: crimson;
}
.item1 {
left: 0%;
}
.item2 {
left: 25%;
}
.item3 {
left: 50%;
}
.item4 {
left: 75%;
}
.item5 {
left: 100%;
}
.item6 {
left: 125%;
}
.previous-arrow,
.next-arrow {
width: 30px;
height: 50%;
top: 50%;
position: absolute;
display: block;
opacity: 0.7;
/*color: transparent;*/
background-repeat: no-repeat;
margin-top: -30px;
display: none;
}
.previous-arrow {
background-image: url(a2.png);
left: 0px;
}
.next-arrow {
background-image: url(b2.png);
right: 0px;
}
.previous-arrow,
.next-arrow {
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<a class="previous-arrow" href=""><</a><!--
--><div class="item item1 wheat">a.</div><!--
--><div class="item item2 pink">a.</div><!--
--><div class="item item3 beige">a.</div><!--
--><div class="item item4 gainsboro">a.</div><!--
--><div class="item item5 coral">a.</div><!--
--><div class="item item6 crimson">a.</div><!--
--><a class="next-arrow" href=""><</a>
</div>
In this SSCCE, I want to use the JQuery to handle the click event on .next-arrow, and in the handler, I want to hide the .item1 (for this example - I have over-simplified to demonstrate my problem). When it is hidden, the .item5 should will into the screen (which was previously overflowed out of the screen).
That does happen, but then:
In the code snippet in SO editor, which can be seen above, it shows only momentarily and then the screen goes blank.
In JSFiddle, linked above, as well as on my computer, it appears only momentarily and then the screen goes back to its initial appearance, that is the .item1 appears again, making the .item4 overflow out of the screen.
I have tried and failed to figure out what is happening. Why is this happening? What am I doing wrong?
If I understand correctly, you just need to prevent the default action of clicking the link (currently it reloads the page).
Pass event (You can use any name) to your function, and use preventDefault().
$('a.next-arrow').click(function(event) {
event.preventDefault();
// etc

How to rotate a chart 90 degrees including the text values?

I have the following progress bar, but I'd like it to go vertically instead of horizontally. In other words, I'd like to flip it 90 degrees and have the text flipped by 90 degrees as well
See my code below, as well as my code pen here:
http://codepen.io/chriscruz/pen/jPGMzW
How would I rotate this chart as well as the text value?
HTML
<!-- Change the below data attribute to play -->
<div class="progress-wrap progress" data-progress-percent="50">
<div class="progress-bar-state progress">50</div>
</div>
CSS
.progress {
width: 100%;
height: 50px;
}
.progress-wrap:before {
content: '66';
position: absolute;
left: 5px;
line-height: 50px;
}
.progress-wrap:after {
content: '$250,000';
right: 5px;
position: absolute;
line-height: 50px;
}
.progress-wrap {
background: #f80;
margin: 20px 0;
overflow: hidden;
position: relative;
}
.progress-wrap .progress-bar-state {
background: #ddd;
left: 0;
position: absolute;
top: 0;
line-height: 50px;
}
Javascript
// on page load...
moveProgressBar();
// on browser resize...
$(window).resize(function() {
moveProgressBar();
});
// SIGNATURE PROGRESS
function moveProgressBar() {
console.log("moveProgressBar");
var getPercent = ($('.progress-wrap').data('progress-percent') / 100);
var getProgressWrapWidth = $('.progress-wrap').width();
var progressTotal = getPercent * getProgressWrapWidth;
var animationLength = 2500;
// on page load, animate percentage bar to data percentage length
// .stop() used to prevent animation queueing
$('.progress-bar-state').stop().animate({
left: progressTotal
}, animationLength);
}
CSS
.progress {
height: 500px;
width: 50px;
}
.progress-wrap:before {
content: '66';
position: absolute;
top: 5px;
line-height: 50px;
}
.progress-wrap:after {
content: '$250,000';
bottom: 5px;
position: absolute;
line-height: 50px;
}
.progress-wrap {
background: #f80;
margin: 20px 0;
overflow: hidden;
position: relative;
}
.progress-wrap .progress-bar-state {
background: #ddd;
left: 0;
position: absolute;
top: 0;
line-height: 50px;
}
Javascript
moveProgressBar();
// on browser resize...
$(window).resize(function() {
moveProgressBar();
});
// SIGNATURE PROGRESS
function moveProgressBar() {
console.log("moveProgressBar");
var getPercent = ($('.progress-wrap').data('progress-percent') / 100);
var getProgressWrapWidth = $('.progress-wrap').height();
var progressTotal = getPercent * getProgressWrapWidth;
var animationLength = 2500;
// on page load, animate percentage bar to data percentage length
// .stop() used to prevent animation queueing
$('.progress-bar-state').stop().animate({
top: progressTotal
}, animationLength);
}
Pretty much its just switching the height and widths as well as the lefts with tops and rights with bottoms.
You can rotate text or anything else using this css rule.
transform: rotate(90deg); /* this is the rotation */
Use -90deg to rotate the other way.

Categories