How to make image change on a hover - javascript

I've been trying to think of ways to do this but I haven't figured one out yet, so I thought I'd ask here!
So for example I have this:
<img src="arrow.png"/>Index
I want that on hovering Index, the image should change to arrow_hover.png, using CSS.

Use the pseudo class :hover
First, give the image a class so that it doesn't target every img. Say, hover-image
Then...
.hover-image:hover {
background: url('arrow_hover.png');
}
HOWEVER! THIS WILL NOT WORK! Using only CSS, you cannot change an images attribute src. You will need to use javascript.
You can change this to a div instead of an img tag, and this code will work. But not with your current markup.
To do this in javascript, give the element an id to make things easier. In this case.. derp.
You would do:
var x = document.getElementById("derp");
x.mouseenter = function() {
this.src = "arrow_hover.png";
}
x.mouseout = function() {
this.src = "arrow.png";
}

You could do this with CSS only. Try this CSS:
#theImage {
height:250px; //Or whatever size it needs to be
width:320px; //Or, again, whatever it needs to be
background-image:url(stuff.jpg);
}
#theImage:hover {
background-image:url(otherstuff.jpg);
}
#theImage would be a div.

Related

setting HTML button image with JavaScript

I'm working on my first website and I want to create an HTML button and put an image on it.
But the image has the wrong size and I am looking for a way to scale the image before putting it on the button. That's how I tried it:
function setImg(){
var img = new Image(200,200);
img.src = "imgs/youtubeImg.png";
img.style.width = 100;
img.style.height = 100;
document.getElementById("youtubeButton").style.backgroundImage = img;
}
I don't know why it isn't working. I don't know if that is important, but this function is called after the button was created.
Hope you can help me, Thanks.
EDIT:
Method: appendChild:
Thats how it looks like with that function
But I want to let the img fit in this button:
But that only works if the image is the background image of the button.
Please try this instead,
Using appendChild() to add a image.
function setImg(e){
e.classList.add("active")
var img = new Image(200,200);
img.src = "https://images.unsplash.com/photo-1530103043960-ef38714abb15?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=60";
img.style.width = "180px";
img.style.height = "70px";
document.getElementById("youtubeButton").textContent= "";
document.getElementById("youtubeButton").appendChild(img);
}
button{
padding:20px 30px;
}
button.active{
padding:0;
margin:0;
}
<button id="youtubeButton" onclick="setImg(this)">Youtube Button</button>
OP's solution moved from question to an answer:
I found the solution. You can just set the background size, so it scales the image automatically.
If you're setting the background image via css (as opposed to just appending it to the button which iou can also do) then you need to set the background-size attribute, look it up for details

Scalable background images that change on click

I have a question that's somewhat of an extension of this thread.
I have my background images working; however, instead of having them tile automatically, I would like to link them to scale to the browser. I know how to create a scalable background image using CSS, but I don't know how to link said CSS to the backImage variable in the script (available below, or after the jump from the previous thread) so that it applies to all of the various images.
<script type="text/javascript">
var backImage = [
"images/street.png",
"images/market.jpg",
"images/building.jpg",
"images/skyscraper.jpg",
"images/gasstation.jpg",
"images/trees.jpg"
];
function changeBGImage(whichImage) {
if (document.body){
document.body.style.backgroundImage = 'url('+backImage[whichImage]+')';
}
};
</script>
The tricky part is I can't apply the class to the HTML because I'm already applying this...
Change
...to an existing div in the HTML with multiple other classes; hence I need to add the class to backImage or the specific pngs and jpgs in the javascript.
Thanks in advance!
A friend helped me solve my problem. Here goes:
<script type="text/javascript">
var backImage = [
"images/vintagemap.png",
"images/earbuds.jpg",
"images/flames.jpg",
"images/grass.jpg",
"images/library.jpg",
"images/shapes.jpg"
];
function changeBGImage(whichImage) {
if (document.body){
document.body.style.backgroundImage = 'url('+backImage[whichImage]+')';
document.body.className = 'bgchange';
}
};
</script>
I added the line "document.body.className = 'bgchange';" below my original JS, then wrote the following CSS class:
.bgchange {
background-repeat:no-repeat;
background-size:cover;
}
It will now resize any photo to a scalable, full-screen background image.
Hopefully someone else finds this helpful!
as part of your changeBGImage() function, you could make additional .style. changes to document.body to do whatever you like to each background image as it changes.
EDIT:
Essentially, take this:
function changeBGImage(whichImage) {
if (document.body){
document.body.style.backgroundImage = 'url('+backImage[whichImage]+')';
}
};
And turn it into this:
function changeBGImage(whichImage) {
if (document.body){
document.body.style.backgroundImage = 'url('+backImage[whichImage]+')';
document.body.style.backgroundSize = '###px';
}
};
Or, if you want to set some CSS other than background-size on the body element, you would do that after the .style. parameter instead. Just remember, when translating CSS to JS, hyphens are removed and the next letter is capitalized (just like background-image in CSS becomes backgroundImage in JS)

Insert a logo next to any DOM element

