repzero
repzero

Reputation: 8412

Handling events in Javascript

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

Answers (3)

Frank B
Frank B

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

David Thomas
David Thomas

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:

Upvotes: 1

user2575725
user2575725

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

Related Questions