The navagation Toggle Wont show up - javascript

Any problem with this code it wont show when I tried to click the toggle icon in responsive view in console it says:
navTogglerBtn is null
I tried to look at it but I can't find the problem. Im new in JavaScript. Thank you so much heres my code in JSFiddle code is here
const navTogglerBtn = document.querySelector(".nav-toggler"),
aside = document.querySelector(".aside-menu");
navTogglerBtn.addEventListener("click",() => {
asideSectionTogglerBtn();
})
function asideSectionTogglerBtn() {
aside.classList.toggle("open");
navTogglerBtn.classList.toggle("open");
}

You CSS code is wrong. It's .nav-toggler.open not .nav-toggler .open. And apply some transition to have smooth effect.
.aside-menu .nav-toggler {
display: flex;
left: 30px;
transition: 0.5s;
}
.aside-menu {
left: -270px;
transition: 0.5s;
}
.aside-menu .nav-toggler.open {
left: 300px;
}
.aside-menu.open {
left: 0px;
}

Related

How to hide menu for mobiles by default? Using Javascript

I have a website with side-bar menu. Menu is by default visible. If i click close-btn. Menu is hidden. That works
I would like make menu by default visible for desktops and by default hidden for mobiles.
.side-bar {
background: #1b1a1b;
backdrop-filter: blur(15px);
width: 250px;
height: 100vh;
position: fixed;
top: 0;
z-index: 50;
left: 0px;
overflow-y: auto;
transition: 0.6s ease;
transition-property: left;
}
.side-bar.non-active {
left: -250px;
}
.side-bar.active {
left: 0px;
}
The window.innerWidth < 850 works but i'm not sure if there is something better. 850px i use for #media queries.
$(document).ready(function () {
//jquery for toggle sub menus
$(".sub-btn").click(function () {
$(this).next(".sub-menu").slideToggle();
$(this).find(".dropdown").toggleClass("rotate");
});
//jquery for expand and collapse the sidebar
if (window.innerWidth > 850) {
$(".close-btn").click(function () {
$(".side-bar").addClass("non-active");
$(".menu-btn").css("visibility", "visible");
});
$(".menu-btn").click(function () {
$(".side-bar").removeClass("non-active");
$(".menu-btn").css("visibility", "hidden");
});
}
else {
$(".side-bar").css("left", -250);
$(".close-btn").click(function () {
$(".side-bar").addClass("active");
$(".menu-btn").css("visibility", "visible");
});
$(".menu-btn").click(function () {
$(".side-bar").removeClass("active");
$(".menu-btn").css("visibility", "hidden");
});
}
});
The issue is propably in $(".side-bar").css("left", -250); because in the DOM i can see it as inline style and after click nothing happen. Only .menu-btn disappers.
Is there another way how to set "reverse" logic for mobiles please? Or maybe just easy fix this i hope little bug?
I tried set oposite style for left: -250px; to left:0; via following logic but without any positiv result..
Use this instead:
if (window.matchMedia('(max-width: 850)').matches) { ... }
else { ... }
This uses css media query in JavaScript without any frameworks.

Using touchmove to trigger hover event