I'm developing a Firefox extension which amends the contents of a loaded webpage. First I select all the elements of which the "src" or "href" attributes match my regex (this part of the code works).
Then, I would like to place a little image at the top right corner of the found element's parent using the following code:
/* create and add attributes to image */
var img = window.content.document.createElement("img");
var b = window.content.document.createAttribute("src");
b.nodeValue = "chrome://plugin/content/agent.png";
img.setAttributeNode(b);
img.addEventListener("click", function(){ alert("ds"); });
img.style.display = "block";
img.style.border = "3px solid red";
img.style.position = "relative";
img.style.top = "-10px";
img.style.right = "-10px";
img.style.left = "20px";
// ... the code to return the element...
//now insert the image
$jq(img).appendTo(element.parentNode);
The current result is that either the image is shown just at the bottom of the element's parent or not shown at all.
If you look at this: http://jsfiddle.net/yzwh5/64/ - I would like my button to work in a similar manner to that red cross.
You must "play" with the element's CSS positioning, in fact it doesn't matter where do you insert the images, but where you do position them.
Maybe you would like to take a look at "next-to", a jQuery plugin that automates the calculations to position an element next to another element
For example:
<script type="text/javascript">
$('.PlaceThisDiv').nextTo($('.ThisOtherDiv'), {position:'right', shareBorder:'top'});
</script>
As you can see in this Fiddle i have prepared (contains the plugin itself)
http://jsfiddle.net/PvcNr/
you will get you something like this:
More info: https://code.google.com/p/next-to/
Hope it helps
Try CSS code like this:
.my-ext-overlay:after {
content:url(smiley.gif);
position: absolute;
margin-left: -16px; margin-top: -16px;
}
and then adding the ".my-ext-overlay" class name to each element you find.
See example
Firstly, CSS floats are called cssFloat (or htmlFloat in some browsers) because float is a reserved word. Second, there is no such float value as block.
Third, you missed an x in -10px for the right property.
Fourth, setting both relative left and right positions can lead to unexpected behaviour.
Fifth, you shouldn't use createAttribute, since attribute nodes aren't reliable in all browsers. Instead, use setAttribute on the element.
Sixth, if this did work it would mess up page layout around the element you're searching for, so you would be better off with position: absolute so it doesn't affect the flow. If you do this, however, you should use margin-left instead of left (same for other directions), to shift the element around.
I think that should at least get the thing close to working...

Change a div background with jQuery

I need to change my background div with some other images.
I want that first, myDiv load the first background image on css style, and then within 2/3 seconds of delay add a fade effect change the background image.
If it's possible, I need to do this with jQuery.
You cannot do fade or any other transitions directly on the background image. You can however add another div with second image as its background and fadeOut() the original one.
Does this do what you you want?
http://jqueryfordesigners.com/image-loading/
EDIT: A bit more Googling - this sounds like what you are trying to do...
http://www.magneticwebworks.com/jquery-rotating-page-background/
Edit: another go - THis? http://css-tricks.com/forums/discussion/9621/solved-is-it-possible-to-add-jquery-cycle-to-background-imagess/p1
this is not fade effect but you can delay and change background image like this.
function changebackground(){
$('#divID').css("background-image", "url(/myimage.jpg)");
}
setTimeout(function() { changebackground();}, 3000);
this might be good workaround
http://jquery.malsup.com/cycle/
after you position on top divs with cycle it can be your background - cycle.js give's you lot of options.
if you want only rotate image's in bacground you must first preload that image and second you must put it in other div so that both divs can animate.
There is no support for this, even if you add all the functionality of jQuery UI.
You could append a temporary image, absolutely positioned inside the div for which u want to change background. Let the image fade in, and once it's fully opaque, swap background image for the div. This will be problematic if you have a repeated background, however.
var im1 = 'picture1.png';
var im2 = 'picture2.png';
$('#divID').css({'background-image': 'url("'+im1+'")', 'position': 'relative'});
$('#divID').on('click', function() {
var img = $('<img />', {
src: im2,
}).css({
position: 'absolute',
top: 0,
left: 0
}).hide();
$(this).append(img);
img.fadeIn('slow', function() {
$(this).parent().css('background-image', 'url("'+im2+'")');
$(this).remove();
});
});
Of course, you should move the CSS I included in my script to a .css file, and use a class instead, for more readable code.

Find the "potential" width of a hidden element

