Image swap when hovering - javascript

I've created a snippet to swap images between no underscore and '_1' in the source path when hovering and leaving the .hover()
Sometimes I see an issue whereby the next image I hover over get's the 'styled' image from the previous image i hovered over (this is inconsistent!) with '_1'?
I think it has to do with the speed at which you hover over the images.
I'm using $(this) to refer to the div the user is currently hovering over and maybe it's inconsistently storing the src for the img and referencing it too soon?
Please see below a video demonstrating my issue:
http://screencast.com/t/lJEDb5lyTXj5
PS: I don't have access to the source code - I am injecting this code onto the site, (So i can't manipulate the divs/images without JS)
<head>
<style>
.js div.result.product {
display: none;
}
</style>
<script>
$('html').addClass('js');
</script>
<script>
$( document ).ready(function() {
$('div.result.product').show();
});
</script>
</head>
<script>
console.log($('div.result-image').length);
// Function to set all images with _1 to no "_1".
$( "div.result-image > a > img" ).each(function() {
console.log('one image');
var styled = "_1";
var revertStyledOriginal = $(this).attr('src');
var preset = "?hei=245&qlt=85,1&wid=245&fmt=jpeg&resMode=bicub&op_sharpen=1";
// if the img is silo
var s = revertStyledOriginal;
// Only takes everything up until the "_"
unstyle = s.substring(0, s.indexOf('_'));
// add the preset back onto the src to make the img crisp
var unstyled = unstyle + preset;
// sets this instance of the image in the each loop to the "new link" with removed "_1"
$(this).attr('src', unstyled);
});
// Hover Function
$('div.result.product').hover(function myfunc() {
//Store 'this' as a reference to the current product image to be referred to when switching images
var selection = $(this);
$link = selection.find('img').attr('src');
$parsed = $link;
var styled = "_1";
var revertStyledOriginal = selection.find('img').attr('src');
var preset = "?hei=245&qlt=85,1&wid=245&fmt=jpeg&resMode=bicub&op_sharpen=1";
//if the img is silo
if(revertStyledOriginal.indexOf(styled) === -1 && ($link !== "http://www.kirklands.com/assets/HTML/MVS/AB_tests/NextPageButton/Next_Page_Buttons_Page_2.jpg"))
{
$preset = "?hei=245&qlt=85,1&wid=245&fmt=jpeg&resMode=bicub&op_sharpen=1";
//Need to remove preset to add _1 (then readd preset).
$removedPreset = $parsed.substring(0, $parsed.indexOf('?'));
var Unstyled = $removedPreset + $preset;
var Styled = $removedPreset + "_1" + $preset;
function checkImage(src) {
var img = new Image();
img.onload = function() {
// code to set the src on success
selection.find('img').attr('src', Styled)
//console.log('exists');
//console.log(revertStyledOriginal);
};
img.onerror = function() {
selection.find('img').attr('src', Unstyled)
console.log('doesnt exist');
//console.log();
};
img.src = src; // fires off loading of image
}
checkImage(Styled);
}
//if the img is styled
else {}
//$( this ).attr("src",);
},
//Function to reset the image on when you exit hover of img
function() {
$original = $(this).find('img').attr('src')
$removedPreset = $parsed.substring(0, $parsed.indexOf('?'));
$link = $removedPreset + $preset;
if ($original !== "http://www.kirklands.com/assets/HTML/MVS/AB_tests/NextPageButton/Next_Page_Buttons_Page_2.jpg") {
// set on hover image src to silo
$(this).find('img').attr('src', $link)
}
});
</script>

Related

Removing current image before loading a new one JavaScript

