I want to rotate an object with .css
First click: 180°
Second click: back to normal position (+180°)
Now i need a function, to detect, if the current click is even or odd ...
Tried it with this:
$(function() {
$(".board-element").find(".category div").click(function() {
$(this).parent().parent().find(".board-boards").slideToggle(1000);
var clicks = $(this).data('clicks');
if (clicks) {
$(this).css("transform", "none");
} else {
//first click
$(this).css("transform", "rotate(180deg)");
}
});
});
It works fine, i klick on the element, the object rotates ...
But when i click again, nothing happens ...
I hope you can understand my problem,
Thanks :)
Cleaner approach would be toggling class name so you don't have to deal with click counts:
$(".board-element").find(".category div").click(function() {
$(this).parent().parent().find(".board-boards").slideToggle(1000);
$(this).toggleClass('rotate');
});
CSS:
.rotate {
transform: rotate(180deg);
}
Additional benefit is that if you decide to support vendor prefixes you don't have to change javascript code for this, just extend CSS.
You do not seem to be setting a data('clicks') value anywhere...
$(function() {
$(".board-element").find(".category div").click(function() {
$(this).parent().parent().find(".board-boards").slideToggle(1000);
var clicks = $(this).data('clicks');
// Save the new flag value
$(this).data('click', true);
if (clicks) {
$(this).css("transform", "none");
} else {
//first click
$(this).css("transform", "rotate(180deg)");
}
});
});
Notes:
You should avoid things like .parent().parent() and use closest('.board-element') or similar instead.
#dfsq has posted a cleaner solution. This one was just to explain where you went wrong :)
You could use a trigger variable, that changes its value after animation 2 directions (you have to inizialize it ouside the function):
var already_turned = false;
$(function() {
$(".board-element").find(".category div").click(function() {
$(this).parent().parent().find(".board-boards").slideToggle(1000);
var clicks = $(this).data('clicks');
if (clicks && already_turned) {
$(this).css("transform", "none");
already_turned = false;
} else {
//first click
$(this).css("transform", "rotate(180deg)");
already_turned = true;
}
});
});
Related
I know this might be silly but I would like to know if there is a way to realize.
Basically, I would like the dropdown-content element to 'KEEP DISPLAYING' even after 3 secs of mouse moving-out of the parental 'dropbtn' button or element.
E.g. code:
$(function() {
$('#dropbtn').hover(function() {
$('.dropdown-content').css('display', 'block');
}, function() {
// on mouseout:
setTimeout(function(){$('.dropdown-content').css('display', 'none');}, 3000);
});
$('.dropdown-content').hover(function(){
$('.dropdown-content').css('display', 'block');
},function(){
$('.dropdown-content').css('display', 'none');
})
});
Current issue is that setTimeout() function is overriding my desired way on this particular line of JS code:
$('.dropdown-content').css('display', 'block');
In another word, I want setTimeout() to be effective if and only if I set not my mouse cursor on 'dropdown-content' div.
Hope someone can help out :)
Instead of using hover, you could use mouseenter/mouseleave to 'toggle' the .dropdown-content, except the delay of 3s on mouseleave:
$(function() {
var dropdownTimeout = null;
$('#dropbtn').mouseenter(function() {
if(dropdownTimeout) {
clearTimeout(dropdownTimeout);
dropdownTimeout = null;
}
$('.dropdown-content').css('display', 'block');
});
$('#dropbtn').mouseleave(function() {
dropdownTimeout = setTimeout(function(){$('.dropdown-content').css('display', 'none');}, 3000);
});
});
Ok, I have totally retooled my approach (thank you superUntitled) and am making progress... I have an unordered list that users can toggle and my only remaining issue is that when I expand some items, and then click "Show All Cities" not all of the arrows go in the same direction. All the arrows change, including the ones on the list items already expanded. Any suggestions on how to resolve this?
Here's my new Javascript:
$("#Names .airports").hide();
$("#Names .close").hide();
$('#Expand').click(function(){
$('h2').children(".close").toggle();
$('h2').children(".arrow-down").toggle();
if($(this).text() == 'Hide All Cities')
{
$(this).text('Show All Cities');
$('#Names .airports').slideUp('fast');
}
else
{
$(this).text('Hide All Cities');
$('#Names .airports').slideDown('fast');
}
});
$("#Names h2").addClass("state").click(function() {
$(this).parent().children(".airports").slideToggle('fast')
$(this).children(".close").toggle();
$(this).children(".arrow-down").toggle();
Here's the fiddle illustrating the remaining problem:
http://jsfiddle.net/d3pxx8ds/127/
Thanks in advance
Here's my old JavaScript (reference only now):
$(function() {
$('li.state').prepend('<img src="http://png-4.findicons.com/files/icons/2227/picol/32/arrow_sans_up_32.png" class="arrow"/>');});
$('.stateNames ul').hide();
$('.stateNames li').click(function(e) {
e.stopPropagation();
$(this).find('ul').toggle();
var value = 0
$(".arrow").rotate({
bind:
{
click: function(){
value +=180;
$(this).rotate(value)
}
}
});
});
All i did was replace the order, i moved the .rotate to happen before the .toggle functions this would read the rotate first and subsequently do the toggle function thus setting the variable to 180 instead of waiting for the toggle to start, not allowing the variable to be set
$(function() {
$('li.state').prepend('<img src="http://png-4.findicons.com/files/icons/2227/picol/32/arrow_sans_up_32.png" class="arrow"/>');
});
$('.stateNames ul').hide();
var value = 0
$(".arrow").rotate({
bind : {
click : function() {
value += 180;
$(this).rotate(value)
}
}
});
$('.stateNames li').click(function(e) {
e.stopPropagation();
$(this).find('ul').toggle();
});
$(function() {
$('li.state').prepend('<img src="http://png-4.findicons.com/files/icons/2227/picol/32/arrow_sans_up_32.png" class="arrow"/>');
});
$('.stateNames ul').hide();
var value = 0
$(".arrow").rotate({
bind:
{
click: function(){
value +=180;
$(this).rotate(value)
if (value==180){
value=360;
}
else{
value=180;
}
}
}
});
$('.stateNames li').click(function(e) {
e.stopPropagation();
$(this).find('ul').toggle();
});
I added the if statement and it works for one full go around but on the next toggle the arrow doesn't rotate hope that helps for now i will keep looking in to it
I'm trying to make it so that when you click a link, it removes a div (with some paragraphs and text) and inserts another div (with some paragraphs and some text). I'm using jQuery to fade those in and out. The fading out of the original div works when you click the link, and then I have a switch case to determine what gets faded in. However, the fadeIn, set to 'slow', appears to be occurring immediately.
Here's the relevant piece of code (the rest is just other cases):
$(document).ready(function() {
$('.nav-link').click(function() {
var linkClicked = $(this).attr("id");
$('.content').fadeOut('fast');
switch(linkClicked) {
case 'home':
console.log("linkClicked = "+linkClicked);
$('#home-content').fadeIn('slow', function() {
$(this).css("display", "inline");
$(this).css("opacity", 100);
});
break;
Edit:
So after changing fadeTo to fadeOut, and changing "slow" in the fadeOut to "fast", it worked well and transition the way I want. However, whenever I click "home" now it will move the div to a "block" position, (it spits it to the lower left corner) before shoving itself back into the right spot in the center of my container. It ONLY does this when I click home and no other of my sidenav links...which are all running the exact same code (home just is the first one in the switch case). Any ideas?
If you want the fadeIn to start after the fadeTo has completed, you'll want to use a callback function. Also, since you're fading to 0 opacity, just use fadeOut:
$(document).ready(function() {
$('.nav-link').click(function() {
var linkClicked = $(this).attr("id");
$('.content').fadeOut('slow', function() {
// this code will begin once fadeTo has finished
switch(linkClicked) {
case 'home':
console.log("linkClicked = "+linkClicked);
$('#home-content').fadeIn('slow', function() {
$(this).css("display", "inline");
$(this).css("opacity", 100);
});
break;
});
});
Without seeing your HTML, it's a little difficult to understand the exact outcome you're trying to achieve, but here is a JSfiddle with your code above.
http://jsfiddle.net/W9d6t/
$('.nav-link').click(function() {
var linkClicked = $(this).attr("id");
//$('.content').fadeTo('slow', 0);
switch(linkClicked) {
case 'home':
console.log("linkClicked = "+linkClicked);
$('#home-content').fadeIn('slow', function() {
$(this).css("display", "block");
alert('All done!');
});
}
});
From my understanding of what you are trying to do, I believe you simply need to do this:
$('#home-content').fadeIn('slow');
(the fadeIn function automatically sets the display property to inline/block)
Also, while your implementation correct, it's simpler to do:
$('.content').fadeOut('slow');
(simplified jsFiddle)
You just need to add a callback to fadeOut so that it executes after the animation is done:
$(document).ready(function() {
$('.nav-link').click(function() {
var linkClicked = $(this).attr("id");
$('.content').fadeOut('slow', function() {
switch(linkClicked) {
case 'home':
console.log("linkClicked = "+linkClicked);
$('#home-content').fadeIn('slow', function() {
$(this).css("display", "inline");
$(this).css("opacity", 100);
});
break;
});
I am quite new to writing my own jquery functions and I find debugging it very difficult as the error messages aren't too helpful when put into google.
I have a navigation menu for page anchors that when each one is clicked the screen scrolls to the anchor, the elements will change color depending on which one and the hover color will also change. Very simple really, I think.
The scrolling always works, the animate works occasionally and the hover works put usually I have to click the link twice. The return false only works on the first link you click.
This uses the scrollTo and animate-colors plugins.
Can anyone tell me what I'm doing wrong?
$(".scrolltoanchor").click(function() {
$('a').removeClass('selected');
$(this).addClass('selected');
$.scrollTo($($(this).attr("href")), {
duration: 750
});
switch ($(this).attr("id")) {
case 'personal':
$('.scrolltoanchor').animate({color: '#E4D8B8'});
$(".scrolltoanchor").hover(
function() {
$(this).css('color', 'blue');
},function(){
$(this).css('color', '#E4D8B8');
});
break;
case 'achievements':
$('.scrolltoanchor').animate({color: '#ffffff'});
$(".scrolltoanchor").hover(
function() {
$(this).css('color', 'red');
},function(){
$(this).css('color', '#ffffff');
});
break;
case 'skills':
$('.scrolltoanchor').animate({color: '#dddddd'});
$(".scrolltoanchor").hover(
function() {
$(this).css('color', 'orange');
},function(){
$(this).css('color', '#ffffff');
});
break;
}
return false;
});
Sorry to ask to be spoonfed, but I have followed what I believed to be the correct syntax from what I have learnt. Is there something I should know that is stopping this working as I expect?
EDIT: Sorry I forgot, I get this error on the (on average) every second click of a scrolltoanchor link
Uncaught TypeError: Cannot read property '0' of undefined
I can't spot a real pattern. Sometimes it seems to happen only on ones that havent been clicked before, sometimes not.
Thanks
You're taking the wrong approach.
You should bind the hover handlers once, and decide the colors based on which one was clicked.
Simplest way would probably to store the color data in a lookup table where the keys are the IDs of the elements.
var ids = {
personal: {
over:'blue',
out:'#E4D8B8'
},
achievements: {
over:'red',
out:'#ffffff'
},
skills: {
over:'orange',
out:'#dddddd'
}
};
var current = ids.personal;
Then bind the handlers once, and use the id of the one clicked to set the current color set.
var scroll_anchors = $(".scrolltoanchor");
scroll_anchors.hover( function() {
$(this).css( 'color', current.over );
},function(){
$(this).css( 'color', current.out );
});
scroll_anchors.click(function() {
$('a.selected').removeClass('selected');
$(this).addClass('selected');
$.scrollTo($($(this).attr("href")), { duration: 750 });
current = ids[ this.id ]; // set the current color set based on the ID
scroll_anchors.animate({ color: current.out });
return false;
});
When you call .hover() multiple times, you aren't removing the old event handlers, you are just adding a new one. Each handler will be called each time. You'll want to call .unbind("hover") first:
$(".scrolltoanchor").unbind("hover").hover(function () {
...
});
You can also bind to hover outside of the switch statement to eliminate some of the code duplication:
$(".scrolltoanchor").click(function () {
$('a').removeClass('selected');
$(this).addClass('selected');
$.scrollTo($(this.href), {
duration: 750
});
var off, on;
switch (this.id) {
case 'personal':
off = '#E4D8B8';
on = 'blue';
break;
case 'achievements':
off = '#ffffff';
on = 'red';
break;
case 'skills':
off = '#dddddd';
on = 'orange';
break;
}
$('.scrolltoanchor')
.animate({ color: off })
.unbind("hover")
.hover(function () {
$(this).css('color', on);
}, function () {
$(this).css('color', off);
});
return false;
});
I have make this: This In the right you see a red button. When you click on the red button. The content screen with the text is coming. But i have a question of this. Can i make this with a other animation. If you hold your mouse. Then you can slide open. With your mouse button to left. Then the content box open. Do you understand it? I hope you can help me.
You can see the code on jsfiddle. And you can change it there. I hope you can help me. I am a starting javascripter. And how And have no idea how I can make this.
To implement dragging, you can make use of mousedown/mouseup/mousemove like this: http://jsfiddle.net/pimvdb/25y4K/8/.
$(function () {
"use strict";
var box = $(".what-is-delicious"),
button = $(".what-is-delicious > a");
var mouseDown = false,
grabbed = 0,
start = -303;
button.mousedown(function(e) {
mouseDown = true;
$('*').bind('selectstart', false); // prevent selections when dragging
grabbed = e.pageX; // save where you grabbed
$("body").append('<div class="background-overlay"></div>');
});
$('body').mouseup(function() {
mouseDown = false;
$('*').unbind('selectstart', false); // allow selections again
$(".background-overlay").remove();
start = parseInt(box.css('right'), 10); // save start for next time
// (parseInt to remove 'px')
}).mousemove(function (e) {
if(mouseDown) { // only if you are dragging
// set right to grabbed - pageX (difference) + start 'right' when started
// dragging. And if you drag too far, set it to 0.
box.css("right", Math.min(grabbed - e.pageX + start, 0));
}
});
});
Here is an updated fiddle. Basically I just did a couple of things:
Changed the handler from "click" to "mouseenter"
Added a "mouseleave" handler that does the opposite thing
Put the handlers on the "what-is-delicious" container instead of the <a>
The code:
$(function () {
"use strict"
var box = $(".what-is-delicious"),
button = $(".what-is-delicious > a");
box.mouseenter(function (e) {
e.preventDefault();
if ($(button).hasClass("open")) {
} else {
$("body").append('<div class="background-overlay"></div>');
button.addClass("open");
box.animate({ right: "0"}, 750);
}
}).mouseleave(function (e) {
e.preventDefault();
if ($(button).hasClass("open")) {
$("body").find('div.background-overlay').remove();
button.removeClass("open");
box.animate({ right: -303}, 750);
} else {
}
});
});
The "preventDefault()" calls aren't really necessary anymore but I left them there.
I would assume you are toggling the Style.Display of the DIV currently in an OnClick() event.
The same code can be called from a Hover() or MouseOver()