Jquery chaining with css method is ignored - javascript

I was playing with jquery and i came to a problem.
i want to animate a box when its container is hovered such that each time the container is hovered , box (initial state 1) should be reset to a position (say state 2) then animate to desired position (say state 3).
HTML
<div id="box-container">
<div id="box"></div>
</div>
CSS
#box-container {
padding : 10px;
border : 1px solid #f00;
}
#box {
display: inline-block;
background : #fff;
padding:50px;
border: 1px solid #ddd;
transform : translateX(150px);
}
JS
$("#box-container").hover(function(){
console.log("hover in");
$("#box").css({
transform : 'translateX(0px)',
transition : 'initial'
}).css({
transform:'translateX(100px)',
transition : 'transform 0.5s linear'
});
},function(){
console.log("hover out");
});
but this method is not working. box is going from state 1 -> state 3 directly and get stucked. i found that css() can't be queued as animate() in jquery
working model 1 => JSfiddle
so i tried to break the chain and tried to add some delay by doing this
$("#box").css({
transform : 'translateX(0px)',
transition : 'initial'
});
setTimeout(function(){console.log("delay")}, 1000);
var x = 4;
console.log("delay");
$("#box").css({
transform:'translateX(100px)',
transition : 'transform 0.5s linear'
});
but this dosn't work , so i tried delay() which works fine for first time. but on second time box got stucked on left
working model 2 => JSfiddle
at last i tried to log the css value of (transform , padding , transition etc) of box after first change (state 2)
console.log($("#box").css('transform'));
and somehow it is working as i wanted it to work
working model 3 => JSfiddle correct
So i want to know why reading css value gives the desired output
what is the good way to achieve this output state 1 (hover)-> state 2 -> state 3 (hover)-> state 2 -> state 3
all links are working fine as checked on chrome (latest version).

Unless you're just married to using transform properties, you could just use jQuery animation to move your elements.
Modified CSS:
#box-container {
padding : 10px;
border : 1px solid #f00;
position: relative;
}
#box {
display: inline-block;
background : #fff;
padding:50px;
border: 1px solid #ddd;
position: relative;
left: 150px;
}
Modified JavaScript
$("#box-container").on('mouseover',function(){
$('#box').animate({
left: "0"
}, 10, function(){
}).animate({
left: "100"
}, 300, function(){
});
}).on('mouseout',function(){
$('#box').animate({
left: "150"
}, 0, function(){
});
});

Related

CSS opacity transition switch to zero immediately

I cannot figure out why a composite transition (opacity and height) on the same element does not follow the expected duration. However, this issue happens only the very first time is run, then begins to work perfectly.
UPDATE:
I found a slimmer way to demonstrate the problem.
By click the "start" button, the box at the right turns immediately transparent, and does not fade slowly as the left one.
$("button").on("click", function() {
doNative();
doJQuery();
});
function doNative() {
const elem = document.getElementById("bn");
elem.style.opacity = 0;
elem.style.height = 0;
elem.style.transitionDuration = "2s";
elem.style.transitionProperty = "opacity, height";
}
function doJQuery() {
const elem = $("#bj");
elem.css({
opacity: 0,
height: 0,
"transition-duration": "2s",
"transition-property": "opacity, height",
});
}
.block {
width: 200px;
font-size: 24px;
font-family: Tahoma;
display: inline-block;
margin: 10px;
border: 1px solid gray;
}
.initial {
opacity: 1;
height: 200px;
}
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<div>
<button>start</button>
</div>
<div>
<div class="block">
<div id="bn" class="initial">This box is collapsed using the native transition API</div>
</div>
<div class="block">
<div id="bj" class="initial">This box is collapsed using the jQuery transition API</div>
</div>
</div>
LEGACY CONTENT (no relevant anymore):
Here is just a snippet to depict the context:
items.css({
opacity: 0,
height: 0,
"transition-duration": transitionDuration + "ms",
"transition-property": "opacity, height"
});
To better clarify the actual and the expected behavior, have a look at this pen: https://codepen.io/highfield/pen/dKLKKo
Once run, by pressing the "hide" button, the "Items" block disappears immediately, but the expected behavior is to fade along a certain interval.
After this initial weird phase, the "show" and "hide" functions behave perfectly as expected.
I also noticed that by removing the "height" from the "transition-property" CSS field, the opacity will fade correctly.
How to patch this problem?
The transition properties must be set on the target element before performing any transitions. To make that initial animation work too, you should set a basic transition definition to the #s1 element in CSS.
Finally, I've found where the problem is.
It seems that the order of the fields matters, but I don't understand why the native version works fine, even in a random order. By changing the jQuery version as follows, the transitions behave correctly:
function doJQuery() {
const elem = $("#bj");
elem.css({
"transition-duration": "2s",
"transition-property": "opacity, height",
opacity: 0,
height: 0,
});
}