I load an image from URL by using document.createElement('img'). And a button triggers it. But, every time I click the button, it creates another img element instead of removing the current one. Can you help me to remove the current image so that there is always maximum one image displayed. Here is the code:
<script>
function() {
var imageUrl = document.getElementById('image-url').value;
var loadedImage = document.createElement('img');
loadedImage.src = imageUrl;
loadedImage.className = 'container';
document.getElementById('imagePlace').appendChild(loadedImage);
}
</script>
Every time you call appendChild method, you add a node to your document, so some changes to your code are required - you should check if the image node is already present and either create a new img element or replace the src attribute of the existing one.
<script>
function() {
// Get a new image url
var imageUrl = document.getElementById('image-url').value;
// Get a parent element
var parent = document.getElementById('imagePlace');
// Try to get an 'img' element that is inside '#imagePlace' node.
var currentImage = parent.querySelector('img');
// Check if there already is an image in the document.
if (currentImage) {
// If there is, replace its 'src' attribute with the new url.
currentImage.src = imageUrl;
}
else {
// If there is no image in the parent, create and add new image node.
var loadedImage = document.createElement('img');
loadedImage.src = imageUrl;
loadedImage.className = 'container';
parent.appendChild(loadedImage);
}
}
</script>
In other approach you may start with removing the img node if it's present in the #imagePlace container, however changing the src attribute is "cheaper" to perform.
<script>
function() {
// Get a new image url
var imageUrl = document.getElementById('image-url').value;
// Get a parent element
var parent = document.getElementById('imagePlace');
// Try to get an 'img' element that is inside '#imagePlace' node.
var currentImage = parent.querySelector('img');
// Check if there already is an image in the document.
if (currentImage) {
// If it's there, remove it.
currentImage.remove();
}
// Create and add new image node.
var loadedImage = document.createElement('img');
loadedImage.src = imageUrl;
loadedImage.className = 'container';
parent.appendChild(loadedImage);
}
</script>

How to display paragraphs and images from div in order?

I am building a small web-tool where editors can write content by using buttons to add paragraphs and images. I store the elements with an id ((number of element) starting at 0 and incremented for every new element) and load with a button in order to a div "preview" where the content is supposed to be displayed as in the web page later on.
My issue is that, for a reason I don't understand, the image is always displayed below all the paragraphs instead of being in order. Presumably there is an easy fix, but I am very new to HTML, CSS and JS and couldn't find the solution online.
Sorry if this is a stupid mistake or the solution was already posted somewhere.
Javascript handling the preview rendering:
// Preview current document status
document.getElementById("previewButton").addEventListener("click", function() {
// Clear
document.getElementById("preview").innerHTML = "";
// Add all elements properly
var section = document.getElementById("preview");
var id = "preview";
for (var counter = 0; counter < element_counter; counter++) {
var type = document.getElementById(counter).nodeName;
// If text element
if (type === "TEXTAREA") {
var paragraph = document.createElement("p");
var text = document.getElementById(counter).value;
paragraph.setAttribute("id", id + counter);
paragraph.setAttribute("class", "flow-text");
paragraph.append(text);
section.appendChild(paragraph);
}
// If image element
if (type === "INPUT") {
var file = document.getElementById(counter).files[0];
var reader = new FileReader();
reader.onload = function(e) {
var image = document.createElement("img");
image.setAttribute("id", id + counter);
image.setAttribute("src", e.target.result);
image.setAttribute("class", "materialboxed responsive-img");
section.appendChild(image);
}
reader.readAsDataURL(file);
}
}
});
This might work. I can't test though without your code. However basically the principle at work is to isolate some of the vars so they represent distinct instantiations. And then immediately add the image element to the DOM. The reader.onload is expected to run asynchronously still.
enter code here if (type === "INPUT") {
(function() {
var file = document.getElementById(counter).files[0];
var reader = new FileReader();
var image = document.createElement("img");
image.setAttribute("id", id + counter);
image.setAttribute("class", "materialboxed responsive-img");
section.appendChild(image);
reader.onload = function(e) {
image.setAttribute("src", e.target.result);
}
reader.readAsDataURL(file);
}());
}

Image Swap on MouseOut (JavaScript, not JQ)

