I'm trying to change the background image of a button when the mouse is hovered.
with the statement
function testIn ()
{
elem.style.backgroundImage = 'url("image_name_in.png")';
}
function testOut ()
{
elem.style.backgroundImage = 'url("image_name_out.png")';
}
i'm doing this with onMouseOver=testIn() and onMouseOut=testOut().
Here the problem is that, when i hover the mouse. I'm seeing the progress bar (bottom right side) is shown in firefox as if some page is getting loaded
Use :hover pseudo-class and CSS Sprites instead.
You need a few changes in order to pass your object reference:
onMouseOver="testIn(this)"
function testIn (elem)
{
elem.style.backgroundImage = 'url("image_name_in.png")';
}
BTW - convention now uses "onmouseover" (no caps)
You're getting activity in the progress bar because your onmouseover image does NOT load until you call the function.
You could use a sprite combined with :hover CSS for the effect - like #Tomasz mentions.
If you don't want to combine your default and hover image states into a sprite, you may try adding an additional container for the hover image (setting it's default CSS to display:none;) then use JS, or jQuery to swap the display states of the default and hover images on mouseover or hover.
$('myDefaultImage').hover(function() {
$(this).hide();
$('myHoverImage').show();
}, function () {
...the inverse, etc.
});
This will eliminate the progress bar issue because all of your images will be loaded together.
At the same time, this is going to bloat your page size unnecessarily.
I'd really try to go with the :hover CSS and sprite, or reevaluate the importance of what you're trying to accomplish with the image swap (is it really the best solution for your overall project?).
Related
When you scroll on a page, the page shows an element, I want to be able to specify this element and
do code with it using JS, is this possible? I tried something but it had another problem..
What I tried was,
let section = document.getElementById('out');
window.onscroll = function() {
if (window.scrollY >= 678) {
document.getElementById('out').style.color = "red";
} else {
document.getElementById('out').style.color = "black"
}
}
I didn't use animate here, I just made sure it works, and it did, well almost, because if you zoom in/out it ruins it, I think that's because I got the 678 by going to the button and printing scrollY manually, is there anyway to make that automatic, so it works on any element I need?
I searched a lot and can't seem to find what I need, the solutions need jQuery, I need a solution only with html, css, and javascript.
In the future the solution will be css scroll timelines, but as that feature is at the time of writing experimental and is not supported by major browsers you can use intersection observers.
Quoted from MDN:
The Intersection Observer API lets code register a callback function that is executed whenever an element they wish to monitor enters or exits another element (or the viewport), or when the amount by which the two intersect changes by a requested amount.
To animate a component when it is in or out of view, you can give animated elements a .hidden class in your html markup and create an intersection observer which appends the .shown class to .hidden elements when they are in view.
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => entry.target.classList.toggle(“shown”, entry.isIntersecting))
})
const hiddenElements = document.querySelectorAll(“.hidden”)
hiddenElements.forEach((el) => observer.observe(el))
Then you can just apply transitions under a <selector>.shown css rule.
I have created a sliding image gallery and when the button is pushed it slides the picture across and updates the image attribute for the relevant sections.
However this works perfectly like 50% of the time. The other times there is a second glitch and the images then go in place as expected.
I have attached the javascript methods for the animate method and the array change method. I have looked elsewhere and cannot see anyone else with a similar issue or where I am going wrong, especially when it doesn't happen often.
imageGallery.leftSelect.onclick = function () {
window.setTimeout(imageGallery.rightClick, 250);
imageGallery.animateImages('.image1', '.imageRight');
imageGallery.animateImages('.imageRight', '.imageNoneRight');
imageGallery.animateImages('.imageLeft', '.image1');
imageGallery.animateImages('.imageNoneLeft', '.imageLeft');
};
animateImages: function (classFrom, classTo) {
var classMoving = $(classFrom);
var classGoingTo = $(classTo);
classMoving.animate({
top: classGoingTo.css('top'),
left: classGoingTo.css('left'),
width: classGoingTo.css('width'),
opacity: classGoingTo.css('opacity'),
}, 258, function () {
console.log('Animated');
classMoving.css({"width":'', "opacity":'', "top":'', "left":'', });
});
},
rightClick: function () {
imageGallery.imagesDisplay.push(imageGallery.imagesDisplay.shift());
imageGallery.imageNoneLeft.setAttribute('src', imageGallery.imagesDisplay[2]);
imageGallery.imageLeft.setAttribute('src', imageGallery.imagesDisplay[1]);
imageGallery.imageMain.setAttribute('src', imageGallery.imagesDisplay[0]);
imageGallery.imageRight.setAttribute('src', imageGallery.imagesDisplay[10]);
imageGallery.imageNoneRight.setAttribute('src', imageGallery.imagesDisplay[9]);
},
Can someone assist, I really need this to work?
If there is anything not clear or you need more code let me know.
Thanks,
First things first, the culprit was the setAttribute of all images i.e. whatever you were doing inside the rightClick and leftClick functions were the reasons why you were seeing a glitch. Changing src of an img tag produces the glitch.
But then we cannot simply remove it because your approach relies heavily on this swapping of images.
I had to breakdown and really understand your approach first. The way it worked was that you would animate, for example, image1 (the centered one) to move to the position of imageLeft upon click on the rightCarousel button. On that same click, you had a setTimeout of almost the duration of the animation to call rightClick function. This rightClick function then swaps the images so that image1 can always remain at the center and only images can come and go after animation. This was the problem.
What I had to change was that all image tags i.e. imageNoneLeft, imageLeft, image1, imageRight & imageNoneRight would change each others classes such that their position remains changed after animations.
Also, I had to add another animateImages line inside your leftSelect and rightSelect callbacks to animate the furthest images i.e. imageNoneLeft & imageNoneRight to animate to each other's positions with respect to the click of the buttons.
Take a look at this jsFiddle. It will help you understand a lot better. And let me know if you have any questions.
JavaScript:
var imageGallery={
prefix:'https://dl.dropboxusercontent.com/u/45891870/Experiments/StackOverflow/1.5/',
imagesDisplay:['JS.jpg','PIXI.jpg','GSAP.jpg','JS.jpg','PIXI.jpg','GSAP.jpg','JS.jpg','PIXI.jpg','GSAP.jpg','JS.jpg','PIXI.jpg'],
rightSelect:document.querySelector('.rightCarousel'),
leftSelect:document.querySelector('.leftCarousel'),
imageMain:document.querySelector('.image1'),
imageLeft:document.querySelector('.imageLeft'),
imageRight:document.querySelector('.imageRight'),
imageNoneLeft:document.querySelector('.imageNoneLeft'),
imageNoneRight:document.querySelector('.imageNoneRight'),
init:function(){
imageGallery.imagesDisplay.push(imageGallery.imagesDisplay.shift());
imageGallery.imageNoneLeft.setAttribute('src',imageGallery.prefix+imageGallery.imagesDisplay[2]);
imageGallery.imageLeft.setAttribute('src',imageGallery.prefix+imageGallery.imagesDisplay[1]);
imageGallery.imageMain.setAttribute('src',imageGallery.prefix+imageGallery.imagesDisplay[0]);
imageGallery.imageRight.setAttribute('src',imageGallery.prefix+imageGallery.imagesDisplay[10]);
imageGallery.imageNoneRight.setAttribute('src',imageGallery.prefix+imageGallery.imagesDisplay[9]);
},
animateImages:function(classFrom,classTo){
var classMoving=$(classFrom);
var classGoingTo=$(classTo);
classMoving.animate({
top:classGoingTo.css('top'),
left:classGoingTo.css('left'),
width:classGoingTo.css('width'),
opacity:classGoingTo.css('opacity')
},258,function(){
$(this).removeClass(classFrom.substr(1));
$(this).addClass(classTo.substr(1));
$(this).removeAttr('style');
});
}
};
imageGallery.init();
imageGallery.leftSelect.onclick=function(){
imageGallery.animateImages('.imageNoneRight','.imageNoneLeft');
imageGallery.animateImages('.imageRight','.imageNoneRight');
imageGallery.animateImages('.image1','.imageRight');
imageGallery.animateImages('.imageLeft','.image1');
imageGallery.animateImages('.imageNoneLeft','.imageLeft');
};
imageGallery.rightSelect.onclick=function(){
imageGallery.animateImages('.imageNoneLeft','.imageNoneRight');
imageGallery.animateImages('.imageLeft','.imageNoneLeft');
imageGallery.animateImages('.image1','.imageLeft');
imageGallery.animateImages('.imageRight','.image1');
imageGallery.animateImages('.imageNoneRight','.imageRight');
};
I've thrown together a cool little script that will make my search box appear using jQuery UI. However, there are links above the search box that must move up at the same speed as well. For this, the margin-top must be adjusted, but by toggling the margin-top, it seems it is disappearing.
Does anyone know how I can toggle the margin-top without making the links disappear AND keep the speed as close as possible to the other one?
$(document).ready(function() {
$('.pwcustomsearch').hide();
$("#pwcustomsearchlink").click(function () {
var effect = 'slide';
var options = { direction: 'down' };
var duration = 400;
$('.pwcustomsearch').toggle(effect, options, duration);
$('.social-media').toggle({"marginTop": "15px"});
})
});
Here is a fiddle:
http://jsfiddle.net/hcmLw/1030/
.toggle() is adding display:none as an inline style to your element, therefore it disappears.
Use .animate() instead to change the top margin.
See my updated fiddle here: http://jsfiddle.net/hcmLw/1032/
EDIT: Updated the fiddle again to make the toggling work properly.
I am using a giant sprite for an element that changes different states at hover. I was wondering if there was a way to have the hover state image fade in? You can view my code live - here
Here's my code for the hover state for each span
$(".hf-1").hover(
function () {
$(this).css("background-position","0 -121px");
$(".hf-2").css("background-position","0 -242px");
$(".hf-3").css("background-position","0 -363px");
$(".hf-4").css("background-position","0 -484px");
},
function () {}
);
I am using Jquery to do the background image hover instead of basic css cause i have multiple hovers that need to be reset.
Thanks for any help.
Use something like this:
$(this).animate({"background-position": "0 -121px"}, "slow");
Rinse and repeat for the other three.
You would need to double-stack the backgrounds and fade from to the other. Won't be able to fade within the same container.
Or you can just use jquery's native fadeIn API.
$(this).click(function () {
$("this").fadeIn("slow");
});
I'm trying to figure out what the best way would be to set up a website interface that has a large centre 'tile' (basically a div with rounded corners, a variable background image, and text on it) that acts as the hub of the interface, around which I have smaller tiles which are clickable as link, e.g. one tile will lead to a photo gallery etc... However I need these smaller tiles to be moveable i.e. I would like them to visibly whisk away off the screen (in a specific direction) before the next set of tiles enters the screen.
(Ideally they would be the same set of tiles, they would simply go off screen to 'change' as it were and come back as the new set of tiles - An ideal example would be of clicking on the photo gallery tile, all the main tiles whisk away off screen, to be replaced by more tiles representing individual photos in the gallery)
I have no issues with the CSS of round corners and positioning my tiles etc... but I'm currently trying to get the tiles to actually move using the code referenced here: Alter CSS class attributes with javascript?
I can't get it to work. I've set up one of my test tiles to make just one change to the width of another test tile using the above-referenced code when it detects a mouseover event on the div, but it appears not to work.
Here's my code, if you can spot any errors, but primarily I'd also like to hear if you have any better suggestions of reaching the design state I'm looking for:
var style;
function changeFoo() {
if(typeof style == 'undefined') {
var append = true;
style = document.createElement('style');
}
else {
while (style.hasChildNodes()) {
style.removeChild(style.firstChild);
}
}
var head = document.getElementsByTagName('head')[0];
var rules = document.createTextNode(
'.tiletest2 { border:4px solid #999; background-color:#999; width: 50px; border-radius:32px; }'
);
style.type = 'text/css';
if(style.styleSheet) {
style.styleSheet.cssText = rules.nodeValue;
} else {
style.appendChild(rules);
}
if(append === true) head.appendChild(style);
}
The onmouseover event looks like this:
<div class="tiletest1" onmouseover="changeFoo()">
<br/><br/>
SAMPLE left
<br/><br/>
Try using a JavaScript library like http://jquery.com/. You can also get plugins like http://jqueryui.com/ for the kinds of effects you're describing.
I agree with TimS to go with jquery, specifically you will want to use the .animate()function.
This will make it much easier on yourself since you can easily control the speed and time the animation plays and you may be able to easily remove div(s) with the .hide() function, which gives you many options of what kind of animation you could use to close it.