I'm relatively new to coding and am running into a particular issue with my website. My homepage has images on it with overlay text hover effect that occurs when a cursor is moved over the image. It works perfectly on desktop, however, not on mobile. I would like for the hover text to appear when the user swipes across the image in any direction. I've done some research and it appears that I should somehow be using jQuery and the touchmove function to make this happen. But I just can't figure it out. I am using Shopify (debut theme) to build my website. Any help will be greatly appreciated!
Here's my CSS for hover event:
//hover effect//
.container {
position: relative;
width: 100%;
}
.image {
display: block;
width: 100%;
height: auto;
}
.overlay {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
height: 99%;
width: 100%;
opacity: 0;
transition: .5s ease;
background-color: #000000;
}
.container:hover .overlay {
opacity: 0.7;
}
.text {
color: white;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 20px;
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
text-align: center;
white-space: pre;
}
Thanks!!!!
You'd need to apply a class with the desired effect to the target element.
You could do it with Jquery, but javascript is perfectly capable to do it on its own.
Something like:
Javascript:
const myTargetElement = document.getElementsByClassName('overlay')[0]; // index to be confirmed
// add hover style
myTargetElement.addEventListener('touchmove', function (e) {
e.target.classList.add('hover'); // or whichever class name you'd like
});
// remove hover style on end
myTargetElement.addEventListener('touchend', function (e) {
e.target.classList.remove('hover'); // or whichever class name you'd like
});
CSS:
.container:hover .overlay,
.overlay.hover {
opacity: 0.7;
}
Note: if you want to target all the elements .overlay on your page with that code, you would need something like:
Javascript:
const myTargetElements = document.getElementsByClassName('overlay');
// convert HTML collection to array
const myTargetElementsArray = [].slice.call(myTargetElements);
myTargetElementsArray.forEach(function (element) {
// add hover style
element.addEventListener('touchmove', function (e) {
e.target.classList.add('hover'); // or whichever class name you'd like
});
// remove hover style on end
element.addEventListener('touchend', function (e) {
e.target.classList.remove('hover'); // or whichever class name you'd like
});
});
so Moustachiste's code works! It had a few syntax errors but I was able to resolve them quickly. Here's the final version:
const myTargetElements = document.getElementsByClassName('overlay');
// convert HTML collection to array
const myTargetElementsArray = [].slice.call(myTargetElements);
myTargetElementsArray.forEach(function (element) {
// add hover style
element.addEventListener('touchmove', function (e) {
e.target.classList.add('hover'); // or whichever class name you'd like
});
// remove hover style on end
element.addEventListener('touchend', function (e) {
e.target.classList.remove('hover'); // or whichever class name you'd like
});
});
Paste the code into your theme.js and adjust the variable names accordingly. Should work for everyone!
Cheers to this guy!

Unable to show and hide text with fade effect on click