I am trying to create functions to mouseover and mouseout of images. The tricky part is this function needs to work for any image, and I cannot use direct image names. I have to therefore use variables.
The HTML code is as follows for the images:
The HTML for the images is like this, and there are 3 images:
<img src="images/h1.jpg" alt="" id="images/h4.jpg" onmouseover="swapToNewImage(this)" onmouseout="swapImageBack(this)">
I'm expecting that you have to reference the id for the new image, and then the src attribute for the previous image to revert when you mouseout.
The problem is that, if I reference the id attribute, the image no longer has information on the src attribute so I cannot call it to revert back.
Here is the JavaScript I have thus far. It works to swap the image to a new one, but not to swap it back :(
//FUNCTION
var $ = function (id) {
return document.getElementById(id);
}
//ONLOAD EVENT HANDLER
window.onload = function () {
//GET ALL IMG TAGS
var ulTree = $("image_rollovers");
var imgElements = ulTree.getElementsByTagName("img");
//PROCESS EACH IMAGE
//1. GET IMG TAG
for (var i = 0; i < imgElements.length; i++) {
console.log (imgElements[i]);
console.log (imgElements[i].getAttribute("src"));
//2. PRELOAD IMAGE FROM IMG TAG
var image = new Image();
image.setAttribute("src", imgElements[i].getAttribute("src"));
//3. Mouseover and Mouseout Functions Called
image.addEventListener("mouseover", swapToNewImage);
image.addEventListener("mouseout", swapImageBack);
}
}
//MOUSE EVENT FUNCTIONS
var swapToNewImage = function(img) {
var secondImage = img.getAttribute("id", "src");
img.src = secondImage;
}
var swapImageBack = function(img) {
var previousImage = img.getAttribute("src");
img.src = previousImage;
}
Let me know if you can help me figure out how to call the image's src attribute so it can be reverted back. Again, I cannot reference specific image names, because that would be a lot easier (: Thank you!
Well, You can use a data attribute to store your src, and a data attribute to store the image you want to swap when mouseover.
Please try the following example.
var swapToNewImage = function(img) {
var secondImage = img.dataset.swapSrc
img.src = secondImage;
}
var swapImageBack = function(img) {
var previousImage = img.dataset.src
img.src = previousImage;
}
<img src="https://images.pexels.com/photos/259803/pexels-photo-259803.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500" alt="" data-src="https://images.pexels.com/photos/259803/pexels-photo-259803.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500" data-swap-src="https://images.pexels.com/photos/416160/pexels-photo-416160.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500" onmouseover="swapToNewImage(this)" onmouseout="swapImageBack(this)">
I also notice that the image tag is generated by code, in order to set the dataset values, we can do this:
var image = new Image();
image.scr = [src]
image.dataset.src = [src]
image.dataset.swapSrc = [swap src]

How to get ALT from IMG tag in JavaScript

I am using THIS script to display my galleries in lightbox. I was using some plugins but all of them does not display the alt=""(alt added in media in wordpress).
How can I modify the code from the link below to display the alt attributes ?
I found something in the code, but I dont know how to put the dynamic alt there(commented by uppercase text in the code). Dynamic I mean that as user will add the img in wordpress dashboard, he will put the alt then.
{
key: '_preloadImage',
value: function _preloadImage(src, $containerForImage) {
var _this4 = this;
$containerForImage = $containerForImage || false;
var img = new Image();
if ($containerForImage) {
(function () {
// if loading takes > 200ms show a loader
var loadingTimeout = setTimeout(function () {
$containerForImage.append(_this4._config.loadingMessage);
}, 200);
img.onload = function () {
if (loadingTimeout) clearTimeout(loadingTimeout);
loadingTimeout = null;
var image = $('<img />');
image.attr('src', img.src);
image.addClass('img-fluid');
image.attr('alt',"Temp TEXT"); // HERE I WOULD LIKE TO DISPLAY THE ALT AUTOMATICALLY - NOT STATIC AS IT IS NOW
// backward compatibility for bootstrap v3
image.css('width', '100%');
$containerForImage.html(image);
if (_this4._$modalArrows) _this4._$modalArrows.css('display', ''); // remove display to default to css property
_this4._resize(img.width, img.height);
_this4._toggleLoading(false);
return _this4._config.onContentLoaded.call(_this4);
};
img.onerror = function () {
_this4._toggleLoading(false);
return _this4._error(_this4._config.strings.fail + (' ' + src));
};
})();
}
img.src = src;
return img;
}
},
I am using wordpress on my page and my skills in JS are rather poor, so I am asking you :).
We don't really know what is the type of your img variable. If you want to set the alt tag of image to the one of img, simply do:
image.attr('alt', img.attr('alt'));
…if it's a jQuery object. Otherwise, if img is pure JavaScript, you can do:
image.attr('alt', img.alt);
if the img object holds the existing alt and image is the new jQuery object, then set it with jQuery
image.attr('alt', img.getAttribute('alt'))

