Javascript onclick event to area - javascript

I am trying to add onclick event through javascript to my map element that was created through javascript too , I am not going to paste whole code here but will make a short version .
so this what I have done so far:
var mapimg = createElement("img"); // create and set up img element for map
mapimg.src "some path ";
map.img.width = some with;
map.img.height = some height;
map.usemap = "#Map"; // img element done
var map = createElement("map"); // set map element and attributes for him
map.name = "Map";
map.id = "Map";
area(1-10) = createElement("area"); // creating a 10 areas
area.id = some;
area.shape = some;
area.coords = some; // area allement have same attributes but with different values
// ones i done with are append them to map and then append mapimg and map to body
// now trying to add on click event
map.addEventListener("onClick",function(){
var id = map.getElementById(this);
var img = "images/map/reg" + id + ".jpg";
mapimg.src = img;
});
map are working but onclick event are not working i have writed jquery version that works just fine with a html elements
$(document).ready(function() {
$('area').click(function() {
var title = $(this).attr('title');
var image = "images/map/reg" + title + ".jpg";
$('.mapimg').attr('src', image);
$('#loginsubmitbutton2').show();
$('input[name="village"]').attr('value', title);
})
});
this is a full script

It should not be onclick it should be just click when using addEventListener
map.addEventListener("click",function(){
var id = map.getElementById(this);
var img = "images/map/reg" + id + ".jpg";
mapimg.src = img;
});
OR if you want to use onclick
map.onclick = function(){
var id = map.getElementById(this);
var img = "images/map/reg" + id + ".jpg";
mapimg.src = img;
};
How to add event listener to repeating elements inside a parent
without looping through all of them
If you want to add event to multiple repeated elements inside a parent element, rather than looping through all the elements and wasting memory a good solution is to use the concept of event propagation as explained in the code below: (since I understand map is the parent of area)
map.addEventListener("click", myFunction());
//we attach an event listener to the parent
function myFunction(e){
//e.currentTarget : to which event listener is attached
//e.target: the element which was clicked
if(e.target !== e.currentTarget){
//we only need to hear events from the area (children of map), so we ignore any other events that are called when the parent is clicked by this if statement
var id = e.target.Id;
alert(id);
//your code here
}
e.stopPropagation(); //we stop the propagation of event to the DOM once its purpose is solved
}
This solution is independent of the number of area elements you have. You will avoid using any for loop and wasting memory.

