How to remove the delay in jQuery .hover() method - javascript

I tried to make my nav element change color as the document scrolls, I also want to make the hover state change color dynamically. But there's a delay, I have to wait for a fraction of seconds before I can hover and change the color. Can I remove the delay? Or better, when I am hovering on a menu, can I make the hovered color change by scrolling? I feel like I'm so close to the solution yet I can't find it.
Here are the jQuery codes:
$(document).ready(function () {
$(document).scroll(function () {
var h = $(window).scrollTop() / $(document).height() * 360;
if (h <= 180) {
hhover = h + 180;
} else {
hhover = h - 180;
}
$("a").css({
"color":"hsl(" + h + ",100%,50%)","transition":"0.2s ease"});
$("a").hover(
function () {
$(this).css(
"color", "hsl(" + hhover + ",100%,50%)");
},
function () {
$(this).css(
"color", "hsl(" + h + ",100%,50%)");
});
});
});
Please find my jsFiddle below:
https://jsfiddle.net/dtZDZ/1036/
Thank you!

In your CSS code:
.nav-links a:hover {
color: hsl(180,100%,50%);
transition: ease;
}

Delete all CSS transition definitions from javascript code and from styles.

Related

Improve background animation color change

I want to make an background color animation change when the user gets to the specific section.
Here is the jQuery code I wrote:
var initialColors = [];
$('section.changecolorbg').each(function(i){
initialColors[i] = $(this).css("backgroundColor");
});
$(window).scroll(function() {
$('section.changecolorbg').each(function(i){
if(isScrolledIntoView($(this))){
var bgc = initialColors[i];
$(this).parent().children('.changecolorbg').each(function(){
$(this).css("backgroundColor", bgc);
});
}
})
});
function isScrolledIntoView(elem)
{
var hT = elem.offset().top,
hH = elem.outerHeight(),
wH = $(window).height(),
wS = $(this).scrollTop() + 200;
return (wS > (hT+hH-wH))
}
The sections will have a background-color initially, this is why I saved them in a variable.
The problem with this is that it's working pretty slow. I think is that because all the checking needs to be done in the .scroll function.
Is there a way I can improve the code?
P.S. The effect I'm trying to achieve is same as on http://sfcd.com/
You can try something like this using hsl colors in CSS (hue, saturation, lightness) and deriving the hue value from the window.scrollY position:
var body = document.getElementsByTagName('body')[0];
function changeHue() {
var hue = (window.scrollY / 20);
body.style.backgroundColor = 'hsl('+hue+', 100%, 50%)';
}
window.addEventListener('scroll', changeHue, false);
body {
background-color: hsl(0,100%,50%);
}
div {
height: 10000px;
}
<div></div>

How to make elements interact with each other and position with jquery