Attempting to change an image onclick via PHP/Javascript/HTML

I've looked at numerous other answers regarding this but haven't found a solution that has worked. I'm using a PHP page that contains some HTML code, with Javascript working some functions. Ideally I would select an image on the page, the image will become colored green as it is selected. I would then like to deselect the image and have it return to the original state. I can only get half-way there however. What am I missing? Is it something with post back?
Here's some code examples:
The HTML:<div onclick="changeImage(1)" id="toolDiv1"><img id="imgCh1" src="/images/Tooling/1.png"></div>
The Javascript function:
function changeImage(var i){
var img = document.getElementById("imgCh" + i + ".png");
if (img.src === "images/Tooling/" + i + ".png"){
img.src = "images/Tooling/" + i + "c.png";
}
else
{
img.src = "images/Tooling/" + i + ".png";
}
}`
The "1c.png" image is the one that is selected and should replace "1.png". There are multiple divs on this page that hold multiple images, which are named 2/2c, 3/3c, which is why the var i is included. Any insight? Thanks in advance.
You could do it something like this, it would also allow for different file names.
<img class="selectable" src="/images/Tooling/1.png"
data-original-source="/images/Tooling/1.png"
data-selected-source="/images/Tooling/1c.png">
<img class="selectable" src="/images/Tooling/2.png"
data-original-source="/images/Tooling/2.png"
data-selected-source="/images/Tooling/2c.png">
 
var images = document.getElementsByClassName('selectable');
for (var image of images) {
image.addEventListener('click', selectElementHandler);
}
function selectElementHandler(event) {
var image = event.target,
currentSrc = image.getAttribute('src'),
originalSrc = image.getAttribute('data-original-source'),
selectedSrc = image.getAttribute('data-selected-source'),
newSrc = currentSrc === originalSrc ? selectedSrc : originalSrc;
image.setAttribute('src', newSrc);
}
 
With comments:
// find all images with class "selectable"
var images = document.getElementsByClassName('selectable');
// add an event listener to each image that on click runs the "selectElementHandler" function
for (var image of images) {
image.addEventListener('click', selectElementHandler);
}
// the handler receives the event from the listener
function selectElementHandler(event) {
// the event contains lots of data, but we're only interested in which element was clicked (event.target)
var image = event.target,
currentSrc = image.getAttribute('src'),
originalSrc = image.getAttribute('data-original-source'),
selectedSrc = image.getAttribute('data-selected-source'),
// if the current src is the original one, set to selected
// if not we assume the current src is the selected one
// and we reset it to the original src
newSrc = currentSrc === originalSrc ? selectedSrc : originalSrc;
// actually set the new src for the image
image.setAttribute('src', newSrc);
}
Your problem is that javascript is returning the full path of the src (you can try alert(img.src); to verify this).
You could look up how to parse a file path to get the file name in javascript, if you want the most robust solution.
However, if you're sure that all your images will end in 'c.png', you could check for those last 5 characters, using a substring of the last 5 characters:
function changeImage(var i){
var img = document.getElementById("imgCh" + i);
if (img.src.substring(img.src.length - 5) === "c.png"){
img.src = "images/Tooling/" + i + ".png";
}
else
{
img.src = "images/Tooling/" + i + "c.png";
}
}

Categories

Resources