Using jQuery to change image map coord values
I have a pretty complex image map that I would like to shrink by half. To do so would require dividing all the coord values by 2. Since there are thousands of coord values, I was thinking that I could use jQuery to traverse the DOM to find the coord values, and divide them by two. I'm pretty amateur when it comes to JavaScript and jQuery and I wrote the following code that doesn't work to accomplish my task:
$(function(){
$('area').each(function(){
coord_vals= $('area'[coords]).split(',');
new_vals= coord_vals/2;
$('area'[coords]).val(new_vals + ',');
});
});
Here's the first few lines of HTML I'm trying to traverse:
<div id="map">
<img class="map" src="images/us_map.jpg" width="960" height="593" usemap="#usa">
<map name="usa">
<area href="#" title="SC" shape="poly" coords="735,418, 734,419, 731,418, 731,416, 729,413, 727,411, 725,410, 723,405, 720,399, 716,398, 714,396, 713,393, 711,391, 709,390, 707,387, 704,385, 699,383, 69开发者_Go百科9,382, 697,379, 696,378, 693,373, 690,373, 686,371, 684,369, 684,368, 685,366, 687,365, 687,363, 693,360, 701,356, 708,355, 724,355, 727,356, 728,360, 732,359, 745,358, 747,358, 760,366, 769,374, 764,379, 762,385, 761,391, 759,392, 758,394, 756,395, 754,398, 751,401, 749,404, 748,405, 744,408, 741,409, 742,412, 737,417, 735,418"></area>
<area href="#" title="HI" shape="poly" coords="225,521, 227,518, 229,517, 229,518, 227,521, 225,521"></area>
<area href="#" title="HI" shape="poly" coords="235,518, 241,520, 243,520, 244,516, 244,513, 240,512, 236,514, 235,518"></area>
You can do it like this:
$("area").each(function() {
var pairs = $(this).attr("coords").split(', ');
for(var i=0; i<pairs.length; i++) {
var nums = pairs[i].split(',');
for(var j=0; j<nums.length; j++) {
nums[j] = parseFloat(nums[j]) /2;
}
pairs[i] = nums.join(',');
}
$(this).attr("coords", pairs.join(', '));
});
This maintains the formats and converts each valid carefully, here's the output:
<div id="map">
<img class="map" src="images/us_map.jpg" width="960" height="593" usemap="#usa">
<map name="usa">
<area href="#" title="SC" shape="poly" coords="367.5,209, 367,209.5, 365.5,209, 365.5,208, 364.5,206.5, 363.5,205.5, 362.5,205, 361.5,202.5, 360,199.5, 358,199, 357,198, 356.5,196.5, 355.5,195.5, 354.5,195, 353.5,193.5, 352,192.5, 349.5,191.5, 349.5,191, 348.5,189.5, 348,189, 346.5,186.5, 345,186.5, 343,185.5, 342,184.5, 342,184, 342.5,183, 343.5,182.5, 343.5,181.5, 346.5,180, 350.5,178, 354,177.5, 362,177.5, 363.5,178, 364,180, 366,179.5, 372.5,179, 373.5,179, 380,183, 384.5,187, 382,189.5, 381,192.5, 380.5,195.5, 379.5,196, 379,197, 378,197.5, 377,199, 375.5,200.5, 374.5,202, 374,202.5, 372,204, 370.5,204.5, 371,206, 368.5,208.5, 367.5,209">
<area href="#" title="HI" shape="poly" coords="112.5,260.5, 113.5,259, 114.5,258.5, 114.5,259, 113.5,260.5, 112.5,260.5">
<area href="#" title="HI" shape="poly" coords="117.5,259, 120.5,260, 121.5,260, 122,258, 122,256.5, 120,256, 118,257, 117.5,259">
</map>
</div>
You can give it a try here.
I know you said you're just shrinking your image map by half, but I thought I'd give you a bit of code that would make your map responsive. As the image that is using the map is re-sized, the coords change appropriately.
First thing it does is store the original coordinates of the image map, and then runs the function mapResize whenever the page re-sizes.
$(function() {
$("area").each(function() { $(this).attr('data-coords', $(this).attr('coords')) });
$(window).resize(mapResize);
setTimeout(mapResize, 1);
});
var mapResize = function() {
Here you'll see that we grab the image that is using the usemap name. This is here in case you have any other maps on the site that you'd like to use as well.
Then the code divides the images current width by its original width. We later use that number multiplied by the coordinates to give the new value of the coords.
$("map").each(function() {
var img = $("img[usemap='#" + $(this).attr("name") + "']");
if (img[0].naturalWidth) {
widthchange = img.width() / img[0].naturalWidth;
}
else {
widthchange = 1;
setTimeout(mapResize, 1000);
}
//borrowed this from Nick's answer. It was spot on!
$("area").each(function() {
var pairs = $(this).attr("data-coords").split(', ');
for(var i=0; i<pairs.length; i++) {
var nums = pairs[i].split(',');
for(var j=0; j<nums.length; j++) {
nums[j] = parseFloat(nums[j]) * widthchange;
}
pairs[i] = nums.join(',');
}
$(this).attr("coords", pairs.join(', '));
});
});
}
So yeah, that might not be the answer to your exact question, but I think it answers your question and goes a bit further.
I also know this is a 2 year old question, but I was searching for an answer to a question of my own and this was the most helpful thread. Just wanted to add in my adjustment =)
jQuery('#planetmap area').each(function (e) {
jQuery(this).mousemove(function () {
jQuery('#dataval').html(jQuery(this).attr('coords'));
jQuery(this).click(function () {
jQuery(this).attr('title', 'SHASHANK');
var current_cordinate = jQuery(this).attr('coords').split(',');
var nextX = Math.ceil(current_cordinate[2]) + 1;
var NextY = Math.ceil(current_cordinate[3]);
var downX = Math.ceil(current_cordinate[2]) + 1;
var downY = Math.ceil(downX) + 1;
//var new_next_coordinate = jQuery(this).attr('coords', ('0,0,' + nextX + ',' + NextY))
//alert(new_next_coordinate.text());
jQuery(jQuery(this).find('coords','0,0,'+nextX+','+NextY)).attr('title', 'SHASHANK');
alert("SUBMIT");
});
});
});
I think it might be best to write some code to produce a new code for you. Doing this will reduce the initialization time and make your users happier. I threw together a demo, basically it fills a textarea with the transformed code with which you just replace the original.
HTML
<div id="map">
<img class="map" src="images/us_map.jpg" width="960" height="593" usemap="#usa">
<map name="usa">
<area href="#" title="SC" shape="poly" coords="735,418, 734,419, 731,418, 731,416, 729,413, 727,411, 725,410, 723,405, 720,399, 716,398, 714,396, 713,393, 711,391, 709,390, 707,387, 704,385, 699,383, 699,382, 697,379, 696,378, 693,373, 690,373, 686,371, 684,369, 684,368, 685,366, 687,365, 687,363, 693,360, 701,356, 708,355, 724,355, 727,356, 728,360, 732,359, 745,358, 747,358, 760,366, 769,374, 764,379, 762,385, 761,391, 759,392, 758,394, 756,395, 754,398, 751,401, 749,404, 748,405, 744,408, 741,409, 742,412, 737,417, 735,418"></area>
<area href="#" title="HI" shape="poly" coords="225,521, 227,518, 229,517, 229,518, 227,521, 225,521"></area>
<area href="#" title="HI" shape="poly" coords="235,518, 241,520, 243,520, 244,516, 244,513, 240,512, 236,514, 235,518"></area>
<!-- ETC -->
</map>
</div>
<textarea id="newAreaTags"></textarea>
Script
$(document).ready(function(){
var newmap = '', coords;
$('map[name=usa]').find('area').each(function(){
newmap += '<area href="#" title="' + $(this).attr('title') +
'" shape="' + $(this).attr('shape') + '" coords="';
coords = $(this).attr('coords').replace(/\s+/g,'').split(',');
for (var i = 0; i < coords.length; i++){
coords[i] = Math.round(parseInt( coords[i], 10) / 2);
}
newmap += coords.join(',') + '"></area>\n';
});
$('#newAreaTags').val(newmap);
})
You were on the right track it's just you didn't use $(this) in your loop. Also, to get the coords, you can use attr('coords')
Fixed version
$(function(){
$('area').each(function(){
var coord_vals = $(this).attr('coords').split(',');
var new_vals;
for(var i=0; i<coord_vals.length; i++) {
new_vals[i] = coord_vals[i] / 2;
}
new_vals = new_vals.join(",");
$(this).attr('coords').val(new_vals);
});
});
精彩评论