I'm currently extending the lavalamp plugin to work on dropdown menus but I've encountered a small problem. I need to know the offsetWidth of an element that is hidden. Now clearly this question makes no sense, rather what I'm looking for is the offsetWidth of the element were it not hidden.
Is the solution to show it, grab the width, then hide again? There must be a better way...
The width of an element that has CSS visibility: hidden is measurable. It's only when it's display: none that it's not rendered at all. So if it's certain the elements are going to be absolutely-positioned (so they don't cause a layout change when displayed), simply use css('visibility', 'hidden') to hide your element instead of hide() and you should be OK measuring the width.
Otherwise, yes, show-measure-hide does work.
The only thing I can think of is to show it (or a clone of it) to allow retrieval of the offsetWidth.
For this measurement step, just make its position absolute and its x or y value a big negative, so it will render but not be visible to the user.
You can use the following function to get the outer width of an element that is inside a hidden container.
$.fn.getHiddenOffsetWidth = function () {
// save a reference to a cloned element that can be measured
var $hiddenElement = $(this).clone().appendTo('body');
// calculate the width of the clone
var width = $hiddenElement.outerWidth();
// remove the clone from the DOM
$hiddenElement.remove();
return width;
};
You can change .outerWidth() to .offsetWidth() for your situation.
The function first clones the element, copying it to a place where it will be visible. It then retrieves the offset width and finally removes the clone. The following snippet illustrates a situation where this function would be perfect:
<style>
.container-inner {
display: none;
}
.measure-me {
width: 120px;
}
</style>
<div class="container-outer">
<div class="container-inner">
<div class="measure-me"></div>
</div>
</div>
Please be aware that if there is CSS applied to the element that changes the width of the element that won't be applied if it's a direct descendant of body, then this method won't work. So something like this will mean that the function doesn't work:
.container-outer .measure-me {
width: 100px;
}
You'll either need to:
change the specificity of the CSS selector ie. .measure-me { width: 100px; }
change the appendTo() to add the clone to a place where your CSS will also be applied to the clone. Ensure that where ever you do put it, that the element will be visible: .appendTo('.container-outer')
Again, this function assumes that the element is only hidden because it's inside a hidden container. If the element itself is display:none, you can simply add some code to make the clone visible before you retrieve it's offset width. Something like this:
$.fn.getHiddenOffsetWidth = function () {
var hiddenElement $(this)
width = 0;
// make the element measurable
hiddenElement.show();
// calculate the width of the element
width = hiddenElement.outerWidth();
// hide the element again
hiddenElement.hide();
return width;
}
This would work in a situation like this:
<style>
.measure-me {
display: none;
width: 120px;
}
</style>
<div class="container">
<div class="measure-me"></div>
</div>
Two options:
position the element outside the viewport (ex: left:-10000px)
use visibility: hidden or opacity: 0 instead of hide().
Either way will work as hiding the element but still being able to get the computed width. Be careful with Safari on thi, it's awfully fast and sometimes too fast...
Actual jQuery plugin!
Usage:
console.log('width without actual: ' + $('#hidden').width());
console.log('width with actual: ' + $('#hidden').actual('width'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.actual/1.0.19/jquery.actual.min.js"></script>
<div style="width: 100px; display: none;">
<div id="hidden"></div>
</div>
If you know the element to be the full width of a parent element another approach is to create a recursive method:
es5:
var getWidth;
getWidth = function($el){
return $el.offsetWidth || getWidth($el.parentElement);
}
var width = getWidth(document.getElementById('the-element'));
es6:
let getWidth
getWidth = ($el) => $el.offsetWidth || getWidth($el.parentElement)
const width = getWidth(document.getElementById('the-element'))
What I did was ;
by the time hiding that element, stored its width in its dataset.
It only will work for you if you can hide programmatically.
ie.
When Hiding ;
var elem = $("selectorOfElement");
elem.dataset.orgWidth = elem.clientWidth;
Later when getting ;
var elem = $("selectorOfElement");
var originalWidthWas = elem.dataset.orgWidth;
thats because its hidden via display: none; What ive done in the past is to make a "reciever" div which i use absolute positioning on to get it off the page. Then i load the new element into that, grab the dimensions and then remove it when im done - then remove the reciever when im done.
Another thing you can do is to not use hide(); but to instead set visibility: hidden; display: ; However this means the blank area will be rendered wherever the node is attached.
var $hiddenElement = $('#id_of_your_item').clone().css({ left: -10000, top: -10000, position: 'absolute', display: 'inline', visibility: 'visible' }).appendTo('body');
var width = parseInt($hiddenElement.outerWidth());
$hiddenElement.remove();
I try to find working function for hidden element but I realize that CSS is much complex than everyone think. There are a lot of new layout techniques in CSS3 that might not work for all previous answers like flexible box, grid, column or even element inside complex parent element.
flexibox example
I think the only sustainable & simple solution is real-time rendering. At that time, browser should give you that correct element size.
Sadly, JavaScript does not provide any direct event to notify when element is showed or hidden. However, I create some function based on DOM Attribute Modified API that will execute callback function when visibility of element is changed.
$('[selector]').onVisibleChanged(function(e, isVisible)
{
var realWidth = $('[selector]').width();
var realHeight = $('[selector]').height();
// render or adjust something
});
For more information, Please visit at my project GitHub.
https://github.com/Soul-Master/visible.event.js
demo: http://jsbin.com/ETiGIre/7
Sorry I am late to this conversation. I am surprised no one has mentioned getComputedStyle. (Note this only works if the CSS sets a width value)
Grab the element:
let yourEle = document.getElementById('this-ele-id');
and use the function:
getComputedStyle(yourEle).width
This returns a string so you will have to remove the numbers from the string.
This works even when the element's display style is set to none.
Other articles to read about this includes here at zellwk.com

Categories

Resources