only first element in jquery each loop getting updated - javascript

Hi I am just trying to do an each loop on elements containing the class front but only first element is getting updated for some reason please help. May be it is a silly mistake but i am unable to find it.
jsfiddle:
http://jsfiddle.net/sVTCK/7/
HTML:
<div class="wrapper">
<div class="front"></div>
<div class="front"></div>
<div class="front"></div>
<div class="front"></div>
<div class="front"></div>
<div class="front"></div>
</div>
jquery:
function setSlide(rows, dimension) {
var topPos = 0;
var leftPos = 0;
$(".front").each(function(i, e) {
topPos++;
if (i % rows === 0) {
topPos = 0;
leftPos++;
}
var position = topPos * dimension + " " + (leftPos - 1) * dimension;
e.style.backgroundPosition = position;
e.innerHTML = e.style.backgroundPosition;
});
}
setSlide(3,200);
css:
.front{
width:200px;
height:200px;
background:url(some image);
border:1px solid black;
float:left
}
.wrapper{
overflow:hidden;
width:610px;
}

function setSlide(rows, dimension) {
var topPos = 0;
var leftPos = 0;
$(".front").each(function(i, e) {
topPos++;
if (i % rows === 0) {
topPos = 0;
leftPos++;
}
var position = topPos * dimension + 'px ' + (leftPos - 1) * dimension +'px';
e.style.backgroundPosition = position;
e.innerHTML = e.style.backgroundPosition;
});
}
setSlide(3,200);
THE WORKING DEMO.

ok I've refractored the javascript stlightly into jquery since your using it and moved from the vanilla javascript:
function setSlide(rows, dimension) {
var topPos = 0;
var leftPos = 0;
var front = $('.front');
$.each(front, function(index, val) {
topPos++;
if (index % rows === 0) {
topPos = 0;
leftPos++;
}
var position = topPos * dimension + "px, " + (leftPos - 1) * dimension + 'px';
$(this).css('backgroundPosition', position);
$(this).append(position);
});
}
setSlide(3,200);
http://jsfiddle.net/sVTCK/18/
If you can tell us what your trying to do with the if statement it would help to add the background-position...
You should be reallying on jQuery if you have it in page since it'll be quicker and you should also be caching your variables

Related

What limit value I need set to stop my function?

I'm trying to create a progress bar with a percentage text using only Javascript, but I don't know what value I need set in the function to limit the incrementation. The bar and the text keep increasing.
Need create 4 skills bar with 30% / 50% / 70% and 90%.
Help, plz! Accept any suggestions!
Here is my code.
<div class="progress">
<div class="progress-bar"></div>
<p value="30" class="text">30</p>
</div>
<script>
function update() {
let element = document.querySelector(".progress-bar");
let counter = document.querySelector(".text");
var width = 1;
var identity = setInterval(scene, 10);
function scene() {
if (width >= counter.value) {
clearInterval(identity);
} else {
width++;
element.style.width = width + '%';
counter.innerHTML = width * 1 + '%';
}
}
}
</script>
I am not sure if I am following the issue you are experiencing. I see your code can be improved and would solve some problems. Here what I suggest:
function update() {
let element = document.querySelector(".progress-bar");
let counter = document.querySelector(".text");
let width = 1;
setTimeout(scene, 1);
function scene() {
if (width < 100) {
width++;
element.style.width = width + '%';
counter.innerHTML = width * 1 + '%';
setTimeout(scene, 1);
} else {
//Complete action here
}
}
}
Welcome to Stackoverflow! Below you can see a working example of your code with minimal changes. I just defined that when the percenteage comes up to 100, it clears the interval on the page.
function update() {
let element = document.querySelector(".progress-bar");
let counter = document.querySelector(".text");
var percenteage = 0;
var identity = setInterval(scene, 50);
function scene() {
if (percenteage < 100) {
percenteage++;
element.style.width = percenteage + '%';
counter.innerHTML = percenteage + ' %';
} else {
clearInterval(identity);
console.log("Cleared!");
}
}
}
update();
.progress-bar {
height: 10px;
background-color: red;
}
<div class="progress">
<div class="progress-bar"></div>
<p value="30" class="text">30</p>
</div>

