Why does .toggle not work for the first function? - javascript

I've created a simple menu with a button of which when clicked on should change the size of the menu at alternating heights, I keep receiving some weird action of which my menu just shrinks to the bottom left of the document disappears then reappears the same height; that's how I found out the second function was being executed but not the first. I've changed the code many times but I can't find a solution, maybe someone can help. Here's my code.
$(document).ready(function () {
$("#HideShow").addClass("fa fa-bars").click(function () {
$("#editor").toggle(function () {
$("#editor").slideToggle("fast", function () {
$("#editor").height(20);
});
}, function () {
$("#editor").slideToggle("fast", function () {
$("#editor").height(150);
});
});
});
});
maybe I'm just not getting it, I am fairly new to this so if I am doing something wrong PLEASE correct me.

I think you are not quite following the jQuery API. If I understood correctly you should probably use classes for opened and closed menus. Then you can use a simple jQuery event to toggle the classes. Something like this:
Code:
$('#HideShow').click(function() {
$(this).toggleClass('closed');
});
CSS:
<style>
.closed {
height: 20px;
}
</style>

The reason is because when .toggle() is called with more than one parameter, the first one is expected to be "a string or number determining how long the animation will run", and the last one "a function to call once the animation is complete" (see documentation). This is why the first function you pass in is not executed, while the second one is.
As others have already proposed, one possible way to get what you want would be:
CSS:
#editor {
height: 150px;
}
#editor.closed {
height: 20px;
}
Javascript:
$("#HideShow").click(function() {
$("#editor").toggleClass('closed');
});

Related

capture setTimeout timerID when setTimeout is used in an if loop