I was trying to create a similar effect on up and down arrows as shown in the image below but got stuck midway because of my low javascript/jquery skills.
I can't figure out how to make the text appear and then fade away on click with color change.
Here's a link to the fiddle just in case SO code snippet doesn't work
$("span").click(function() {
$("span").css("color", "grey");
$(this).css("color", "red");
});
ul > li{
list-style:none;
}
span {
cursor: pointer;
}
.fa {
font-size: 55px;
text-indent: 200px;
margin-bottom: 20px;
margin-top:30px;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li><span id='select1'><i class="fa fa-long-arrow-up" aria-hidden="true"></i></span></li>
<li><span id='select2'><i class="fa fa-long-arrow-down" aria-hidden="true"></i></span></li>
</ul>
So far none of the answers have worked for me so I am asking for more help on this.
I saw this effect on reddit and I've tried many times and spent so much time but failed to get the similar effect. I'd really appreciate it if anybody could help me understand and create the exact effect.
here is my version of the solution, https://jsfiddle.net/hnk1vw6x/33/
see some explanations below.
HTML
<div class="padding-container">
<span id="rating">0</span>
<a class="arrow fa fa-arrow-up" data-animation-text="Nice!" data-value="1"></a><br/>
<a class="arrow fa fa-arrow-down" data-animation-text="Troll" data-value="-1"></a>
</div>
CSS
.padding-container {
width: 60px;
margin: 100px;
}
#rating {
float: right;
font-size: 2.1em;
width: auto;
}
a.arrow {
display: inline-block;
position: relative;
cursor: pointer;
}
a.arrow:after {
content: attr(data-animation-text);
display: block;
position: absolute;
left: 50%;
transform: translateX(-50%);
text-align: center;
width: auto;
opacity: 0;
}
a.arrow.fa-arrow-up {
color: #FF0000;
}
a.arrow.fa-arrow-down {
color: #0000FF;
}
a.arrow.fa-arrow-up:after {
bottom: 100%;
}
a.arrow.fa-arrow-down:after {
top: 100%;
}
a.arrow.animate.fa-arrow-up:after {
animation-name: slideup, bounce;
animation-duration: 3s;
}
a.arrow.animate.fa-arrow-down:after {
animation-name: slidedown, bounce;
animation-duration: 3s;
}
#keyframes slideup {
from {
bottom: 100%;
opacity: 1;
}
to {
bottom: 300%;
opacity: 0;
}
}
#keyframes slidedown {
from {
top: 100%;
opacity: 1;
}
to {
top: 300%;
opacity: 0;
}
}
#keyframes bounce {
from {
font-size: 1em;
}
3% {
font-size: 1.25em;
}
6% {
font-size: 0.75em;
}
9% {
font-size: 1em;
}
}
JavaScript
function arrowAnimationEndHandler(e) {
var arrow = e.target;
if (typeof arrow === 'undefined') {
return;
}
arrow.className = arrow.className.replace(/\banimate\b/,'');
}
function arrowClickHandler(e) {
var arrow = e.target;
if (typeof arrow === 'undefined') {
return;
}
arrow.className = arrow.className.replace(/\banimate\b/,'');
setTimeout(function () {
arrow.className += ' animate';
}, 0);
ratingUpdateBusinessLogic(arrow);
}
function ratingUpdateBusinessLogic(arrow) {
if (typeof ratingElement === 'undefined') {
return;
}
var ratingDelta = parseInt(arrow.getAttribute('data-value'), 10);
ratingElement.innerHTML = parseInt(ratingElement.innerHTML, 10) + ratingDelta;
}
var ratingElement = document.getElementById("rating");
var arrows = document.getElementsByClassName("arrow");
for (var i = 0; i < arrows.length; i++) {
arrows[i].addEventListener("animationend", arrowAnimationEndHandler, false);
arrows[i].addEventListener("click", arrowClickHandler, false);
}
Now little bit of explanation:
The problem is quite complex and author is asking for a complete solution rather then explanation of one aspect which is not clear. I decided to give an answer because then I can outline the software design steps, which might
help someone else to solve another complex problem.
In my opinion the key to complex tasks is the ability to split them in smaller, which in turn are easier to approach. Let's try to split this task into smaller pieces:
We need to draw two arrows and a number.
Up and down arrows should have different colors.
We need to draw the arrow tooltips/labels next to them.
We need to animate the arrow tooltips/labels on user interaction.
We need to apply our business logic (change the rating) on user input.
Now let's try to solve those smaller problems one by one:
We need to draw two arrows and a number. Well, HTML is our friend here and below is a trivial html code. I'm using font-awesome to draw the actual arrow icons.
<div class="padding-container">
<span id="rating">0</span>
<a class="arrow fa fa-arrow-up"></a>
<a class="arrow fa fa-arrow-down"></a>
</div>
We want our arrows to be positioned in a certain way on the screen, let's make the arrows inline-blocks, and add a line-break between them, also add some CSS to line up:
.padding-container {
width: 60px;
margin: 100px;
}
#rating {
float: right;
font-size: 2.1em;
width: auto;
}
a.arrow {
display: inline-block;
cursor: pointer;
}
Our arrows should have different colors. Again trivial CSS here. The colors are not 100% like in the gif, but that is the question of making the screenshot and picking the right color - you can do it yourself.
a.arrow.fa-arrow-up {
color: #FF0000;
}
a.arrow.fa-arrow-down {
color: #0000FF;
}
We need to draw the arrow tooltips/labels next to them. Ok, that starts to be interesting. Let's use the :after pseudo-element to draw our tooltips, because those tooltips are part of representation (and not content), they don't need to be reflected in the html structure.
I use :after and not :before because font-awesome is using before for the arrow icon rendering ;) Let's also use absolute positioning to place them relative to the actual arrows. That gives us the following CSS:
a.arrow {
position: relative;
}
a.arrow:after {
content: attr(data-animation-text);
display: block;
position: absolute;
left: 50%;
transform: translateX(-50%);
text-align: center;
width: auto;
}
a.arrow.fa-arrow-up:after {
bottom: 100%;
}
a.arrow.fa-arrow-down:after {
top: 100%;
}
Now, our tooltips are rendered just next to the arrows, and we have the possibility to control the content of them through html, e.g. for translation purposes.
Tooltips are also centered relative to the arrows.
We need to animate the arrow tooltips/labels on user interaction.
We can animate elements by javascript and we can also do that via CSS. Doing it via CSS is way more efficient, so unless we need to support really old browsers, let's stick to CSS.
We need to implement two animations, one is tooltip fading together with lift/drop and the second one is the tooltip bounce.
Let's what CSS has to offer:
a.arrow:after {
opacity: 0;
}
a.arrow.fa-arrow-up:after {
animation-name: slideup, bounce;
animation-duration: 3s;
}
a.arrow.fa-arrow-down:after {
animation-name: slidedown, bounce;
animation-duration: 3s;
}
#keyframes slideup {
from {
bottom: 100%;
opacity: 1;
}
to {
bottom: 300%;
opacity: 0;
}
}
#keyframes slidedown {
from {
top: 100%;
opacity: 1;
}
to {
top: 300%;
opacity: 0;
}
}
#keyframes bounce {
from {
font-size: 1em;
}
3% {
font-size: 1.25em;
}
6% {
font-size: 0.75em;
}
9% {
font-size: 1em;
}
}
Now we see a nice label animation straight after we load the page. All that was done without a single line of JavaScript so far.
But the task says we need to animate on user interaction.
Ok, let's now add some javascript. But before that we need a possibility to trigger the animation, let's trigger it using CSS class: animate, our CSS then changes like
a.arrow.animate.fa-arrow-up:after {
animation-name: slideup, bounce;
animation-duration: 3s;
}
a.arrow.animate.fa-arrow-down:after {
animation-name: slidedown, bounce;
animation-duration: 3s;
}
Note added animate class. If we now manually add the class to the HTML - we will see the animation again. But we need that to happen on user click, well that is easy:
function arrowClickHandler(e) {
var arrow = e.target;
arrow.className += ' animate';
}
var arrows = document.getElementsByClassName("arrow");
for (var i = 0; i < arrows.length; i++) {
arrows[i].addEventListener("click", arrowClickHandler, false);
}
Now, if we load the page and click the arrow - we will see the animation, but only once. We need to find a way to reset it. Let's remove the animate class on animation finish.
function arrowAnimationEndHandler(e) {
var arrow = e.target;
if (typeof arrow === 'undefined') {
return;
}
arrow.className = arrow.className.replace(/\banimate\b/,'');
}
var arrows = document.getElementsByClassName("arrow");
for (var i = 0; i < arrows.length; i++) {
arrows[i].addEventListener("animationend", arrowAnimationEndHandler, false);
}
Now, we can click the arrow and see an animation as many times as we want. But there is a problem, we can't restart the animation if it is going already.
For that we need a little trick:
function arrowClickHandler(e) {
var arrow = e.target;
if (typeof arrow === 'undefined') {
return;
}
arrow.className = arrow.className.replace(/\banimate\b/,'');
setTimeout(function () {
arrow.className += ' animate';
}, 0);
}
as long as we remote the animate class - we give the browser a chance to execute it's code and stop the animation and then we add the animate class again.
We need to apply our business logic (change the rating) on user input.
Here is no rocket science, we read current value and update it according to the values we have assigned to arrows:
function arrowClickHandler(e) {
...
ratingUpdateBusinessLogic(arrow);
}
function ratingUpdateBusinessLogic(arrow) {
if (typeof ratingElement === 'undefined') {
return;
}
var ratingDelta = parseInt(arrow.getAttribute('data-value'), 10);
ratingElement.innerHTML = parseInt(ratingElement.innerHTML, 10) + ratingDelta;
}
var ratingElement = document.getElementById("rating");
UPDATE:
solution with glyphicons would require replacing css/html classes fa fa-arrow-up and fa fa-arrow-down with corresponding glyphicon classes, i.e.: glyphicon glyphicon-arrow-up and glyphicon glyphicon-arrow-down. After little thinking I also decided to unbind the custom css from library classes and added custom arrow-up and arrow-down classes to simplify the icon library replacement:
<a class="arrow arrow-up glyphicon glyphicon-arrow-up" data-animation-text="Sick!" data-value="1"></a>
<a class="arrow arrow-down glyphicon glyphicon-arrow-down" data-animation-text="Suck!" data-value="-1"></a>
CSS
a.arrow.arrow-up {
.
}
a.arrow.arrow-down {
...
}
a.arrow.arrow-up:after {
...
}
a.arrow.arrow-down:after {
...
}
a.arrow.animate.arrow-up:after {
...
}
a.arrow.animate.arrow-down:after {
...
}
You can use jquery animate to get that effect. Try this
EDIT:
for exact effect use jquery easing plugin and give
easeOutElastic easing effect
$("#select1").click(function() {
$(".nice").css("display","block");
$(".nice").animate({
top: -10,
}, 500, "easeOutElastic", function() {
// Animation complete.
$(".nice").css({"opacity":"1", "top":"10px","display":"none"});
});
});
$("#select2").click(function(){
$(".troll").css("display","block");
$(".troll").animate({
top: 130,
}, 500,"easeOutElastic", function(){
$(".troll").css({"opacity":"1", "top":"120px","display":"none"});
});
});
ul > li{
list-style:none;
}
span {
cursor: pointer;
}
.fa {
font-size: 55px;
text-indent: 200px;
margin-bottom: 20px;
margin-top:30px;
}
.nice{
position:absolute;
top:10px;
text-indent :190px;
display:none;
}
.troll{
position:absolute;
top:120px;
text-indent : 190px;
display:none;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.4.1/jquery.easing.min.js"></script>
<ul>
<li>
<p class="nice">Nice</p>
<span id='select1'><i class="fa fa-long-arrow-up" aria-hidden="true"></i></span></li>
<li><span id='select2'><i class="fa fa-long-arrow-down" aria-hidden="true"></i></span>
<p class="troll">Troll</p>
</li>
</ul>
Just Add the text and show/hide it with the help of fadeout and fadein property of Jquery.
Check your updated fiddle
$("span").click(function() {
if($(this).attr('id')=='select1')
{
$("#downText").fadeOut(300);
$("#upText").fadeIn(300);
}
else
{
$("#upText").fadeOut(300);
$("#downText").fadeIn(300);
}
$("span").css("color", "grey");
$(this).css("color", "red");
});
$("fa").click(function(){
$("fa").fadeTo("slow", 0.15);
});
Add a setTimeout to make the text fade out after a few milliseconds:
$("span").click(function() {
$("span").css("color", "grey");
$(this).css("color", "red");
});
$("#select1").click(function() {
$("#down").fadeOut(300);
$("#up").fadeIn(300);
setTimeout(function() {
$("#up").fadeOut(300); // fade out the up text
}, 300); // delay of 0.3s before fading out
});
$("#select2").click(function() {
$("#up").fadeOut(300);
$("#down").fadeIn(300);
setTimeout(function() {
$("#down").fadeOut(300); // fade out the down text
}, 300); // delay of 0.3s before fading out
});
jsFiddle: https://jsfiddle.net/qze7mqj4/16/
I also added a position:absolute; to the fading text so that it doesn't make the arrows "jump" around.
You can read more about setTimeout here: http://www.w3schools.com/jsref/met_win_settimeout.asp
Basically it tells the browser to execute a function after a specified number of milliseconds, in this case, we tell the browser to fadeOut() the text after 300ms.

How to animate the ajax/json response?

This is my piece of HTML code
<div class='qna_div'>
<div class="q_div"></div>
<div class="a_div"></div>
</div>
I make a Ajax request and get a json response for every click by the user and i append the q_div and a_div using the jquery function
$('.q_div').append(data.question);
$('.a_div').append(data.answer);
I have css keyframe animation on both q_div and a_div to come from right to left of the screen. But the animation works only on the first load of the page and not on the 'append' function for the json response. I am new to css and animations. help me out for the responsive animations
animation in css3 code:
.q_div {
animation: q_ani 2s;
}
#keyframes q_ani {
from{margin-left: 50px;}
to{margin-left: default;}
}
a possible solution using css animation
$(function() {
var cssAnimationEnd = "webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend";
$('.click').click(function() {
$('.q_div, .a_div').addClass("animate").one(cssAnimationEnd , function() {
$('.q_div, .a_div').removeClass("animate");
});
});
})
.q_div.animate {
animation: q_ani 2s;
}
.a_div.animate {
animation: q_ani 2s;
}
#keyframes q_ani {
from {
margin-left: 150%;
}
to {
margin-left: default;
}
}
/*for test purpose*/
.q_div,
.a_div {
position: relative;
height: 20px;
width: 500px;
background: #ddd;
margin-top: 10px;
}
.qna_div {
padding: 20px;
width: 500px;
background: #333;
}
body {
overflow: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="click">go</button>
<div class='qna_div'>
<div class="q_div"></div>
<div class="a_div"></div>
</div>
You should delete and add .q_div class each time you need animation appear
You could use jquery to animate your divs. Put this code in the success ajax callback:
// First put your divs to the right
$('.q_div, .a_div').css('right','0');
// Do the animation
$('.q_div, .a_div').animate({
left: 0,
}, 1000);
https://jsfiddle.net/a8cq9yj1/1/
I hope it can help you,i just simple using the classList function and some SASS style rule
http://jsbin.com/vosuvam/2/edit?js,output

How can I get only the specific H3 I am hovering over to show and not all of them?

I am trying to have text appear over each image as the user hovers over that specific image. I don't want all of the text for every image to appear when a user hovers over one image. I have it where only the one photo becomes opaque but right now the text shows up for every image when hovering over any image.
HTML:
<div class="image">
<img class="projectImage" src="images/peralta.png" alt="">
<h3 class="hiddenH3">This is a test!</h3>
</div>
SCSS:
.image {
position: relative;
width: 100%;
.projectImage {
width: 100%;
transition: all 0.5s ease-in;
}
.hiddenH3 {
display: none;
position: absolute;
top: 45%;
width: 100%;
}
}
JS:
$('.projectImage').on("mouseover", function() {
$(this).closest('.projectImage').addClass("coolEffect");
$('.hiddenH3').fadeIn(1000);
});
$('.projectImage').on("mouseout", function() {
$(this).closest('.projectImage').removeClass("coolEffect");
$('.hiddenH3').fadeOut(1000);
});
Use .next along with this
$('.projectImage').on("mouseover", function() {
$(this).addClass("coolEffect");
$(this).next(".hiddenH3").fadeIn(1000);
});
$('.projectImage').on("mouseout", function() {
$(this).removeClass("coolEffect");
$(this).next(".hiddenH3").fadeOut(1000);
});
You can also remove .closest(".projectImage") as this refers to that image.
Why don't you do this with CSS? Since the selectors needed are very old and entrenched, you can do something like this:
.projectImage + h3 {
transition: opacity 1000ms;
opacity: 0;
}
.projectImage:hover + h3 {
opacity: 1;
}
This will fade in your h3 when you hover over the project image, as long as you structure it in that way (i.e., ing, then h3). You can also remove the classes cooLEffect and hiddenh3 as we have defined that by only targeting the h3 that comes after a project image.
The fancy transition effect will only work on modern browser, but older browsers gracefully degrade.
Edit: SASS / LESS
.image {
.projectImage {
& + h3 {
transition: opacity 1000ms;
opacity: 0;
}
&:hover + h3 {
opacity: 1;
}
}
}

Categories

Resources