Vertical line before hover CSS

I'm trying to show an image when a path on the site is hovered.
The hover part works well. However, when I "mouseout" the path, the image is removed but a red vertical line is always there.
This is my css :
.imgElu {
height: 23%;
width: auto;
position: absolute;
bottom: 33.1%;
left: 36.7%;
border-radius: 50%;
border: 3px solid #ac2c2d;
}
When not hovered :
When hovered :
I tried to use DOM to set display : "none" when the event "mouseout" is triggered. But the line is always briefly displayed before showing what you can see in the second photo.
Any help is appreciated.
UPDATE : I understood why I got this red line briefly when hovering a path : it's because the image is an url and is loading. And until it's not load, the css is "bordering" nothing. Now I'm searching to show nothing until it's not loaded, how can I do that ?
UPDATE 2 : this is my js code :
siege[0].addEventListener("mouseover", function() { //when mouseover
var actualImg = siege.Vignette; //gets the url Image
document.getElementById("photoElu").src = siege.Vignette; //puts the url on the img div
if (eluPresent == false) {
$('<p class="tooltip"></p>').text("Siège non occupé").appendTo('body').fadeIn('slow');
} else { //If there is something to show :
$('<p class="tooltip"></p>').text("Siège n°"+siege.Seat+" "+siege.Name).appendTo('body').fadeIn('slow');
document.getElementById('photoElu').style.border = "3px solid #ac2c2d"; //sets the css to the img div
}
siege.animate(hoverStyle, animationSpeed);
}, true);
siege[0].addEventListener("mouseout", function() { //when mouseout
$('.tooltip').remove();
document.getElementById("photoElu").src = ""; //remove the url
siege.animate(style, animationSpeed);
document.getElementById('photoElu').style.border = "0px solid #ac2c2d"; //sets the css to remove the border
}, true);
It's a border which is 3px in width that is being displayed, give your image style of box-shadow as an alternative to this problem.
Initially hide the content.
.imgElu {
height: 23%;
width: auto;
position: absolute;
bottom: 33.1%;
left: 36.7%;
border-radius: 50%;
border: none;
display: none;
}
You need to set border property when the div is hovered.
.imgElu:hover {
border: 3px solid #ac2c2d;
display: /*your display setting*/
}
Use
border: 0px solid #3c2c2d;
In your normal state, and
border: 3px solid #3c2c2d;
in your hover state.
If you are adding hover style using jquery, use jquery .css() method.
Hope this help

Contenteditable height transition: animate after adding (shift+enter) and removing a line of text

It works so far on using the contenteditable attribute on the <div> tag with the autogrow feature of a textbox. Also the height transition of it. It all works good, except for one thing, deleting characters, to be specific, a line, will not animate its height, unlike adding new lines. I have still a little knowledge on CSS.
.autogrow {
border: 1px solid rgb( 0, 0, 0 );
padding: 10px;
}
#keyframes line_insert {
from {
height: 0px;
}
to {
height: 20px;
}
}
.autogrow[contenteditable] > div {
animation-duration: 250ms;
animation-name: line_insert;
}
.autogrow[contenteditable] {
overflow: hidden;
line-height: 20px;
}
<div class="autogrow" contenteditable="true"></div>
When I press Shift + Enter, it doesn't animate either, it does well though while pressing Enter. Just the removing of lines and the Shift + Enter key combination while entering a new line is the problem.
How to make it work? Can it be done using pure CSS? Or adding a javascript function for it?
To avoid these issues, I personally use a solution not based on pure CSS animations / transitions which I found always have problems. For example, in your CSS implementation, there is a bounce back effect if using the Enter too fast (you can slow the animation down to see it better).
Moreover, new lines handling is different between browsers, some will add <div><br></div>, some versions of IE add only <br>, etc.
I've never been able to fix all these problems or found an implementation fixing all of these so I decided to not modify at all the behavior of the contenteditable, let the browser do is magic which works and instead, react to what's happening.
We don't even have to worry about keys events like Shift + Enter or events like deletion, etc., all of these are natively handled by the navigator.
I choose instead to use 2 elements: one for the actual contenteditable and one for the styling of my contenteditable which will be the one having height animations / transitions based on the actual height of the contenteditable.
To do that, I'm monitoring every events that can change the height of a contenteditable and if the height of my styling element is not the same, I'm animating the styling element.
var kAnimationSpeed = 125;
var kPadding = 10;
$('div[contenteditable]').on('blur keyup paste input', function() {
var styleElement = $(this).prev();
var editorHeight = $(this).height();
var styleElementHeight = styleElement.height();
if (editorHeight !== styleElementHeight - kPadding * 2) {
styleElement.stop().animate({ height: editorHeight + kPadding * 2 }, kAnimationSpeed);
}
});
.autogrowWrapper {
position: relative;
}
.autogrow {
border: 1px solid rgb(0, 0, 0);
height: 40px; /* line-height + 2 * padding */
}
div[contenteditable] {
outline: none;
line-height : 20px;
position: absolute;
top: 10px; /* padding */
left: 10px; /* padding */
right: 10px; /* padding */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="autogrowWrapper">
<div class="autogrow"></div>
<div contenteditable="true"></div>
</div>
It's kinda hacky, but it works.
First, modify your CSS
.autogrow {
border: 1px solid rgb( 0, 0, 0 );
padding: 10px;
}
#keyframes line_insert {
from {
height: 0px;
}
to {
height: 20px;
}
}
.autogrow[contenteditable] > div {
animation-duration: 250ms;
animation-name: line_insert;
}
.autogrow[contenteditable] {
overflow: hidden;
line-height: 20px;
}
Then add this jQuery that detects Shift + Enter events and appends a div whenever they occur
$(".autogrow").keydown(function(e){
if (e.keyCode == 13 && e.shiftKey || e.keyCode == 13)
{
$(this).animate({height: $(this).height()+20},200);
$(this).append('<div><br></div>');
}
});
And that should work.
Check fiddle https://jsfiddle.net/wx38rz5L/582/