I'm using setTimeout to create a pause in a loop (on mouseenter) and need to capture the timer ID so it can be stopped on mouseleave.
I thought that would be a simple task… before I tried to code it.
I have a gallery of thumbnails and on hovering over a thumbnail I want to cycle though a series of images (in an endless loop); kind of like a mini-carousel. I achieve this with the common method of swapping out the thumbnail’s source file path; I capture and store the thumbnail’s file path, loop through an array of images then replace the original thumbnail on mouseleave. Nothing complicated.
I coded this up and everything worked fine except on mouseenter the function looped through the entire array of images no matter how briefly the mouse hovered. I eventually discovered that you can’t actually pause a function or stop it but by wrapping it in a setTimeout and using a boolean flag you can create that effect. This is the answer I found https://stackoverflow.com/a/19192399 by user1693593, it’s really simple and works really well.
var doLoop = false;
function loopy() {
if (doLoop === true) {
setTimeout(function () {
// code to loop through array of images
loopy();
}, 11);
}
};
I'm using jQuery's hover method to set the flag.
$(".thumbnails").hover(function() {
doLoop = true;
}, function() {
doLoop = false;
});
So I coded that up and it worked perfectly when you hover over the first thumbnail but when you move to a new thumbnail it all goes haywire. I figured out this was because the first timeout wasn’t being cancelled and subsequent timeouts were interfering with it (and each other). I can see from various Stack Overflow questions that this is a common problem. I discovered that setTimeout returns an ID that you need to capture if you want to cancel it with clearTimeout.
So I found an example on MDN setInterval whereby you store the timeout ID in a variable. It looked simple enough so I coded that up and it worked perfectly. I can see in the console all the timeouts being set (with unique IDs) and cancelled as the mouse moves over the thumbnails… but now I can’t get the loop to work.
I can’t understand why this is so complicated in JavaScript, surely something like this is a common requirement.
Can someone please take pity on a relative newbie and explain how I can code user1693593's example so that it works when mousing over multiple elements. I don’t mind if it uses setTimeout or setInterval.
Please don’t mark this as a duplicate – I’ll understand if someone does – but I’ve been all over Stack Overflow (plus MDN and W3Schools) and I can’t find an example that specifically answers this question, certainly not one that I can understand anyway.
Store the reference somewhere and cancel it.
var timer = null
function addOne (elem) {
elem.textContent = (+elem.textContent + .1).toFixed(1)
}
$(".foo")
.on("mouseenter", function () {
var elem = this
timer = window.setInterval(function () { addOne(elem) }, 100)
}).on("mouseleave", function () {
if (timer) window.clearInterval(timer)
})
div.foo {
width:100px;
line-height: 100px;
border: 1px solid black;
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="foo">1</div>
<div class="foo">1</div>
<div class="foo">1</div>
<div class="foo">1</div>
<div class="foo">1</div>
Just keep track of the element that’s currently doing the loop instead of a boolean true/false.
var loopEl;
function loopy() {
if (loopEl) {
setTimeout(function () {
// code to loop through array of images
// do something with loopEl
loopy();
}, 11);
}
};
$(".thumbnails").hover(function() {
loopEl = this;
}, function() {
loopEl = false;
});

jQuery transitions: on load and after for each click, an addClass

Well, let me try to explain my gol:
I did a small project (Random Quote Machine from ferecodecamp.com), and it is quite functional. But I want to make it like an slide show (Power Point) with transitions.
See what I have for now Random Quote Machine project
The page should load the quote making a transition from zero opacity to total.
2 .When I click button generate, it should change the quote and again, it should be a quote thate comes from 0 opacity to 1.
The CSS could be something like:
span, i, footer{
opacity: 0;
}
.transitions {
transition-duration: 1s;
opacity: 1;
}
span, i, footer goes from 0 to 1 on opacity with a transition-duration of 1 second.
I tried some jQuery but nothing had gone well the way I want
<script type="text/javascript">
//for page load
$(".quote").load(function(){
$(".quote").addClass("transitions");
});
//for new quote generated
$(".button").click(function() {
$(".quote").fadeOut("slow", function() {
$(this).addClass("quote");
});
$(".quote").fadeIn("slow", function() {
$(this).addClass("quote");
});
});
</script>
Fist part doesn't work at all. The .load event has never worked and .ready just works with a .click event.
Second part, partialy works, but it first desapears and after apears. I want to be desapeared (0 opacity) to total apear...
I've been trying for two long days and nothing is going realy well. I would be really glad in read some suggestions.
Thanks in advance!
I would do it like this:
// equivalent to $(document).ready(function()
$(function() {
// define an array of elements to fade
var elements = [$('#quote'), $('#author')];
fade(); // call a custom function defined below which will execute on page load
// on .button click, call the same function
$('.button').click(fade);
function fade() {
// for each element in elements (defined above), execute jQuery's hide() method and then fadeIn()
$.each(elements, function(index, element) {
element.hide().fadeIn();
});
}
});
If you paste this in the console within your project, it works nicely.
note: $.load() was deprecated in jQuery version 1.8.
This should be what you wanted:
$(document).ready(function(){
$(".quote").fadeIn(1000);
});
$(".button").click(function() {
$(".quote").fadeOut(1000, function() {
// change the quote here
$(".quote").fadeIn(1000);
});
});
.quote {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="button">new</button>
<div class="quote">quote</div>

Keep the hover state on the last clicked menu item

I have added a nice (jquery + css) navigation menu to my website, but there's a small problem. When I click on a menu item, the light blue box jumps back to the first item, and I would like the box to stay on the clicked item, but I have no clue how to make it happen.
Here's an example: http://jsfiddle.net/Stylock/ta8g4/
In that example, it actually works how I want, but on my website it doesn't work for some reason. Any help would be much appreciated.
You could add a class to the item like .selected
And in your css you apply the same style to the .selected than the :hover
http://api.jquery.com/addClass/
Or you cloud also modify the css using jQuery. But the first solution is more flexible.
Edit: Use the callback function to add/remove class, after your effect
This might be a solution to the right direction:
Onclick check if the menu already has a classname to get the background changed
remove that class from there
Add the class where you clicked
some minor css changes are needed and u will have solved it
have a great day
you can add a class when other page loads like to add on all pages like
this is bad one
<script type="text/javascript">
$(window).load(function () {
$("#index").toggleClass("highlight");
});
$(window).unload(function () {
$("#index").toggleClass("highlight");
});
</script>
site i used this at http://www.hoteloperaindia.com/
or like this short one to add this to master page
<script>
$(function () {
var loc = window.location.href; // returns the full URL
if (location.pathname == "/") {
$('#home').addClass('active');
}
if (/index/.test(loc)) {
$('#home').addClass('active');
}
if (/about/.test(loc)) {
$('#about').addClass('active');
}
if (/accommodation/.test(loc)) {
$('#accommodation').addClass('active');
}
if (/gallery/.test(loc)) {
$('#gallery').addClass('active');
}
if (/tariff/.test(loc)) {
$('#tariff').addClass('active');
}
if (/facilities/.test(loc)) {
$('#facilities').addClass('active');
}
if (/contact/.test(loc)) {
$('#contact').addClass('active');
}
});
</script>
site where i used this one http://rtshotel.in/
change it with your code

JavaScript HTML, clickable button from IMG tag

I am trying to do a clickable button with javascript. I am doing the following
document.getElementById("nav").onmousedown = function() { this.src="img1.png"; return false;}
document.getElementById("nav").onmouseout = function() { this.src="img.png"; return false;
}
What am I missing with events? By the way, I did it before by encapsulating events in single initAll foo makes the button clickable but slow on the server.... When I click it opens the link before I see my button pressed animation... Any info?
Do you really want to use javascript here? Maybe CSS will fit your needs better?
#nav {
background: url('img1.png') no-repeat 0 0;
}
#nav:active {
background: url('img2.png') no-repeat 0 0;
}
Have you tried using jquery's .animate, and then in the callback function sending the user to the link?
Try replacing this with document.getElementById("nav") and see if it does anything.

Jquery mouse-over fade-in/out (best practices)

I've got working Jquery code to fade in/out descriptive text in a div below the question. The problem? The solution is not very elegant. Here's what I've got:
$("#home").mouseover(function() {
$("#homeText").fadeIn("slow");
});
$("#homeText").mouseout(function() {
$("#homeText").fadeOut();
});
I know there is better way to do this, I'm just not sure what it is.
you could use hover, the first function will act on a "hover over" and the second will act on a "hover out"
The documentation is located here: http://docs.jquery.com/Events/hover
$("#home").hover(function(){
$("#homeText").fadeIn("slow");
},
function(){
$("#homeText").fadeOut();
});
How about 3 lines?
<script>
$(function () {
$('#home').hover(function() {
$('#homeText').fadeToggle("slow");
});
});
</script>
Elegant enough?
Jon, Great advice! I used as a staring point though for a more complete solution. Doing this with just the basic hover would still leave me with a hover call for single menu item..A lot of redundant code. So using what you suggested, I came up with this:
$('.topMenu').hover(function()
{
$('#_'+this.id).fadeIn("slow");
},
function ()
{
$('#_'+this.id).fadeOut();
});
});
All menu items are given the topMenu class and ID. The corresponding div to display is the same id as the menu item, just prefixed with _
Example:
....
Stuff about us!
...
Thanks!
$(function () {
$('#home').hover(function() {
$('#homeText').fadeIn("slow");
});
$('#home').mouseout(function() {
$('#homeText').fadeOut("slow");
});
});

Categories