Is there a way to combine multiple divs into one

I have a dynamic group of n by m divs to form a grid. The items in this grid can be selected. The end result which I am hoping to achieve is to be able to combine and split the selected divs.
I have managed to get the divs to show correctly and select them, storing their id's in a list. Is there a way I could combine the selected divs, keeping the ones around it in their place?
#(Html.Kendo().Window()
.Name("window") //The name of the window is mandatory. It specifies the "id" attribute of the widget.
.Title("Dashboard Setup") //set the title of the window
.Content(#<text>
<div id="divSetup">
<div class="dvheader">
<b>Dashboard Setup</b>
</div>
<div>
<p>Enter the number of columns and rows of dashboard elements. This will create an empty dashboard with a set number of items which can be filled with KPI charts.</p>
<br />
<div class="dvform">
<table>
<tr style="margin-bottom: 15px;">
<td>
#Html.Label("Number of Columns: ")
</td>
<td>
<input type="number" name="NumColumns" id="NoColumns" min="1" max="20" />
</td>
</tr>
<tr style="margin-bottom: 15px;">
<td>
#Html.Label("Number of Rows: ")
</td>
<td>
<input type="number" name="NumRows" id="NoRows" min="1" max="20" />
</td>
</tr>
</table>
</div>
</div>
<div style="float: right">
<button id="btnSave" class="k-primary">Save</button>
<button id="btnClose">Close</button>
</div>
</div>
</text>)
.Draggable() //Enable dragging of the window
.Resizable() //Enable resizing of the window
.Width(600) //Set width of the window
.Modal(true)
.Visible(false)
)
<div id="dashboard">
</div>
<button id="combine" title="Combine">Combine</button>
<script>
$(document).ready(function () {
debugger;
$("#window").data("kendoWindow").open();
$("#btnClose").kendoButton({
click: close
});
$("#btnSave").kendoButton({
click: Save
});
$("#combine").kendoButton();
});
var array = [];
function clicked(e)
{
debugger;
var selectedDiv = "";
var x = document.getElementsByClassName('column')
for (var i = 0; i < x.length; i++)
{
if (x[i].id == e.id)
{
x[i].classList.add("selected");
array.push(x[i]);
}
}
for (var x = 0; x < array.length - 1; x++) {
array[x].classList.add("selected");
}
}
function close() {
$("#window").hide();
}
function Save()
{
debugger;
var col = document.getElementById("NoColumns").value;
var row = document.getElementById("NoRows").value;
for (var x = 1; x <= row; x++)
{
debugger;
document.getElementById("dashboard").innerHTML += '<div class="row">';
debugger;
for (var i = 1; i <= col; i++)
{
document.getElementById("dashboard").innerHTML += '<div onclick="clicked(this)" id="Row ' + x + ' Col ' + i + '" class="column">' + i + '</div>';
}
document.getElementById("dashboard").innerHTML += '</div>';
}
}
<style>
.selected {
background-color: #226fa3;
transition: background-color 0.4s ease-in, border-color 0.4s ease-in;
color: #ffffff;
}
#dashboard {
width: 80%;
margin: auto;
background-color: grey;
padding: 20px;
}
* {
box-sizing: border-box;
}
/* Create three equal columns that floats next to each other */
.column {
float: left;
padding: 20px;
border: 1px black solid;
}
/* Clear floats after the columns */
.row:after {
content: "";
display: table;
clear: both;
}
Below is an image of the selected blocks I would like to combine into one, while keeping it's place
If you were using a table it would be much easier, for div's, I can think of a solution if the style position is absolute, maybe it would help you start at least.
<div id="container"></div>
<button id="combine" title="Combine" disabled="disabled">Combine</button>
<div id="output"></div>
the script:
<script>
var cc;
function group() {
var xx = $(".selected").map(function () { return $(this).attr("data-x"); }).get();
var yy = $(".selected").map(function () { return $(this).attr("data-y"); }).get();
this.minX = Math.min.apply(Math, xx);
this.minY = Math.min.apply(Math, yy);
this.maxX = Math.max.apply(Math, xx);
this.maxY = Math.max.apply(Math, yy);
this.selectedCount = $(".selected").length;
this.CorrectGroup = function () {
var s = this.selectedCount;
return s == this.cellsCount() && s > 1;
}
this.width = function () {
return this.maxX - this.minX + 1;
}
this.height = function () {
return this.maxY - this.minY + 1;
}
this.cellsCount = function () {
return this.width() * this.height();
}
}
function cell(x, y, g) {
this.x = x;
this.y = y;
this.g = g;
this.spanX = 1;
this.spanY = 1;
this.visible = true;
var cellWidth = 80;
var cellHeight = 50;
this.div = function () {
var output = jQuery('<div/>');
output.attr('id', 'y' + y + 'x' + x);
output.attr('data-x', x);
output.attr('data-y', y);
output.attr('style', this.left() + this.top() + this.width() + this.height());
output.addClass('clickable');
output.html('(y=' + y + ' x=' + x + ')')
return output;
}
this.left = function () {
return 'left:' + (x * cellWidth) + 'px;';
}
this.top = function () {
return 'top:' + (100 + y * cellHeight) + 'px;';
}
this.width = function () {
return 'width:' + (this.spanX * cellWidth) + 'px;';
}
this.height = function () {
return 'height:' + (this.spanY * cellHeight) + 'px;';
}
}
function cells(xx, yy) {
this.CellWidth = xx;
this.CellHeight = yy;
this.CellList = [];
for (var y = 0; y < yy; y++)
for (var x = 0; x < xx; x++) {
this.CellList.push(new cell(x, y, 1));
}
this.findCell = function (xx, yy) {
return this.CellList.find(function (element) {
return (element.x == xx && element.y == yy);
});
}
this.displayCells = function (container) {
container.html('');
for (var y = 0; y < yy; y++)
for (var x = 0; x < xx; x++) {
var cell = this.findCell(x, y);
if (cell.visible)
cell.div().appendTo(container);
}
}
}
$(document).ready(function () {
$('#combine').click(function () {
$(".selected").each(function () {
var x = $(this).data('x');
var y = $(this).data('y');
var cell = cc.findCell(x, y);
cell.visible = false;
cell.g = 'y';
});
var first = $(".selected").first();
var xx = $(first).data('x');
var yy = $(first).data('y');
var cell = cc.findCell(xx, yy);
var g = new group();
cell.visible = true;
cell.g = xx + '_' + yy;
cell.spanX = g.width();
cell.spanY = g.height();
cc.displayCells($('#container'));
});
//make divs clickable
$('#container').on('click', 'div', function () {
$(this).toggleClass('selected');
if (CheckIfSelectedAreGroupable())
$('#combine').removeAttr("disabled");
else
$('#combine').attr("disabled", "disabled");
});
cc = new cells(12, 10);
cc.displayCells($('#container'));
});
function CheckIfSelectedAreGroupable() {
var g = new group();
return g.CorrectGroup();
}
</script>
Style:
<style>
.selected {
background-color: #226fa3 !important;
transition: background-color 0.4s ease-in, border-color 0.4s ease-in;
color: #ffffff;
}
.clickable {
border: 1px solid lightgray;
margin: 0px;
padding: 0px;
background-color: lightyellow;
position: absolute;
}
</style>
Im starting the divs by the following line, you can hock your form to trigger something similar.
cc = new cells(12, 10);
the combine button will not activate if you dont select a correct group, a rectangle shape selection.
the split will not be hard too but I did not have time to put it together, if this solution help, I can update it for the split.
Note: I wrote this quickly so its not optimized.
to try the solution use :
jsfiddle