$(document).ready(function() {
//ENTRANCE
$("#first").css("top", -1000);
setTimeout(function() {
$("#first").animate({
top: 10
}, 400);
}, 200);
$("#second").css("top", -1000);
setTimeout(function() {
$("#second").animate({
top: 10 + 45 + 15
}, 400);
}, 400);
$("#third").css("top", -1000);
setTimeout(function() {
$("#third").animate({
top: 10 + 45 + 45 + 30
}, 400);
}, 600);
$("#four").css("top", -1000);
setTimeout(function() {
$("#four").animate({
top: 10 + 45 + 45 + 45 + 45
}, 400);
}, 800);
//EXIT
$('#first').on('click', function() {
$('#first').toggle();
$('#second').animate({top: 5}, 400);
});
$('#second').on('click', function() {
$('#second').toggle();
$('#third').animate({top: 5}, 400);
});
$('#third').on('click', function() {
$('#third').toggle();
$('#four').animate({top: 5}, 400);
});
$('#four').on('click', function() {
window.location.reload();
});
});
`
I have been trying for a while to make elements interact with each other using jquery, Here is a
Fiddle of my code.
I have although been having a few hiccups.
In a real world environment, elements may not be called in ascending or logical order.
Items do not animate properly when closed, there are gaps and in some cases, some items do not move depending on which is clicked.
There may be more than 4 items.
Here is my question: How can i make the elements animate and cover properly regardless of which item is clicked and what order the items are sorted.
please see this fiddle
var elements = $('.menu');// Here you can write any selector to get list of elements
elements.on('click', function() {
$(this).toggle();
var nextEleemnts = $(this).nextAll('.menu'); // Same selector will follow here
for (var i = 0; i < nextEleemnts.length; i++) {
var topPos = $(nextEleemnts[i]).position().top - 60; //little bit of counting
$(nextEleemnts[i]).animate({
top: topPos
}, 400);
}
});
There is also a good solution and straight forward solution provided to you by a guy in comment, For this you need to do a bit of change in CSS aswell, so if you don't want to do it, then you can take my approach aswell
Here I am talking an alternate approach, here what I am doing whenever you click on any element I am finding it's next siblings and position them up by 60 pixels
If I were you, I would consider using jqueryUI
But maybe you have some restrictions of some kind.
I came up with a solution, in which I use jquery gt selector to select elements after the one clicked.
Please note that html is almost empty, which allows to add as many elements as you like.
(By the way I wouldn't make elements position absolute as well, but that's another story.
$(document).ready(function() {
"use strict";
var childCount = 12;
// some templating library would make a better job
for (var i = 0; i < childCount; ++i) {
var child = $("<div>" + i + "th div </div>");
child.css("background-color", "#" + ((1 << 24) * Math.random() | 0).toString(16));
child.css("top", i * 50);
$("#parent").append(child); // add any transition here
}
var reset = $("<div id='reset'>Reset</div>")
.css("background-color", "black")
.css("color", "white")
.css("top", childCount * 50);
$("#parent").append(reset);
$("#parent > div").on("click", function() {
var clicked = $(this);
var index = $("#parent > div").index(clicked);
$("#parent > div:gt(" + (index - 1) + ")").add(reset).animate({
top: "-=50"
}, 100, function() {
clicked.remove();
});
childCount -= 1;
});
});
#parent > div {
width: 100px;
height: 40px;
margin-bottom: 10px;
position: absolute;
text-align: center;
-webkit-transition: all .5s;
-moz-transition: all .5s;
-o-transition: all .5s;
transition: all .5s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="parent">
<!-- some data-bind attribute would be better than an id -->
</div>

Image Rotation with Fancybox

I'm creating an interface that allows users to rotate images 90 degrees counter clockwise. I rotate the image on the page using jquery and -webkit-transform, but I also want to update the preview of image in the Fancybox slideshow.
I tried rotating the image by doing the following:
$(".fancybox").fancybox({
afterShow: function(){
fancyboxRotation();
}
});
function fancyboxRotation(){
$('.fancybox-wrap').css('webkitTransform', rotate(-90deg));
$('.fancybox-wrap').css('mozTransform', rotate(-90deg));
}
But that ended up rotating the controls as well (and also placed the close button on the top left instead of the top right):
If I just apply the rotation to the image, the white border around it has the wrong orientation:
Anyone have experience applying transformations to a fancybox image?
For fancybox 3 here is what I came up with. It uses font awesome icons, you can replace with glyphicons or whatever else you choose.
//adding custom item to fancybox menu to rotate image
$(document).on('onInit.fb', function (e, instance) {
if ($('.fancybox-toolbar').find('#rotate_button').length === 0) {
$('.fancybox-toolbar').prepend('<button id="rotate_button" class="fancybox-button" title="Rotate Image"><i class="fa fa-repeat"></i></button>');
}
var click = 1;
$('.fancybox-toolbar').on('click', '#rotate_button', function () {
var n = 90 * ++click;
$('.fancybox-image-wrap img').css('webkitTransform', 'rotate(-' + n + 'deg)');
$('.fancybox-image-wrap img').css('mozTransform', 'rotate(-' + n + 'deg)');
});
});
You can rotate the outer most div in the fancy box content, In my case it's fancybox-skin(fancybox v2 )
afterShow: function(){
var click = 1;
$('.fancybox-wrap').append('<div id="rotate_button"></div>')
.on('click', '#rotate_button', function(){
var n = 90 * ++click;
$('.fancybox-skin').css('webkitTransform', 'rotate(-' + n + 'deg)');
$('.fancybox-skin').css('mozTransform', 'rotate(-' + n + 'deg)');
});
};
With help from #Ashik I finally got this working and did not have to give up showing the title since I instead rotate .fancybox-inner and overwrite some CSS so I can keep the white border. I also initialize the fancybox from the $(document).ready() function so I had to bind the button a little different.
Finally, this is kind of a long answer so let me know if I left something out since it is entirely possible! Also, we do not need to support IE (thank the lord), so it may or may not work correctly there.
I went ahead and removed the regular arrow and close buttons so they would stay put at the top. This requires that you add the fancy box button helper CSS and JS files:
<link href="/Content/css/jquery.fancybox.css" rel="stylesheet"/>
<link href="/Content/css/jquery.fancybox-buttons.css" rel="stylesheet"/>
<script src="/Content/Scripts/fancybox/jquery.fancybox.js"></script>
<script src="/Content/Scripts/fancybox/jquery.fancybox.pack.js"></script>
<script src="/Content/Scripts/fancybox/jquery.fancybox-buttons.js"></script>
Then initializing fancy box is being done from $(document).ready(), as I said, like below (notice I remove the arrows and close buttons and add them back in using the button helper's tpl property). In that tpl property I also create a custom rotation button with an onclick and a custom data-rotation property which will hold the current rotation:
$(document).ready(function() {
$(".fancybox").fancybox({
loop : true,
helpers: {
buttons: {
position: 'top',
tpl : '<div id="fancybox-buttons"><ul><li><a class="btnPrev" title="Previous" href="javascript:;"></a></li><li><a id="fancybox-rotate-button" title="Rotate" data-rotation="0" onclick="FancyBoxRotateButton()"></a></li><li><a class="btnNext" title="Next" href="javascript:;"></a></li><li><a class="btnClose" title="Close" href="javascript:jQuery.fancybox.close();"></a></li></ul></div>'
}
},
closeBtn: false, // you will use the tpl buttons now
arrows : false // you will use the tpl buttons now
});
Here is the custom rotation button's onclick function:
window.FancyBoxRotateButton = function() {
var fancyboxInner = $('.fancybox-inner');
var fancyBoxRotateButton = $('#fancybox-rotate-button');
var currentRotation = parseInt(fancyBoxRotateButton.data("rotation"));
var rotation = 'rotate(-' + (90 * ++currentRotation) + 'deg)';
fancyboxInner.css({
'-moz-transform' : rotation,
'-webkit-transform': rotation,
'-o-transform' : rotation,
'transform' : rotation
});
fancyBoxRotateButton.data("rotation", currentRotation.toString());
}
Last but not least we need to fix the white border and then I also change the size of the custom button ul and set my custom rotation button's picture. There is probably better ways to do this (if you know of one let me know!) but I simply removed .fancybox-skin's background and box shadow and added it to .fancybox-inner:
#fancybox-buttons ul{
width: 130px;
}
#fancybox-buttons #fancybox-rotate-button {
background-image: url('/Content/images/fancybox_rotate.png')
}
.fancybox-skin {
background: none !important;
}
.fancybox-opened .fancybox-skin {
-webkit-box-shadow: none !important;
-moz-box-shadow : none !important;
box-shadow : none !important;
}
.fancybox-inner {
border-radius : 4px;
border : 2px solid white;
padding : 10px;
background : white none repeat scroll 0 0;
-webkit-box-shadow: 0 10px 25px #000000;
-webkit-box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5);
-moz-box-shadow : 0 10px 25px #000000;
-moz-box-shadow : 0 10px 25px rgba(0, 0, 0, 0.5);
box-shadow : 0 10px 25px #000000;
box-shadow : 0 10px 25px rgba(0, 0, 0, 0.5);
}
Hope it helps someone!
You can rotate your image by applying the css style -webkit-transform: rotate(-90deg); only to the '.fancybox-inner' class element instead of the '.fancybox-wrap' so that it will rotate only the image and not the whole container that includes the controls and descriptions.
My solution was to remove the arrows and close button from the fancybox and fade in the fancybox slideshow after the rotation was applied to the entire fancybox-wrap. To do this, I set the display of the fancybox-wrap to none in the "beforeShow", and then on "AfterShow", I fade in the image. Here's my code:
$(".fancybox").fancybox({
helpers: {
overlay: {
locked: false
}
},
arrows: false,
closeBtn: false,
beforeShow: function(){
if($('.fancybox-image').length>0){
$('.fancybox-wrap').css('display', 'none');
var imageID = getFancyboxImageID();
var rotation = getFancyboxRotation(imageID);
if(rotation!=0){
fancyboxRotate(rotation);
}
}
},
afterShow: function(){
if($('.fancybox-image').length>0){
$('.fancybox-wrap').fadeIn();
}
}
});
I wanted to keep the close button and the caption so I did a little magic trick with CSS3 transform:
afterShow: function() {
var click = 0, deg;
$('.fancybox-inner')
.append('<img id="rotate_button" src="https://cdn0.iconfinder.com/data/icons/super-mono-sticker/icons/button-rotate-cw_sticker.png" title="Rotate 90° CW">')
.on('click', '#rotate_button', function() {
click = (++click % 4 === 0) ? 0 : click;
deg = 90 * click;
$('.fancybox-wrap').css('transform', 'rotate(' + deg + 'deg)');
$('#rotate_button').css('transform', 'rotate(-' + deg + 'deg)');
sessionStorage.setItem('prev_rotated_image', $('.fancybox-image').prop('src'));
sessionStorage.setItem($('.fancybox-image').prop('src'), deg);
// move the close button and rotate the label
switch (deg) {
case 90:
$('.fancybox-close').css('transform', 'translate(-' + $('.fancybox-wrap').width() + 'px, 0px)');
$('.fancybox-title').find('span.child').css('transform', 'translate(' + ($('.fancybox-wrap').width() / 2 + $('.fancybox-title').height() / 2 + 8) + 'px, -' + ($('.fancybox-wrap').height() / 2) + 'px) rotate(-' + deg + 'deg)');
break;
case 180:
$('.fancybox-close').css('transform', 'translate(-' + $('.fancybox-wrap').width() + 'px, ' + $('.fancybox-wrap').height() + 'px)');
$('.fancybox-title').find('span.child').css('transform', 'translate(0px, -'+ ($('.fancybox-wrap').height() + $('.fancybox-title').height() + 16) +'px) rotate(-' + deg + 'deg)');
break;
case 270:
$('.fancybox-close').css('transform', 'translate(0px, ' + $('.fancybox-wrap').height() + 'px)');
$('.fancybox-title').find('span.child').css('transform', 'translate(-' + ($('.fancybox-wrap').width() / 2 + $('.fancybox-title').height() / 2 + 8) + 'px, -' + ($('.fancybox-wrap').height() / 2) + 'px) rotate(-' + deg + 'deg)');
break;
case 0:
case 360:
default:
$('.fancybox-close').css('transform', 'translate(0px, 0px)');
$('.fancybox-title').find('span.child').css('transform', 'translate(0px, 0px) rotate(0deg)');
}
});
}
Thanks, #Paul for a great snippet, I have added some class changes (current slide) and CSS property that worked for my version of fancybox3. Might help someone.
Note: you can replace the "Rotate" text with an icon.
//adding custom item to fancybox menu to rotate image
$(document).on('onInit.fb', function (e, instance) {
if ($('.fancybox-toolbar').find('#rotate_button').length === 0) {
$('.fancybox-toolbar').prepend('<button id="rotate_button" class="fancybox-button" title="Rotate Image">Rotate</button>');
}
var click = 1;
$('.fancybox-toolbar').on('click', '#rotate_button', function () {
var n = 90 * ++click;
$('.fancybox-slide--current img').css('webkitTransform', 'rotate(-' + n + 'deg)');
$('.fancybox-slide--current img').css('mozTransform', 'rotate(-' + n + 'deg)');
$('.fancybox-slide--current img').css('transform', 'rotate(-' + n + 'deg)');
});
});
See this issue on Github: https://github.com/fancyapps/fancybox/issues/1100
Code of user seltix5 is working in fancybox v3. I tested it myself.
You just need to append his/her code to your fancybox.js file. It simply extends fancybox object with rotate functionality after event "onInit.fb". It also adds rotate buttons to top menu and smooth rotate animation.

changing script to jquery combining another function

I have a script that I put together, which a button is clicked it rotates 45 degrees, I also would like it to toggle a paragraph open and closed. I don't have access to the CSS because the content management system interwoven wont' let me have accerss, so this is why it's all done with the javascript and it has to stay that way. The script is:
var img = document.images[0];
effects_of_yoga_info.style.setProperty("-webkit-transition", "-webkit-transform 0.3s ease-in-out");
var deg = 0;
effects_of_yoga_info.addEventListener('click', function() {
deg += 45;
effects_of_yoga_info.style.setProperty('-webkit-transform', 'rotateZ('+deg+'deg)');
and the part I'd like to incorporate into it so that they happen at the same time is:
$("#effects_of_yoga_info").click(function () {
$("p#effects_of_yoga_text").slideToggle("fast");
});
I'm sure it's very simple but I've been having a hard time with it, thanks in advance.
You mean something like this:
$(img).click(function () {
deg += 45;
$(this).css('-webkit-transform', 'rotateZ(' + deg + 'deg)');
$('#KittenText').slideToggle("fast");
});​
got it working:
var img = document.images[0];
effects_of_yoga_info.style.setProperty("-webkit-transition", "-webkit-transform 0.3s ease-in-out");
var deg = 0;
effects_of_yoga_info.addEventListener('click', function() {
$("p#effects_of_yoga_text").slideToggle("fast");
deg += 45;
effects_of_yoga_info.style.setProperty('-webkit-transform', 'rotateZ('+deg+'deg)');
});

Expanding compressed div

http://jsfiddle.net/Y8MUF/
It can expand the div when i click on it. How do i make it look nicer by adding a "See More" link then hide it when the div exapands and adjust the row height relative to the See More link?
$(document).ready(function(){
var rowsshown = 2;
var rowheight = 1.2; // line height in 'em'
var ht = (rowsshown * rowheight) - .5; // subtracting the .5 prevents the top of the next line from showing
$('.info')
.css({'overflow':'hidden','line-height' : rowheight + 'em','height': ht + 'em' })
.click(function(){
if ( $(this).css('height') == 'auto') {
$(this).css('height', ht + 'em');
} else {
$(this).css('height','auto');
}
});
})
try :
http://jsfiddle.net/Y8MUF/11/
You could look at the jquery slideup and slidedown
http://api.jquery.com/slideUp/
For a better effect

Categories