Reputation: 8412
I am pretty new to the Javascript world. I have three pictures:
1. mango.jpg
2. apple.jpg
3. pineapple.jpg.
What I am trying to do is whenever I click on an image in my browser it gets blurred..I have 3 additional blurred pictures named:
1.apple_blur.jpg
2.mango_blur.jpg
3.pineapple_blur.png
this is my code below ( I am trying to do this the shortest way)
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title> I'm alive! </title>
<script>
window.onload = pageLoadedHandler;
function pageLoadedHandler() {
blur_images=[{id_pic:["apple","apple_blur.jpg"]},{id_pic:["mango","mango_blur.jpg"]}, {id_pic:["pineapple","pineapple_blur.png"]}];
for(i=0;i<=blur_images.length;++i) {
blur_image=blur_images[i];
window[blur_image.id_pic[0]]=document.getElementById(blur_image.id_pic[0]);
window[blur_image.id_pic[0]].onclick=blur_func;
}
function blur_func() {
for(i=0;i<=blur_images.length;++i) {
blur_image=blur_images[i];
window[blur_image.id_pic[0]]=document.getElementById(blur_image.id_pic[0]);
window[blur_image.id_pic[0]].src=blur_image.id_pic[1];
}
}
}
</script>
</head>
<body>
<img src="apple.jpg" id="apple"></img>
<img src="mango.jpg" id="mango"></img>
<img src="pineapple.png" id="pineapple"></img>
</body>
</html>
When I clicked on an image in my browser, all of the images get blurred instead of that particular image (this is because whenever I click on any image, the handler "blur_func" iterates and replace ALL images with their blurred version images.
How can I rewrite the code to tell the blur_func
handler to replace the apple image ONLY with the blurred apple image?.
Upvotes: 0
Views: 56
Reputation: 3697
I think you never saw the "this" pointer? What about this example?
<html lang="en">
<head>
<meta charset="utf-8">
<title> I'm alive! </title>
<script>
window.onload = function() {
var images = document.getElementsByClassName("fruit");
for(var i = 0 ; i < images.length ; i++) {
images[i].onclick = function() {
this.src = this.getAttribute("data-blur");
}
}
}
</script>
</head>
<body>
<img class="fruit" src="apple.jpg" data-blur="blur_apple.jpg"></img>
<img class="fruit" src="mango.jpg" data-blur="blur_mango.jpg"></img>
<img class="fruit" src="pineapple.png" data-blur="blur_pineapple.jpg"></img>
</body>
</html>
Upvotes: 0
Reputation: 253308
Given that you have a predictable file-name, apple.jpg
and apple_blur.jpg
, I'd suggest that you take advantage of the addEventListener()
method, which allows you to pass the node that received the event, and simply change it's src
property:
function toggleBlur () {
// caching the node, and its src property
// to avoid repeated look-ups:
var image = this,
source = image.src;
// if the string of the src property _does not_ contain '_blur'
// indexOf() will return -1
if (source.indexOf('_blur') === -1) {
// replacing the file-type '.jpg' with
// the supplied '_blur.jpg':
image.src = source.replace('.jpg', '_blur.jpg');
}
else {
// replacing '_blur.jpg' with '.jpg':
image.src = source.replace('_blur.jpg', '.jpg');
}
}
// retrieving all <img> elements from the document:
var images = document.getElementsByTagName('img');
// iterating over those <img> element nodes with a for loop:
for (var i = 0, len = images.length; i < len; i++) {
// binding the toggleBlur function as an event-listener
// for the 'click' event:
images[i].addEventListener('click', toggleBlur);
}
To make it a little shorter, you could use the following which does exactly the same:
function toggleBlur () {
// caching the node, and its src property
// to avoid repeated look-ups:
var image = this,
source = image.src;
// using a conditional operator, known as a 'ternary,' to
// perform an assessment (as above); if the assessment is
// true or truthy we perform the action betwee the '?' and
// ':' characters, otherwise false or falsey we perform
// the code following the ':' character. Once either action
// is completed the result is passed as the new value of
// image.src:
image.src = source.indexOf('_blur.jpg') === -1 ? source.replace('.jpg','_blur.jpg') : source.replace('_blur.jpg', '.jpg');
}
// retrieving all <img> elements from the document,
// and converting the NodeList to an array, using
// Array.prototype.slice, along with Function.prototype.call:
var images = Array.prototype.slice(document.getElementsByTagName('img'), 0);
// iterating over those <img> element nodes using
// Array.prototype.forEach():
images.forEach(function (image) {
// 'image' here is the DOM Node from the Array over
// which we're iterating:
image.addEventListener('click', toggleBlur);
});
To use your – quite sensible – object-based approach, though, I'd suggest:
// here we store the blurred and non-blurred states together:
var imageObject = {
'apple' : 'apple_blur',
'apple_blur' : 'apple',
'mango' : 'mango_blur',
'mango_blur' : 'mango',
'pineapple' : 'pineapple_blur'
};
function toggleBlur () {
// caching the <img> element node:
var image = this,
// here we use getAttribute() to get the attribute value,
// as using image.src returns the full absolute URL and we only need
// the file-path (assuming your image element's HTML remains as-
// written in your posted code), we then replace the '.jpg' with
// an empty string, to remove the file-type:
source = image.getAttribute('src').replace('.jpg', '');
// setting the 'src' attribute, with setAttribute(), to
// the value associated with the current attribute-value
// in the imageObject:
image.setAttribute('src', imageObject[source]);
}
var images = Array.prototype.slice.call(document.getElementsByTagName('img'), 0);
images.forEach(function (image) {
image.addEventListener('click', toggleBlur);
});
References:
Array.prototype.forEach()
.Array.prototype.slice()
.EventTarget.addEventListener()
.Function.prototype.call()
.String.prototype.indexOf()
.String.prototype.replace()
.Upvotes: 1
Reputation:
Edit:
There are few corrections in your code:
window.onload = pageLoadedHandler;
/* moved outside to make it global and used `var` keyword */
var blur_images=[{id_pic:["apple","apple_blur.jpg"]},{id_pic:["mango","mango_blur.jpg"]}, {id_pic:["pineapple","pineapple_blur.png"]}];
function pageLoadedHandler() {
for(var i=0;i<blur_images.length;i++) { //removed `=` sign and using `i++` instead of `++i`
// ^ ^^
document.getElementById(blur_images[i].id_pic[0]).onclick=blur_func;
}
}
function blur_func(e) {
e = (e || window.event); //get the right event
var id = (e.target || e.srcElement).id; //get the clicked image id
var blur_image;
for(var i=0;i<blur_images.length;i++) { //removed `=` sign and using `i++` instead of `++i`
// ^ ^^
if(id === blur_images[i].id_pic[0]){//got the one clicked
blur_image=blur_images[i];
break;
}
}
document.getElementById(blur_image.id_pic[0]).src=blur_image.id_pic[1];
}
P.S. use var
keyword whenever you need to declare variables to avoid un-expected behavior.
Upvotes: 1