Vertical line before hover CSS - javascript

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

Related

Jquery chaining with css method is ignored

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(){
});
});

Onmouseover/out deactivate and reactivate in jQuery

I have a search function that does 3 things:
1) first, when a user hover over the icon, it should change the icon, and the color of border around it as well:
HTML:
<div class="searchbox">
<img id="search" src="Icons/magnifier2.png"
onmouseover="this.src='Icons/magnifier.png'"
onmouseout="this.src='Icons/magnifier2.png'"/>
</div>
CSS:
.searchbox #search {
display: inline;
border: 2px solid #c8c8c8;
position: relative;
height: 20px;
width: 20px;
float: right;
padding: 4px;
border-radius: 5px;
transition: all 500ms;
}
.searchbox #search:hover {
display: inline;
border: 2px solid #808080;
position: relative;
float: right;
padding: 4px;
border-radius: 5px;
transition: all 500ms;
}
So far so good. In this bit, im unsure why the image isnt applied any transition at all when hovered... Is there a way in which you can change color on a single .png icon, instead of juggling between two .pngs?
2) The user is supposed to click on this icon, whereafter it expands with a new icon and a changed border width (padding-left: 130px;). Here goes the following jQuery code:
$(function () {
var search = $("#search");
search.click(function () {
search.attr("src", "Icons/magnifier.png").css({
"border": "2px",
"border-style": "solid",
"border-color": "#808080",
"padding-left": "130px",
"transition": "all 500ms" });
});
});
3) When the user clicks on the HTML body, the border should slide back to normal position and apply the original CSS:
$('html').click(function (e) {
if (e.target.id != 'search') {
$("#search").attr("src", "Icons/magnifier2.png");
$("#search").removeAttr('style');;
}
});
My issue is, the HTML onmouseover/out shown in the top of my post, is still active when the function is fired upon clicking the icon.(if i place my mouse inside and outside the expanded border, it still changes the icon.)
My idea of an easy fix:
It would be a lot easier if the :hover parameter in the CSS could change both the color of the .png and the border, however i've been searching alot for this specific solution, and it doesnt seem to be available!
The second solution would be to add some kind of code in the jQuery, search.click(function() that deactivates the onmouseover/out and reactivates it in the 2'nd .click(function().
I hope im clear enough with my question.
How do i overcome this onmouseover/out issue?
I've added a jsfiddle just for you to see my example:
https://jsfiddle.net/bfytnbs3/
It would be a lot easier if the :hover parameter in the CSS could
change both the color of the .png and the border, however i've been
searching alot for this specific solution, and it doesnt seem to be
available!
You can accomplish that using a CSS sprite. More reading is here: http://www.w3schools.com/css/css_image_sprites.asp
Basically, you'd have one magnifier.png image that would have both states for the icon. Then you'd use some CSS to switch between them.
.searchbox {
background: url('magnifier.png') 0px 0px;
}
.searchbox:hover {
background: url('magnifier.png') 0px -25px;
}
In this example, you'd have a sprite image that was 25px by 50px, with each state of the image being 25px by 25px.
Hope that helps!
Edit to add: Here is a JS Fiddle Example so you can see how it works:
https://jsfiddle.net/s51zjre4/1/

How to position two elements centered on top of each other?

The problem:
I have a form with a button underneath it to submit (post) from data with jQuery ajax(). I want for the button to be replaced with a spinner (animated png) for the duration of server ajax call. But such a trivial task is impossible in css to do right.
What i have tried:
I have placed button and image inside a bootstrap row. Ox ajax call I have set button display to none and img display to block. But because this two are not of the same size makes the whole page flicker, breaks the positioning of other elements and so on.
Another idea was to try to place both elements on top of each other with absolute positioning. But, stupid as css is I cannot center it on the middle of the row.
Is there a way to position both elements on top of each other so I can control their visibility?
Please bear in mind that I cannot used absolute position in pixel, because this is a web page and I do not not how wide the browser will be, image can change in the future, text in the button can change in the future, all this things affect absolute size.
If there is another solution to my problem which would prevent the page from jumping up and down it would also be great.
EDIT
Link to one of fiddle experiments:
https://jsfiddle.net/ofb2qdt8/
.button {
position: relative;
margin: auto;
height: 50px;
width: 30px;
background: blue;
z-index: 1;
display: block;
}
.spinner {
position: relative;
margin: auto;
height: 30px;
width: 50px;
background:red;
z-index: 2;
}
This renders second element underneath on screen. Not on different z layer.
Experiment 2:
https://jsfiddle.net/ofb2qdt8/
.button {
position: absolute;
margin: auto;
height: 50px;
width: 30px;
background: blue;
z-index: 1;
display: block;
}
.spinner {
position: absolute;
margin: auto;
height: 30px;
width: 50px;
background:red;
z-index: 2;
}
This does not center both elements, and they are pushed to the top of the containing div. The element with less height should be centered.
Check this working demo: https://jsfiddle.net/ofb2qdt8/3/
Add in a few lines of jquery and update your css.
Position your loading div according to button div's position, width, height using jquery.
*Click the button to see loading div, and try to play the margin of the button to any pixel.
###JQUERY
$(document).ready(function () {
$('.c2').each(function () {
$(this).css({
'width': $(this).siblings('.c1').outerWidth(),
'height': $(this).siblings('.c1').outerHeight(),
'top': $(this).siblings('.c1').offset().top,
'left': $(this).siblings('.c1').offset().left
});
});
$('.c2').on('click', function () {
$(this).hide(0);
});
});
###CSS
.c1 {
margin: 100px auto;
width: 100px;
text-align: center;
padding: 5px 10px;
background: blue;
z-index: 1;
}
.c2 {
position: fixed;
text-align: center;
background: red;
z-index: 2;
cursor: pointer;
}
Rough, ready and untested:
HTML
<div>
<input type='submit' />
<img src="spinneyIMage.gif" />
</div>
CSS
div{ text-align: center; }
div img{ display: none; }
jQuery
$('submit').click(function(e){
e.preventDefault();
$(this).hide().next().show();
});
After the Ajax call completes reverse the above jQuery.
As I haven't been able to find a working solution I have reverted to my first idea which I discarded at first. Albeit with a little twist.
HTML
<div class="row>
<div id="container-button" class="col-xs-12>
<button id="button" onclick="button_OnClick(e)">submit form via ajax</button>
<img src="img/spinner.png" sytle="display: none" />
</div>
</div>
JS
function btnContact_OnClick() {
// show the soinner and hide the button
showSpinner();
$.ajax(
{
type: 'POST',
url: "someurl.com/target",
data: $("#form").serialize(),
dataType: "json",
complete: function() { hideSpinner();},
success: onAjaxSuccess,
error : onAjaxError
});
}
function hideSpinner() {
$("#spinner").hide();
$("#button").show();
// make container height non-fixed and content adjustable again
$("#container-button").height('auto');
}
function showSpinner() {
// THis is the trick !!!
// Make the container fixed height as it was before displaying spinner, so it does not change with content (spinner is not the same height as button
$("#container-button").height($("#container-button").height());
$("#button").hide();
$("#spinner").show();
}
This is not the perfect solution but the best I could make.
Drawbacks:
it is not clean, you have to use javasript to fix what is css layout
problem
it still causes a little flicker
the height of container while displaying spinner is dependant on button, this may cause clipping if spinner is too big

Multiple line jquery tooltip

How to make custom jquery tooltip appear as multiple line that adjusts to fixed width? So it not go in one long line (if 'title' attribute is very long). Because Now if I write long 'title' attribute, tooltip is displayed on one long line and it does not matter what width is set to tooltip element.
My code to get better understanding of what I'm asking:
http://jsfiddle.net/8XttH/
jquery code:
$(document).ready(function() {
$("body").append("<div class='tip'></div>");
$("p[title]").each(function() {
$(this).hover(function(e) {
$().mousemove(function(e) {
var tipY = e.pageY + 16;
var tipX = e.pageX + 16;
$(".tip").css({'top': tipY, 'left': tipX});
});
$(".tip")
.html($(this).attr('title'))
.stop(true,true)
.fadeIn("fast");
$(this).removeAttr('title');
}, function() {
$(".tip")
.stop(true,true)
.fadeOut("fast");
$(this).attr('title', $(".tip").html());
});
});
});
Set a max-width on the tool tip box?
max-width: 100px;
Also set the height to auto so it increases as needed
height: auto;
The text will then wrap to the next line.
See this fiddle
Use this css
div.tip{
position: absolute;
top: 100px;
left: 100px;
width:100px;
border: 2px solid #FF0000;
background-color: #FF9999;
display: none;
padding: 3px;
}
Fiddle: http://jsfiddle.net/8XttH/2/

How do I make my "alert bar" push down everything of my website?

I wrote an alert bar like this:
alertmsg{
font-family:Arial,Helvetica,sans-serif;
font-size:135%;
font-weight:bold;
overflow: hidden;
width: 100%;
text-align: center;
position: fixed;
top: 0px;
left: 0px;
background-color: #fff;
height: 56px;
color: #000;
font: 20px/40px arial, sans-serif;
display:none;
padding-top:12px;
-webkit-box-shadow: 3px 3px 5px #888;
-moz-box-shadow: 3px 3px 5px #888;
box-shadow: 3px 3px 5px #888;
}
function alertbar(m, timeout){
if(!timeout){
var timeout = 3000;
}
var $alertdiv = $('<div id = "alertmsg"/>');
$alertdiv.text(m);
$alertdiv.bind('click', function() {
$(this).slideUp(200);
});
$(document.body).append($alertdiv);
$("#alertmsg").slideDown("slow");
setTimeout(function() { $alertdiv.slideUp(200) }, timeout);
return false
}
Pretty simple. I call alertbar("Go go go!"); to have this alert drop down.
However, it covers the body's page. I want it to sort of "push down" on the entire page (all the elements)....sort of like StackOverflow does it I guess.
I think it's the position: fixed that is your problem. This will place your element relative to the window and take it out of the normal flow.
Use position:static (or relative) and make sure the alertmsg element is at the top of the markup.
There's a couple things you must do:
Change the position CSS attribute of the "alert bar" to not be fixed and just be normal (remove that property).
Change your JavaScript to prepend the alertdiv, rather than append it. This will make it the first thing in the body.
$('body').prepend($alertdiv);
Slide your $alertdiv down normally.
Now something that you didn't take into account in your code is what happens when you run alertbar more than once. You'll append more than one to the body. If this is a concern, try doing something like this:
var exists = $('#alertmsg').length > 0;
var $alertdiv = exists ? $('#alertmsg') : $('<div id="alertmsg" />');
Now only prepend to the body if it doesn't exist already.
if (!exists)
$('body').prepend($alertdiv);
If you want to keep the position: fixed then just expand the body's top padding to the size of the alertbox.
$("#alertmsg").slideDown("slow", function() {
var paddingTopStr = "+" + $(this).outerHeight().toString() + "px";
$('body').css({ paddingTop: paddingTopStr });
});
You will also have to return the padding after:
setTimeout(function() {
var paddingTopStr = "-" + $(this).outerHeight().toString() + "px";
$('body').css({ paddingTop: paddingTopStr });
$alertdiv.slideUp(200) }, timeout);
}
Same for the click event.
You could wrap the rest of your content (to be pushed down) in a separate div and then insert your alert bar before it

Categories