Change opacity of a particular div, on mouse hover, and add a text label

My Question is: Change opacity of a particular div, on mouse hover, and add a text label, to display which div is being hovered and changed opacity.
My Solution so far- I have changed the opacity, but for all the divs(HISTOGRAM, basically).
Problem- Want to change for a particular div, on HOVER.
HTML File
<head>
<title>Statistical Histograms</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="boxes.css">
<!-- <script src="alter.js"></script> -->
</head>
<body>
<script type="text/javascript" src="box.js"></script>
<form>
Number:<input type="text" id="number"/><br>
<input type="button" id="button1" value="Draw" onClick="draw()"/><br>
<input type="button" id="button2" value="Change Color" onClick="color()"/><br>
<div id="histContainer" style="position: relative;"> </div>
<!-- <input type="button" id="color_change" style="float: right;" value="Change Color" /> -->
</body>
JavaScript File
function draw()
{
var nums = document.getElementById("number").value.split(",");
console.log(nums);
var w = 40;
var factor = 20;
var n_max = Math.max.apply(parseInt, nums);
var h_max = factor * n_max;
console.log("h max is " + h_max);
console.log("n max is " + n_max);
//var h_max = Math.max(h);
//var a = parseInt(nums);
//var create = document.getElementById("shape");
for (var i = 0 ; i <= nums.length ; i++)
{
//var x = parseInt(nums[i]);
//var final_width = w / x;
var x_cor = (i+1) * w;
//var y_cor = i * w * 0.5;
var h = factor * nums[i];
console.log(x_cor);
console.log(h);
//console.log(h_max);
var change = document.getElementById("histContainer");
//change.className = 'myClass';
var bar = document.createElement("div");
bar.className = 'myClass';
//var c_change = document.createElement("div2");
//change.appendChild(c_change);
change.appendChild(bar);
console.log(change);
//change.style.x.value = x_cor;
//change.style.y.value = y_cor;
bar.style.position = "absolute";
bar.style.top = (h_max - h) + "px";
//bar.style.transform = "rotate(-1deg)"
bar.style.left = i*w*1 + "px";
bar.style.backgroundColor = "rgba(1,211,97,0.6)";
bar.style.opacity = "1.0";
bar.style.width = w + "px";
bar.style.height = h + "px";
//var color1 = document.getElementById("histContainer");
//var bar_color = document.createElement("div");
//color1.appendChild(change);
//bar.style.color = "rgba(1,211,97,0.6)";
}
}
$(document).ready(function() {
$("#histContainer").bind("mouseover", function() {
var shade = $("#histContainer").css("opacity");
$("#histContainer").css("opacity", "0.7");
$("#histContainer").bind("mouseout", function() {
$("#histContainer").css("opacity", shade);
});
//$("histContainer").css("opacity", "0.4");
});
});
Add a class to all divs you would like to attach the hover event to, e.g.
<div class="histogram" id="histogram1"></div>
<div class="histogram" id="histogram2"></div>
<div class="histogram" id="histogram3"></div>
<div class="histogram" id="histogram4"></div>
Then use jquery's hover function to capture the event:
$(document).ready(function() {
$('.histogram').hover(
function() { // handler in
$( this ).css('opacity', 0.7);
// Additional actions (display info, etc.)
}, function() { // handler out
$( this ).css('opacity', 1);
// Additional actions (hide info, etc.)
}
);
})
Use CSS for this.
CSS:
#hover-content {
display:none;
}
#hover-me:hover #hover-content {
display:block;
}
#hover-me:hover {
opacity: 0.8;
}
HMTL:
<div class="container">
<div id="hover-me">
<span>Hover Me</span>
<div id="hover-content">
This content is visible only when you mouse hover the parent div and it has no transition.
</div>
</div>
</div>
Shouldn't you use CSS for that? Give a equal class to your divs and then just do :
.your_div : hover {
opacity: 0.8;
}
check out this snippet if you want only backgroundto be opaque try rgba()
$(document).ready(function() {
$('.histogram').hover(
function() {
$( this ).css('opacity', '0.7');
}, function() {
$( this ).css('opacity', '1');
}
);
})
.histogram{
height:40px;
width:40px;
}
.red{
background-color:red;
}
.blue{
background-color:blue;
}
.green{
background-color:green;
}
.yell{
background-color:yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="histogram red" >1</div>
<div class="histogram blue">2</div>
<div class="histogram green">3</div>
<div class="histogram yell" >4</div>
Use this javascript instead. It works.
function draw()
{
var nums = document.getElementById("number").value.split(",");
var w = 40;
var factor = 20;
var n_max = Math.max.apply(parseInt, nums);
var h_max = factor * n_max;
for (var i = 0 ; i <= nums.length ; i++)
{
var x_cor = (i+1) * w;
var h = factor * nums[i];
var change = document.getElementById("histContainer");
var bar = document.createElement("div");
bar.className = 'myClass';
change.appendChild(bar);
bar.style.position = "absolute";
bar.style.top = (h_max - h) + "px";
bar.style.left = i*w*1 + "px";
bar.style.backgroundColor = "rgba(1,211,97,0.6)";
bar.style.opacity = "1.0";
bar.style.width = w + "px";
bar.style.height = h + "px";
}
}
$(document).ready(function() {
$(document).on("mouseover",".myClass", function(index,el) {
$(this).text($(this).index());
var shade = $(this).css("opacity");
$(this).css("opacity", "0.7");
$(document).on("mouseout",".myClass", function() {
$(this).css("opacity", shade);
});
});
});

javascript algorithm to auto fit multiple images

I was looking for a function which would take the overall width, max height, min height parameters as the input and fit multiple images in the given overall width adjusting their width.
So for an example in this page , all the images (in same row) should get auto adjusted to the same height keeping their original aspect ratio with javascript changing their widths.
Edit: I have Answered
You need only to change the height of the picture. The aspect ratio remains.
function height100() {
var imgages = document.getElementsByTagName('img');
Array.prototype.forEach.call(imgages, function (a) {
a.style.height = '100px';
});
}
<button onclick="height100();">100px height</button><br>
<img src="http://lorempixel.com/400/200/">
<img src="http://lorempixel.com/100/200/">
<img src="http://lorempixel.com/300/200/">
<img src="http://lorempixel.com/400/300/">
<img src="http://lorempixel.com/400/150/">
<img src="http://lorempixel.com/800/200/">
<img src="http://lorempixel.com/450/200/">
<img src="http://lorempixel.com/400/250/">
You dont necessarily need JS to accomplish this, unless your height is dynamic.
Flexbox should be able to take care of it for you.
Here is what you could do.
div {
border: 1px solid black;
display: flex;
flex-flow: row wrap;
}
img {
border: 1px solid red;
max-width: 100%;
height: 100px;
}
<div>
<img src="http://lorempixel.com/400/200/">
<img src="http://lorempixel.com/100/200/">
<img src="http://lorempixel.com/300/200/">
<img src="http://lorempixel.com/400/300/">
<img src="http://lorempixel.com/400/150/">
<img src="http://lorempixel.com/800/200/">
<img src="http://lorempixel.com/450/200/">
<img src="http://lorempixel.com/400/250/">
</div>
If you are looking for a dynamic height, just set the height at run time and could do something like this.
var imgs = document.querySelectorAll('img');
[].forEach.call(imgs, function(img) {
img.style.height = "100px";
});
div {
border: 1px solid black;
display: flex;
flex-flow: row wrap;
}
img {
border: 1px solid red;
max-width: 100%;
}
<div>
<img src="http://lorempixel.com/400/200/">
<img src="http://lorempixel.com/100/200/">
<img src="http://lorempixel.com/300/200/">
<img src="http://lorempixel.com/400/300/">
<img src="http://lorempixel.com/400/150/">
<img src="http://lorempixel.com/800/200/">
<img src="http://lorempixel.com/450/200/">
<img src="http://lorempixel.com/400/250/">
</div>
As stated in the other answers, it's a trivial job to adjust images to have the same height. Once you have scaled the images to have same height, according to their individual aspect ratio they will have different widths. Assuming that you have a certain width per row of images you might do as follows to distribute the images to the rows such that rows evenly get populated with the maximum amount of image and minimum white space.
function lineUpImages(imageWidths,totalWidth){
var sum = imageWidths.reduce((p,c) => p+c),
avg = sum/imageWidths.length;
initial = [...Array(Math.ceil(avg))].map(sa => (sa = [], sa.sum = 0, sa)); // initial rows array
return imageWidths.sort((a,b) => b-a)
.reduce((lines,image) => { var line = lines.reduce((p,c) => p.sum < c.sum ? p : c);
line.push(image);
line.sum += image;
return lines;
},initial);
}
var imageWidths = [...Array(20)].map(_ => ~~(Math.random()*4)+2), // generate a random array of image width values
result = lineUpImages(imageWidths,20); // maximum row width allowed is 20
console.log("Image Widths: :", JSON.stringify(imageWidths));
console.log("Rows:", JSON.stringify(result));
You might also chain up a map instruction to the very end and shuffle the images in each row (shuffling the sub arrays).
The answer so that images are of constant height and fills the outer div.
The example here
The javscript here -
$(function(){
//var pics;
var pic1 = {height:"10", width:"20", ap:1.374, rh:0};
var pics = [pic1];
//pics.push(pic3);
//$('#test').html(pics[2].height);
$('#some').imagesLoaded(function() {
$('#test').html('test ');
$('#some img').each(function(index) {
//setting const height
$(this).height(150);
var apic = {height:$(this).height() , width: $(this).width() ,ap: $(this).width() / $(this).height() , rh:0};
pics.push(apic);
});
$('#test').append(pics.length+ '<br />');
for (var j=1; j <pics.length;j++) {
$('#test').append(pics[j].width + ' ' + pics[j].ap + '<br />');
}
$('#test').append('Calculating width ' + '<br />');
var set = [0];
for (var j=1; j <pics.length;j++) {
var t = 0;
var c = j
do {
t = t+ pics[c].width;
$('#test').append(c + ' ' + t+ '<br />');
c=c+1;
}while (t < 645 && c<pics.length);
c=c-1;
if(t>645) {
c = c -1;
}
set.push(c);
j = c;
}
$('#test').append('Sets are: <br />');
var v = 1;
var st = 0;
for (p = 1; p<set.length; p++) {
$('#test').append(set[p] + ' ');
st = v;
v = set[p];
$('#test').append(p + ': ');
var tot = 0;
var inc = 0;
while(tot < 645 ) {
var tot1=0;
for(var g = st; g<v+1; g ++) {
tot1 =tot1+ (pics[g].ap * (pics[g].height+inc));
}
tot=tot1;
inc = inc+1;
}
for(var g = st; g<v+1; g ++) {
$('#some img').eq(g-1).height ( 150 + inc);
}
$('#test').append( '<br / >');
v = v+1;
}
$('#test').append('<br />');
/*
var tot = 0
var wid;
var wid1;
var inc=0;
var r = 1;
for (r =1; r<pics.length-1; r++) {
inc = 0;
tot = 0;
while ( tot < 645) {
wid = pics[r].ap * (pics[r].height+inc);
wid1 = pics[r+1].ap * (pics[r+1].height+inc);
tot = wid + wid1;
inc = inc+ 1;
}
$('#test').append('Total ' + inc +' '+ wid + ' ' + wid1 + '<br />');
$('#some img').eq(r-1).height ( 150 + inc);
$('#some img').eq(r).height ( 150 + inc);
r=r+1;
*/
}
);
});

Show overlay id using mousemove

Thanks to a really helpful user on this website (whose name I do not know, but I wish to thank and credit him!), I got the following tip on how to store area elements in an array so that when I mouse over a coordinate, I could display all of the overlay id's of the area elements that existed at that coordinate (even if the area elements were not at the same z-level):
I'm just stuck on one thing- once I have gathered all the elements that exist at the coordinate in the hoveredElements array, how do I show their overlay ids?
EDIT:
Here is an example of the full code (the overlay still does not display when I mouse over)
The file test.txt contains:
cscCSL1A15 700 359 905 318
cscCSL1A14 794 400 905 318
I use the maphilight plugin available online, and blanketaphi.png is the plot I use as a background.
<!DOCTYPE html>
<html>
<head>
<title>Detector Elements</title>
<script type="text/javascript"
src="Demo_imagemap_highlight_files/jquery-1.js"></script>
<!-- add maphilight plugin -->
<script type="text/javascript"
src="Demo_imagemap_highlight_files/jquery_002.js"></script>
</head>
<body>
<div class="content">
<div class="map"
style='display: block; background: transparent
url("Demo_imagemap_highlight_files/blanketaphi.png")
repeat scroll 0% 0%; position: relative; padding: 0px; width: 1037px;
height: 557px;'>
<canvas width="1037" height="557" style="width: 1037px; height: 557px;
position: absolute; left: 0px; top: 0px; padding: 0px; border: 0px none;
opacity: 1;"></canvas>
<img style="opacity: 0; position: absolute; left: 0px; top: 0px; padding: 0px;
border: 0px none;" src="Demo_imagemap_highlight_files/blanketaphi.png"
alt="foo" class="map maphilighted" usemap="#demo" height="557" width="1037"
border="0" />
</div>
</div>
<map name="demo" id="demo"></map>
</body>
</html>
<script type="text/javascript">
window.onload = function(){
var f = (function(){
var xhr = [];
var files = [ "test.txt"];
for (i = 0; i < 1; i++) {
(function (i){
xhr[i] = new XMLHttpRequest();
xhr[i].open("GET", files[i], true);
xhr[i].onreadystatechange = function () {
if (xhr[i].readyState == 4 && xhr[i].status == 200) {
// get text contents
j=20000*i + 50000;
var coords = xhr[i].responseText.split("\n");
coords = coords.filter(Boolean) //prevents extra rect with 0 coords
coords.forEach(function(coord) {
var area = document.createElement("area");
var att = document.createAttribute("data-maphilight");
if (i == 0) { //green
att.value = '{"strokeColor":"000000","strokeWidth":2,' +
'"fillColor":"009900","fillOpacity":0.5}';
}
area.setAttributeNode(att);
area.id = "r"+j;
area.shape = "rect";
area.coords = coord.substring(10,coord.length).trim()
.replace(/ +/g,","); // replaces spaces in txt file with commas
area.href = "#";
area.alt = "r"+j;
// create overlay with first term in string
var div = document.createElement("div");
div.id ="overlayr"+j;
div.innerHTML = coord.substring(0,10);
div.style.display = "none";
//increase j
j++;
// get map element
document.getElementById("demo").appendChild(area);
document.getElementById("demo").appendChild(div);
});
$('.map').maphilight();
//display overlay ids by mousing over
var elementPositions = [];
var hoveredElements = [];
if($('#demo')) {
$('#demo area').each(function() {
var offset = $(this).offset();
var top = offset.top;
var left = offset.left;
var bottom = $(window).height() - top - $(this).height();
var right = $(window).width() - left - $(this).width();
elementPositions.push({
element: $(this),
top: top,
bottom: bottom,
left: left,
right: right
});
//alert(top + "," + left + "," + right + "," + bottom);
});
$("body").mousemove(function(e) {
hoveredElements = [];
var yPosition = e.pageX;
var xPosition = e.pageY;
for (var i = 0; i < elementPositions.length; i++) {
if (xPosition >= elementPositions[i].left &&
xPosition <= elementPositions[i].right &&
yPosition >= elementPositions[i].top &&
yPosition <= elementPositions[i].bottom) {
// The mouse is within the element's boundaries
$("#hovers").append(elementPositions[i].element);
}
}
for (var i = 0; i < hoveredElements.length; i++) {
// The element as a jQuery object
var elem = hoveredElements[i];
var id = hoveredElements[i].attr('id');
$('#overlay'+id).show();
}
});
};
}
};
xhr[i].send();
})(i);
}
})();
};
</script>
Why not just something like this:
var elementPositions = [];
var hoveredElements = [];
if($('#demo')) {
$('#demo area').each(function() {
var offset = $(this).offset();
var top = offset.top;
var left = offset.left;
var bottom = $(window).height() - top - $(this).height();
var right = $(window).width() - left - $(this).width();
elementPositions.push({ element: $(this), top: top, bottom: bottom, left: left, right: right });
//alert(top + "," + left + "," + right + "," + bottom);
});
$("body").mousemove(function(e) {
hoveredElements = [];
var yPosition = e.pageX;
var xPosition = e.pageY;
for (var i = 0; i < elementPositions.length; i++) {
if (xPosition >= elementPositions[i].left &&
xPosition <= elementPositions[i].right &&
yPosition >= elementPositions[i].top &&
yPosition <= elementPositions[i].bottom) {
// The mouse is within the element's boundaries
hoveredElements.push(elementPositions[i].element);
$("#hovers").append(elementPositions[i].element);
}
} //end of for loop over all elements
console.log(hoveredElements);
for (var i = 0; hoveredElements.length; i++)
{ //for loop over all hovered elements
// The element as a jQuery object
var elem = hoveredElements[i];
var id = hoveredElements[i].attr('id');
console.log(id);
$('#overlay'+id).show();
// Do stuff to that jQuery element:
//??? something like elem.show();
}
You've got a lot of stuff here that doesn't make sense to me but here's what I can gather so far.
Your areas need to be in a container called demo area. Not sure how the space in the ID works so in my case I switched it to demoarea. Also somewhere in the page, there has to be another element called demo for anything to even happen.
Once that's done, the script loads demoarea into the elementPositions array. Judging from your description that's not what you want to do, you probably want to load all the elements inside demoareainto the array. So the first change is
$('#demo area').each(function() {
Becomes
$('#demoarea').children().each(function() {
Now what becomes confusing to me is that this script for whatever reason decides that you need to have another element called hover so it can move the element out of demoarea into hover when you mouse over it. If that is what you want, then you can do your show trick with some simple CSS.
<div style="display:none" id="overlayr6064"> Example Overlay ID name </div>
Becomes
<div id="overlayr6064"> Example Overlay ID name </div>
And then you add:
<style>
#demoarea div {
display: none;
}
#hover div {
display: block;
}
</style>
Assuming that is not what you wanted, what #liamEgan did to add the elements to the hoveredElements array is good, but you have an infinite loop here
for (var i = 0; hoveredElements.length; i++)
it should be
for (var i = 0; i < hoveredElements.length; i++)
Then the rest works... except one last thing, you want to load these listeners to your script when the page loads in a document ready method.
So in all it looks a bit like:
//display overlay ids by mousing over (my map is called 'demo')
var elementPositions = [];
var hoveredElements = [];
if($('#demo')) {
$('#demoarea').children().each(function() {
var offset = $(this).offset();
var top = offset.top;
var left = offset.left;
var bottom = $(window).height() - top - $(this).height();
var right = $(window).width() - left - $(this).width();
elementPositions.push({ element: $(this), top: top, bottom: bottom, left: left, right: right });
});
console.log('After Scanning demoarea elementPositions looks like:')
console.log(elementPositions);
$(document).ready(function () {
$("body").mousemove(function(e) {
hoveredElements = [];
var yPosition = e.pageX;
var xPosition = e.pageY;
for (var i = 0; i < elementPositions.length; i++) {
if (xPosition >= elementPositions[i].left &&
xPosition <= elementPositions[i].right &&
yPosition >= elementPositions[i].top &&
yPosition <= elementPositions[i].bottom) {
// The mouse is within the element's boundaries
if (typeof elementPositions[i].element != "undefined") {
hoveredElements.push(elementPositions[i].element);
$("#hovers").append(elementPositions[i].element);
}
}
} //end of for loop over all elements
for (var i = 0; i < hoveredElements.length; i++) { //for loop over all hovered elements
// The element as a jQuery object
console.log(hoveredElements[i]);
if (typeof hoveredElements[i] != "undefined") {
var elem = hoveredElements[i];
var id = elem.attr('id');
$('#overlay'+id).show();
}
// Do stuff to that jQuery element:
//??? something like elem.show();
}
});
});
}
#demoarea {
border: 2px blue dotted;
}
/* Border added so I can see where to mouse over */
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="demo">
<div id="demoarea">
<area shape="rect" coords="431,499,458,491" href="#" id="r6064" alt="r6064">
<div style="display:none" id="overlayr6064"> Example Overlay ID name </div>
</div>
<div id="hovers">
</div>
</div>
Edit: sorry I added the undefined tests while fixing this because of the infinite loop but I think they're not really needed. Still nice to have though. Also since the area also gets moved into the hover area this script does try to show an element called overlayoverlayr6064r6064 which fortunately doesn't exist. But ya, again, probably not what you had in mind.

Categories

Resources