jQuery (fully) expand and (partially) collapse div on mouse hover

I'm trying to implement rating functionality on my website.
I have the following HTML:
<div class="rating-container">
<div class="stars">
</div>
</div>
The stars div gets populated with 10 fa fa-star font-awesome star icons during runtime via jQuery
My CSS looks like this:
div.rating-container div.stars {
display: block;
}
div.rating-container div.stars i {
font-size: 20px;
color: white;
cursor: pointer;
margin-right: 3px;
padding: 3px;
}
..And the final result looks like this:
What I want to do now is to only show 1 star instead of 10 when the page initially loads. Hovering over the 1 star should expand the stars div so that all 10 stars show and the user can rate - once the mouse leaves the stars div, it goes back to only showing one star. I'm trying to achieve this using jQuery's $(this).animate({ width: someWidthHere }); on the $(".stars").hover()function but I can't seem to get it right.
Any help/pointers would be greatly appreciated.
Thanks in advance!
Update: per request, here is the (silly) test code I've tried:
$(function () {
$(".stars").hover(
function () {
$(this).animate({ width: '100%' });
},
function () {
$(this).animate({ width: '10%' });
}
);
});
Which gives me this on hover:
Hopefully I understand your question correctly. You can get trigger an event for on and off like this:
$( ".stars" ).hover(
function() {
$( ".stars" ).animate({ width: "100px" },1000);
}, function() {
$( ".stars" ).animate({ width: "20px" },1000);
}
);
Just an FYI, I think it might be better to just use css transitions and just use the .toggleClass() to expand and contract the div. It works better with some mobile browsers that have less processing power but either way works.
This is how you would do that with css:
.stars {
width:20px;
-webkit-transition: width 1s; /* For Safari 3.1 to 6.0 */
transition: width 1s;
}
.stars:hover{
width:100px;
}

Animate background position different behaviours

I'm not that good with jQuery animations, but i'm trying to animate an background image when mouse enters on its element. The animation is simple, mouse enters, the image moves a little to the left. Mouse leaves, image returns to its position.
I could have that working on Chrome, but with a different behaviour in IE. FF doesn't event move anything. My is the following:
$(".arrow").on("mouseenter", function()
{
$(this).stop(true).animate({ "background-position-x": "75%" });
}).on("mouseleave", function()
{
$(this).stop(true).animate({ "background-position-x": "50%" });
});
Where .arrow is a div with these properties:
.arrow {
width: 50px;
padding: 10px 0;
background: url(http://upload.wikimedia.org/wikipedia/commons/4/45/Right-facing-Arrow-icon.jpg) no-repeat center;
background-size: 16px
}
And here is a demo.
What is most strange for me is the case of IE. It seems that the animation start always from left to right, not middle right. It occours when mouses leaves too. Any ideas ?
Because Firefox doesn't support backgroundPositionX, but it does support background position
Try this code in firefox and InternetExplorer:
$(".arrow").on("mouseenter", function()
{
$(this).stop(true).animate({ "background-position": "75%" });
}).on("mouseleave", function()
{
$(this).stop(true).animate({ "background-position": "50%" });
});
More Info: backgroundPositionX not working on Firefox
Here is Updated Demo working well with FF and IE
I know Manwal has solved it , but it can also be done very easily in CSS3 like so:
.arrow {
float:left;
width: 50px;
padding: 10px 0;
background: url(http://upload.wikimedia.org/wikipedia/commons/4/45/Right-facing-Arrow-icon.jpg) no-repeat center;
background-size: 16px;
transition: all 2s ease-in-out;
}
.arrow:hover {
transform :translateX(50px);
}
where translate 50px will be the value you wish to move it along the X axis

Categories