Having multiple elements with an event listener for each one of them is inefficient. jQuery makes it easy by using $(document) as event.target (i.e. the element clicked, hovered, etc.). In plain JavaScript it's possible as well by adding the event listener on the ancestor of the multiple elements.
addEventListener() to an element that contains the group of elements.
event.preventDefault() if event.targets (i.e. the group of elements you want to click) default behavior is undesired (e.g. if e.target is an <a>nchor and you don't want it to jump to somewhere like it normally does).
Set a conditional that will verify what is in the eventPhase* is an event.target and not the event.currentTarget*.
After that important step, you do all of your intended tasks of your functions at this point.
After your functions have completed their tasks, use event.stopPropagation() to stop the event from bubbling* so that no other events are triggered on anything else.
* TD;LR for details on event methods and properties read: eventPhase, currentTarget, and Comparison of Event Targets
Also, read this article about this particular technique.
The following Snippet demonstrates how you use one event listener on a <map> and assign each <area> as a unique event.target. To test it, simply click a planet, and the result will be the coordinates of the event.target and msg that the click event was triggered. Click anywhere that's not covered by a planet, and you get no result, that's the event.stopPropagation() working.
SNIPPET
var map = document.querySelector('map');
map.addEventListener("click", eventHandler, false);
function eventHandler(e) {
e.preventDefault();
if (e.target != e.currentTarget) {
var clicked = e.target.coords;
console.log('click event triggered at ' + clicked);
}
e.stopPropagation();
}
<img src="https://s-media-cache-ak0.pinimg.com/736x/80/f3/06/80f3061369194bef1e2025d9a382d1a2.jpg" usemap='#iMap'>
<map id="iMap" name="iMap">
<area shape="circle" alt="" title="" coords="66,179,10" href="" target="" />
<area shape="circle" alt="" title="" coords="198,141,13" href="" target="" />
<area shape="circle" alt="" title="" coords="152,244,17" href="" target="" />
<area shape="circle" alt="" title="" coords="107,124,17" href="" target="" />
<area shape="circle" alt="" title="" coords="353,203,83" href="" target="" />
<area shape="circle" alt="" title="" coords="438,235,29" href="" target="" />
<area shape="circle" alt="" title="" coords="482,135,25" href="" target="" />
<area shape="circle" alt="" title="" coords="499,271,6" href="" target="" />
<area shape="circle" alt="" title="" coords="262,243,99" href="" target="" />
<!-- Created by Online Image Map Editor (http://www.maschek.hu/imagemap/index) -->
</map>

Use click instead of onclick,you can simply use id instead of getElementById
map.addEventListener("click",function(){
var id = this.id;
var img = "images/map/reg" + id + ".jpg";
mapimg.src = img;
});

Related

How get src value when click on one of the mulitple images in javascript?

I have 3 images in my web page. I want to get src value every time when I clicked on any image. I tried following code but its not working with multiple images.
<div class="test">
</div>
</div>
</div>
</div>
<script type="text/javascript">
function filename(){
//var fullPath = document.getElementsByClassName('dImage').src;
var fullpath = document.getElementsByClassName('dImg').src
console.log(fullPath);
var filename = fullPath.replace(/^.*[\\\/]/, '');
var fileid = filename.split("\deckel.")[0];
//window.location.href = "web-rocketcreator.html?="+fileid;
console.log(fileid);
}
</script>
As the other answers have mentioned the specific problem area, here's an alternative solution.
Instead of attaching a click event to each image you can attach one to the container and listen for events as they bubble up the DOM (known as event delegation.)
// Grab the container, and add an event listener to it
const imageContainer = document.querySelector('.test');
imageContainer.addEventListener('click', filename, false);
function filename(event) {
// Pick out the src attribute from target element
// (the image that was clicked on)
const { target: { src } } = event;
// Use the src as the basis for the rest of
// your calculations
var filename = src.replace(/^.*[\\\/]/, '');
var fileid = filename.split("\deckel.")[0];
console.log(`web-rocketcreator.html?=${fileid}`);
}
.test a {
display: block;
}
<div class="test">
<a href="#" class="part-one">
<img class="dImage" src="images/deckel-1.png" alt="">
</a>
<a href="#" class="part-one">
<img class="dImage" src="images/deckel-2.png" alt="">
</a>
<a href="#" class="part-one">
<img class="dImage" src="images/deckel-3.png" alt="">
</a>
</div>
To get a reference to the object which triggered the click event you need to pass the keyword this as a parameter.
In your case this object is the <a> element. To get it's nested children - the <img> element you need to call the .children method which returns an array. Since there's just the image element you can directly reference it using children[0] and ultimately add the .src property to retrieve the source.
function filename(element){
console.log(element.children[0].src);
}
<div class="test">
</div>
Get src value from image when clicking on it
When you call a function from onClick() you can pass 'this' to the function. This way you will directly have a reference to the clicked element inside the functon
<img src="xxxx.jpg" onclick="myFunction(this)" />
function myFunction(element) {
const src = element.src;
}
Get src value from image when clicking on parent container
<a onclick="myFunction(this)"><img src="xxxx.jpg" /></a>
function myFunction(link) {
const src = link.children[0].src
}

JavaScript event handler click thumbnail to enlarge image

So I am very new to Web Design and am having issues getting my click event handler to work.I cant change the html or css files. My task is to set a click handler to my thumbnails to enlarge the image in the img within the <figure> element. While also setting the figcaption text in the figure to the thumbs title attribute. I need to attach to the div id = thumbnails. My script is not enlarging my thumbnails or titles.
This is my created HTML Doc:
<!DOCTYPE html>
<html lang="en">
<head >
<meta charset="utf-8">
<title>Chapter 9 - Share Your Travels</title>
<link rel="stylesheet" href="css/styles.css" />
<script type="text/javascript" src="js/chapter09-project02.js">
</script>
` `</head>
<body>
<header>
<h2>Share Your Travels</h2>
<nav><img src="images/menu.png"></nav>
</header>
<main>
<figure id="featured">
<img src="images/medium/5855774224.jpg" title="Battle" />
<figcaption>Battle</figcaption>
</figure>
<div id="thumbnails">
<img src="images/small/5855774224.jpg" title="Battle"/>
<img src="images/small/5856697109.jpg" title="Luneburg"/>
<img src="images/small/6119130918.jpg" title="Bermuda" />
<img src="images/small/8711645510.jpg" title="Athens" />
<img src="images/small/9504449928.jpg" title="Florence" />
</div>
</main>
</body>
</html>
Js script:
var thumbs = document.getElementById("thumbnails");
thumbs.addEventListener("click", function (e) {
if (e.target.nodeName.toLowerCase() == 'img') {
var clickedImageSource = e.target.src;
var newSrc = clickedImageSource.replace("small", "medium");
var featuredImage = document.querySelector("#featured img");
featuredImage.src = newSrc;
featuredImage.title = e.target.title;
}
});
var img = document.getElementById("figcaption");
img.addEventListener("mouseover",function (event) {
img.className = "featured figcaption";
});
img.addEventListener("mouseout", function (event) {
img.className = "featured figcaption";
var element = document.getElementById('figcaption');
element.style.opacity = "0.9";
element.style.filter = 'alpha(opacity=0%)';
});
Thanks for any advice and hopefully I can pay it forward for someone else!
I think it causes you the problem. The JS is getElementById, but there's no ID is call figcaption.
var img = document.getElementById("figcaption");
The problem is that you are trying to use getElementById to find something with the id of figcaption; nothing on the page has an id of figcaption, so getElementById returns null.
There are a few ways you could fix it:
Add an id to your <figcaption> element: <figcaption id="figcaption">
Instead of using getElementById, use getElementsByTagName: document.getElementsByTagName('figcaption')[0];. (getElementsByTagName always returns a collection of elements, the [0] grabs the first, and in this case only, one in the collection).
Instead of using getElementById, use querySelector like you did to find the featured image element: document.querySelector("#featured figcaption");
This last approach of using querySelector is what I would recommend in this situation; other times it might be better to add an id to the element.
const thumbs = document.getElementById("thumbnails");
const featuredImage = document.querySelector("#featured img");
const caption = document.querySelector("#featured figcaption");
thumbs.addEventListener("click", function (e) {
if (e.target.nodeName.toLowerCase() == 'img') {
var clickedImageSource = e.target.src;
// for the purposes of this demo, I'm using a placeholder
// image service so I need to change the size slightly differently
let newSrc = clickedImageSource.replace("50x50", "350x150");
//var newSrc = clickedImageSource.replace("small", "medium");
featuredImage.src = newSrc;
caption.textContent = e.target.title;
}
});
caption.addEventListener("mouseover",function (event) {
caption.className = "featured figcaption";
});
caption.addEventListener("mouseout", function (event) {
caption.className = "featured figcaption";
// I changed the value to .5 instead of .9 because with such small
// text the opacity change is barely perceivable.
caption.style.opacity = "0.5";
// This is not needed, this was the old way IE used to do it,
// IE < 9 needed it, but IE < 9 is no longer relevant. Just use opacity.
//element.style.filter = 'alpha(opacity=0%)';
});
<header>
<h2>Share Your Travels</h2>
<nav><img src="http://via.placeholder.com/50x50?text=Menu"></nav>
</header>
<main>
<figure id="featured">
<img src="http://via.placeholder.com/350x150" title="Battle">
<figcaption>Battle</figcaption>
</figure>
<div id="thumbnails">
<img src="http://via.placeholder.com/50x50" title="Battle">
<img src="http://via.placeholder.com/50x50/ff0000/ffffff" title="Luneburg">
<img src="http://via.placeholder.com/50x50/00ff00/ffffff" title="Bermuda">
<img src="http://via.placeholder.com/50x50/0000ff/ffffff" title="Athens">
<img src="http://via.placeholder.com/50x50/000000/ffffff" title="Florence">
</div>
</main>
A few things to note about my version, I used let and const instead of var. Both let and const are well supported these days and should be used instead of var unless you need to support very old browsers. I also only query for the caption and featured image elements once and store them in the scope above the click handler, this allows the code inside the click handler to have access to them via closure. This makes everything slightly more efficient since you don't have to query the DOM to find them each time the click handler runs. In this case the performance gain is moot but it is good to be in the habit of writing code as efficiently as possible so you don't have to think about it when it does matter.
Images are void elements, meaning they can't have any content, so you don't need a closing tag. For this reason I used bare <img> tags instead of self-closing <img /> tags. Self-closing images were only ever needed in XHTML, since it was XML, which has a more rigid syntax than HTML. Another thing to note, you don't need the type="text/javascript" on your <script> tags, it just takes up extra space and doesn't really do anything.
I don't understand what you are trying to do with the mouseover and mouseout handlers. Currently what your code does is:
When the mouse moves over the caption, the featured and figcaption classes are added to the caption.
When the mouse leaves the caption, the featured and figcaption classes are again added to the caption and its opacity is set to 0.9, effectively permanently.
I cleaned it up a little in my example to make it more obvious that is what is happening.

jQuery hover on imagemap does not work

I have an imagemap and want to add a jQuery hover. Basically the whole image shall be replaced with a new one, based on an imagemap. Hovering on certain parts of the image shall result in replacing the image completely. On a mouseout of the mapped areas, it shall flip back to the imagemap. It works fine doing the imageflip with javascript, but I want to change it to jQuery in order to have mor control about the fadeIn and stuff like this. It just seems easier in jQuery.
Here is what Ive got.
<html>
<head>
<!-- LINK ZU JQUERY ONLINE-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
//PRELOAD THE IMAGES
original = new Image(698, 360);
original.src = "imagenes_png/bosque_mapa.png";
azul = new Image(698, 360)
azul.src = "imagenes_png/azul_mouse.png";
verde = new Image(698, 360)
verde.src = "imagenes_png/verde_mouse.png";
//jQUERY HOVER
$(document).ready(function(){
$("#verdeA").hover(function() {
$(this).attr("src" , "verde.src");
}, function() {
$(this).attr("src" , "original.src");
$("#azulA").hover(function() {
$(this).attr("src" , "azul.src");
}, function() {
$(this).attr("src" , "original.src");
});
});
});
</script>
<body>
<!-- INSERT THE PICTURE -->
<img name="bosque" id="bosque" src="imagenes_png/bosque_mapa.png" width="698" height="360" border="0" usemap="#bosque_m" alt="Bosque con animales" />
<map name="bosque_m" id="bosque_m">
<area id="verdeA" shape="poly" coords="643,324,646,322,648,321,651,320,654,320,656,321,658,323,659,324,660,327,659,330,657,332,655,334,654,335,654,332,653,329,653,327,650,326,648,328,648,331,649,332,650,334,652,335,654,337,656,338,658,339,660,341,662,342,662,345,661,348,660,350,657,351,656,351,656,346,656,345,653,347,651,350,650,351,651,353,651,354,653,356,656,356,658,356,660,356,662,356,666,354,668,351,669,349,670,347,669,346,665,346,666,342,667,341,668,340,670,339,672,339,674,341,676,344,676,347,675,351,672,355,670,357,669,360,642,360,644,356,646,353,647,350,648,346,650,340,650,337,646,332,645,330,644,327,643,324"
alt="" />
<area id="azulA" shape="poly" coords="472,249,476,249,479,250,483,251,484,255,485,258,487,261,489,263,493,265,498,266,501,268,504,270,504,271,499,270,495,269,489,268,486,269,484,270,480,269,476,268,473,266,470,262,469,260,468,256,470,253,472,249"
alt="" />
</map>
</body>
</html>
First I preload the images that the imageflip works without delay. Then I delcare the jQuery function, based on the id in my imagemap and then I add the names of the pictures assigned in the preloading.
Buut, it does not work, at all. Nothing is happening.
Where is the mistake?
There are two problems:
First, when you refer to $(this) in your hover handlers, $(this) is referring to your <area> elements, not your <img>. You'll want to refer instead to $("#bosque").
Second, you are setting the src attribute to the actual strings verde.src, azul.src and original.src. It's as if you were saying <img src="verde.src">, which is not what you want. Remove the quotes from around those strings, as in: $("#bosque").attr("src", verde.src"); so that you are setting src equal to the src property of the verde object and not just to a relative URL that is broken.
So the hover section becomes this:
$(document).ready(function(){
$("#verdeA").hover(function() {
$("#bosque").attr("src" , verde.src);
}, function() {
$("#bosque").attr("src" , original.src);
$("#azulA").hover(function() {
$("#bosque").attr("src" , azul.src);
}, function() {
$("#bosque").attr("src" , original.src);
});
});
});
Which only reacts to the mapped areas:

Get href and use as identifier jQuery

Currently I am trying to implement a hover effect for an image map. I swap the image on hover, the replcement image have that section of the map filled with a 'hover' color.
<map name="Map">
<area id="france" shape="poly" coords="98,133,123,129,151,116,165,129,188,140,181,156,175,167,177,176,181,195,171,203,153,201,145,209,110,196,119,171,110,149,94,141" href="/page/france">
<area id="england" shape="poly" coords="94,119,114,115,139,116,150,100,130,69,117,75,119,89,115,106" href="/page/england">
<area id="wales" shape="poly" coords="118,87,112,107,99,100,109,86" href="/page/wales">
// many more areas //
</map>
jQuery
$('#england').hover(
function() {
$('img').attr('src', '/lib/img/layout/map-en.gif');
},
function() {
$('img').attr('src', '/lib/img/layout/map.gif');
}
);
It works very nicely. The problem is I have many areas within my image map. Is there a way with jQuery of getting the last part of the href from a link and putting it into a dynamic working variable?
Example logic:
var identifier = area/href/this
$(identifier).hover(
function() {
$('img').attr('src', '/lib/img/layout/map-'+identifier+'.gif');
},
function() {
$('img').attr('src', '/lib/img/layout/map.gif');
}
);
You can use this :
$('area').hover(function(){
$('img').attr('src', '/lib/img/layout/map-'+this.href.split('/').pop().slice(0,2) +'.gif');
}, function(){
$('img').attr('src', '/lib/img/layout/map.gif');
});
this.href.split('/').pop().slice(0,2) takes the first 2 characters of the last token of the href of the hovered area. You could also give to your areas more normalized identifiants (like "en", "fr") so you wouldn't have to do this extraction.
Using the answer of dystroy and answering your doubt about getting only the end of the href you can use string split:
$("#france").attr('href').split("/")[2]
The [2] is to get the result that is the land name (in the example: france)
Instead of using the 2 you can also first store in a variable and then get the last item using length:
var tmp = $('#france').attr('href').split("/");
tmp[tmp.length-1];
It will print the last item of the href always. In this case "france"

Why doesn't my div swap by .class work?

Having trouble converting the following code from dealing with IDs to Classes.
Basicly what the code does is reveals one Div while hiding another.
In the original version it was simple because the div location was absolute.
With the classes version I need to reveal the next instance of 'product-specs' based on which DIV the onClick was located.
NOTE/EDIT: Their are multiple versions of the same classes on the page. So references to the classes must be specific to the closest instance of the class, based on the location of the link that was clicked.
HTML:
<div id="product-details">
<area shape="rect" onClick="swap3('product-details','product-specs');">
</div>
<div id="product-specs">
<p>Content</p>
</div>
Javascript:
function swap3(oldDivId, newDivId) {
var oldDiv = document.getElementById(oldDivId);
var newDiv = document.getElementById(newDivId);
oldDiv.style.display = "none";
newDiv.style.display = "block";
}
However now I need to add multiple instances of product details Div & Products specs
New HTML:
<div class="product-details">
<area shape="rect" onClick="swap3('product- details','product-specs');">
</div>
<div class="product-specs">
<p>Content</p>
</div>
<div class="product-details">
<area shape="rect" onClick="swap3('product- details','product-specs');">
</div>
<div class="product-specs">
<p>Content</p>
</div>
New Javascript:
????????
Note: (I explain the complete code befoe here, so just put the updated here) remember that when your selector is a className, you will got an array! change the code like this and test again:
function swap3(currentDivId ,oldDivId, newDivId) {
var oldDiv = $(currentDivId).nextAll("div." + oldDivId);
var newDiv = $(currentDivId).nextAll("div." + newDivId);
$(oldDiv).each(function(){ $(this).css({"display" : "none"}); });
$(newDiv).each(function(){ $(this).css({"display" : "block"}); });
}
In native JavaScript, you'd use getElementsByClassName() -- but it's not supported in IE up thru version 8. You can use a purpose-built wrapper script like this one, or use a library like jQuery to abstract away the browser differences.
In jQuery, try something like
function swap( oldClassName, newClassName ) {
$("'." + oldClassName + "'").hide();
$("'." + newClassName + "'").show();
}
To hide the 'details' div and show the immediately-following div, assumed to be 'specs', try this jQuery snippet. It attaches a click handler to every 'product-details' div, and when it fires, it hides that div and shows its immediate sibling:
$(".product-details").click( function() {
$(this).hide();
$(this).next().show();
});
The reverse behavior (hiding the specs and showing the details) is left as an exercise for the reader ;-)
Original:
function swap3(oldDivId, newDivId) {
var oldDiv = document.getElementById(oldDivId);
var newDiv = document.getElementById(newDivId);
oldDiv.style.display = "none";
newDiv.style.display = "block";
}
jQuery:
function swap3(oldDivId, newDivId) {
var $oldDiv = $('#' + oldDivId);
var $newDiv = $('#' + newDivId);
$oldDiv.hide();
$newDiv.show();
}
jQuery Classes:
function swap3(oldDivClass, newDivClass) {
var $oldDiv = $('.' + oldDivClass);
var $newDiv = $('.' + newDivClass);
$oldDiv.hide();
$newDiv.show();
}
Something else you can do is to wrap each of your products inside a div without any class or id. It does make sense to group them like that, something like
<div>
<div class="product-details">
<area shape="rect" onClick="swap3('product-
details','product-specs');">
</div>
<div class="product-specs">
<p>Content</p>
</div>
</div>
<div>
<div class="product-details">
<area shape="rect" onClick="swap3('product-
details','product-specs');">
</div>
<div class="product-specs">
<p>Content</p>
</div>
</div>
Note the extra wrapping divs. Now, you can use the parent element to identify the product specs that you have to show. E.g.: (Maybe there's a better way to do it)
$('.product-details').click(function() {
// Find the specs to show
var $specs = $(this).siblings('.product-specs');
// Hide the other ones
$('.product-specs').not($specs).hide();
// Show the one that you want
$specs.show();
});
Hope it works!

Categories