I am a beginner in Javascript/jQuery. Thank you for reading!
EDIT:
Here is a jsfiddle with all of the code (annotated) https://jsfiddle.net/sfs1926/n1sopf79/
It does not work, but here is a working example video of what my code does so far: https://www.youtube.com/watch?v=N67Bx9jgPFo
The context is: I am trying to model layers of electronics (represented as rectangles) on a graph. There are 10,000 overlapping rectangles (each representing the position of a piece of electronics). I write these area elements in line by line from a text file that contains the coordinates of each rectangle and its title. I associate each area element with its title using an overlay id. My goal: When I mouse over a pixel on the graph, I want to display ALL rectangles associated with that pixel and their overlay id's (to the side, off the graph). So far I am able to do all of this besides displaying the rectangles.
Right now I have a HTML map 'demo' containing many area elements (all rectangles). I want to use jQuery to push each of those area elements into the array elementPositions. This I do successfully below, but with one exception: I want to create the identifier 'element' to be that area element written as a div with css. This is because I want to show and hide rectangles belonging to elementPositions using the .show() method. That is why I am converting the area elements to be divs.
Can someone help me with the syntax for how to do this conversion? I think the reason why no rectangle will 'show' is because I have not set the display or the background attribute of the div, but I'm not sure how to do this.
if( $('#demo').length >0 ) {
var elementPositions = [];
$('#demo area').each(function() {
var offset = this.coords;
var coordarray = offset.split(",");
var left = coordarray[0];
var top = coordarray[1];
var right = coordarray[2];
var bottom = coordarray[3];
var id = this.id;
var wid = right - left;
var hei = bottom - top;
var hoveredElements = [];
elementPositions.push({
element: $('<div class="area"></div>')
.css({position: 'absolute', left: left, top: top}).
width(wid).height(hei), // attempt so far!
top: top,
bottom: bottom,
left: left,
right: right,
id: id,
});
Then I hope to do something like:
$("body").mousemove(function(e) {
elementPositions.forEach( function(item) {
item.element.show();
});
}
you need to append your div before show it, append to body for example :
var elementDiv = $('<div class="area"></div>')
.css({position: 'absolute', left: left, top: top}).
width(wid).height(hei);
$("body").append(elementDiv );
elementDiv.hide();
elementPositions.push({
element: elementDiv ,
top: top,
bottom: bottom,
left: left,
right: right,
id: id,
});
Related
I am using the following code (Javascript within a webpage) to create a 'new' element in the DOM dynamically. I wish to position this say 200px 'below' an existing element. However my output has the positioning of the new element(s) all wrong...as if the position (top, left) I am specifying is ignored.
var _reference = document.getElementById("outputs");
for (_count = 0; _count < _limits; _count++) {
var _structure = document.createElement("div");
_structure.setAttribute("class", "container-fluid");
_structure.setAttribute("id", "struct_" + _tally);
if (_count === 0){
_rect = _reference.getBoundingClientRect();
//get the bounding box of the "outputs" id element...
document.getElementById("outputs").appendChild(_structure);
_structure.style.top = _rect.top + "200px"; //NOT positioned 200px below 'outputs'
_structure.style.left = _rect.left; //NOT positioned same position as 'outputs'
} //_count is "0"
} //for loop
I would have thought this should be fairly straightforward...however it is driving me crazy...any help appreciated.
You'll need to set _structure.style.position to 'relative', 'absolute', 'fixed', or 'sticky' in order to use top, left, right, bottom.
You need to set your position to realtive or absolute in order for this to work, also note that position: absolute sets the position according to the nearest relative positioned parent while position: relative positions according to the current position of the element
I have a div element of css width and height, 800x600. I am using javascript to generate three object elements in the div that should be in a diagonal line, touching each other. I am using position:relative, and the left and top css properties to position the object elements. However when I do it this way, there is a horizontal gap between the squares that shouldn't be there. When I use positon:fixed, they line up how I want it but not inside the div element.
Html of my div element
<div id="Stage" style="background:black;width:800px;height:600px;margin-left:auto;margin-right:auto;overflow:hidden;">
and my javascript
w="w";
level_data =
[
[w,0,0],
[0,w,0],
[0,0,w],
];
function generate(level_data){
for(row=0;row<level_data.length;row++){
for(col=0;col<level_data[row].length;col++){
posx = col*50; posy=row*50;
if(level_data[row][col]=="w"){
entity = document.createElement('object');
entity.style.position = "relative";
entity.style.left = String(posx)+"px"; entity.style.top = String(posy)+"px";
entity.data = "Objects/Sprites/Wall.jpg";
document.getElementById("Stage").appendChild(entity);
}
}
}
}
generate(level_data);
This is what I get: Link1
This is what I want: Link2 but the redsquares inside the big black square instead. What's the problem?
position: fixed positions elements relative to the viewport. position: relative gives that result because object element probably has some default value for widht and height. You'll need something like this:
entity.style.position = "absolute";
entity.style.left = String(posx)+"px";
entity.style.top = String(posy)+"px";
entity.style.width = "50px";
entity.style.height = "50px";
When using position: absolute, the code is supposed to work even without dimensions for the entity. Notice , that when using position: relative you should not multiply position values with col, they should be just 50px.
What i'm trying to do is append hotspots on top of an existing image. As of right now this code appends the new div and image but does so next to the image and not on top of it. I'm new to javascript and jquery so any help is appreciated.
//build data structure to store coordinates and content.
var product_hotspots = new Array();
product_hotspots[0] = {x: 200, y:200, content: "This is test content"}
product_hotspots[1] = {x: 500, y:500, content: "This is more test content"}
product_hotspots[2] = {x: 400, y:400, content: "This is even more test content"}
//loop through each hotspot.
$(product_hotspots).each(function(idx) {
//append a new div to #product_image for each hotspot with the following format:
var $newdiv1 = $('<div id="bullet" style="position: absolute; top: product_hotspot[idx].x; left: product_hotspot[idx].y" data-content="product_hotspot[idx].content"></div>');
var $image1 = $('<img src="images/hotspot.png"/>');
$("#product_image").append($newdiv1,$image1);
});
Your concatenation of the properties taken from object is incorrect. You are missing quotes that tell javascript they aren't strings and values of a javascript object
Try
$('<div id="bullet" style="position: absolute; top:'+product_hotspot[idx].x+'px; left:'+product_hotspot[idx].y+'px" data-content="'+product_hotspot[idx].content+'"></div>');
Notice the syntax highlighting of the product_hotpsot items reflecting they are not string
NOTE: I believe you have x and y in wrong positions within the style. Normally x is left not top
I want to place many divs in a form of a circle. I will use relative positioning for the divs. For a start I am trying to place four divs around the circle
div 1 - top 50,
left 100
div 2 - top 100,
left 150
div3 -
top 150,
left 100
div 4 -
top 100,
left 50
I will be calculating the values in the actual case and setting them but for now it does not matter.Is it possible to create four divs (in an actual case it will be a large number)inside an outer div. But I need to assign differenet sequential ids to these divs and place them at the positions menntioned.
I will have to calculate and then assign top and left positions using script. So could you show how to assign these values using script.
This is really a nice question, as it requires also some math backgrounds.
So, first, let's say what we are going to do:
0. you must decide the center of the circle and its radius
1. we must decide at which angle, on a circle, we should put our divs
2 we should then make a function which, given the angle, gives you the position of the div
So, what do we do wth all that?
decide which should be the center of the circle (if it has to stay in the center of the page
decide the radius (could be calculated as well according to windows dimension)
some trigonometry: to understand the angle iterval, just divide 360° by the number of divs: if you have two divs, then you angle interval is 360/2=180 (ugly). If you have 10 divs your intrval is 36°
Very good, now we're ready to code.
get center: I just redirect you to t it at this stackoverflow link
use the same code to decide tha radius
the function which takes, as input, the number of divs, the radius, the center, and gives you back an array with the divs coord. the center is a 2 places array (x and y). In the function we make some adjustment to output the actual postion of the div.
.
function getCoords(divNum, radius, center){
var num= divNum;
var angleInt= (6.28/num);
var outArray=[];
for (i=0;i<divNum;i++){
outArray.push([(Math.cos(angleInt*i)*radius+center[0]),(Math.sin(angleInt*i)*radius+center[1])]);
}
return outArray;
}
Well, it's done, now you can place your divs with any jquery method, like in this example:
var localization=getCoords(10,200,[400,400]);
var i=1;
for (var element in localization){
var posTop=localization[element][0];
var posLeft=localization[element][1];
var element= $("<div class='inner'>"+i+"</div>");
$(element).css({ position: "absolute",
marginLeft: 0, marginTop: 0,
top: posTop, left: posLeft });
$("body").append(element);
i=i+1;
}
hope this helps
<script>
$(document).ready(function() {
"use strict";
var NR_OF_ITTERATIONS = 4,
RADIUS = 40,
i,
$wrapper = $("#wrapper");
for(i=0;i<NR_OF_ITTERATIONS;i+=1) {
$wrapper.append(
$("<div/>")
.css({
top: /* Top position */,
left: /* Left position */
});
);
}
};
</script>
<style>
#wrapper > div {
position: absolute;
border: 1px solid black;
width: 40px;
height: 40px;
}
</style>
<div id="wrapper"></div>
Here is the code to generate divs. Put your top and left style in style attr of the div. You can ignore the random number. I used it just as place holder.
<div id="outterDiv" class="outterDivision"> </div>
var html = '';
var i;
for(i=0;i<=4;i++) {
var Random_Number = Math.ceil(Math.random()*500+i);
html +='<div id="inner'+i+'" class="anything" style="top:50px; left:100px;">'+Random_Number+'</div>';
}
$('#outterDiv').html(html);
I have something vaguely like the following:
<div id="body">
surrounding text
<div id="pane" style="overflow: auto; height: 500px; width: 500px;">
lots and lots of text here
<span id="some_bit">tooltip appears below-right of here</span>
</div>
more surrounding text (should be overlapped by tooltip)
</div>
and:
<div id="tooltip" style="width: 100px; height: 100px;">Whee</div>
What I want to do is insert the tooltip such that it is positioned above the pane it's in. If it's attached to an element that's next to the pane boundary (like above), then it should be visible above the pane, and above the text surrounding the pane.
It should NOT a) extend the pane, such that you have to scroll down to see the tooltip (like in http://saizai.com/css_overlap.png), or b) be cut off, so you can't see all of the tooltip.
I'm inserting this with JS, so I can add a wrapper position:relative div or the like if needed, calculate offsets and make it position:absolute, etc. I would prefer to not assume anything about the pane's position property - the tooltip should be insertable with minimal assumptions of possible page layout. (This is just one example case.)
It's for a prototype tooltip library I'm writing that will be open source.
ETA: http://jsfiddle.net/vCb2y/5/ behaves visually like I want (if you keep re-hovering the trigger text), but would require me to update the position of the tooltip on all DOM changes and scrolling behavior. I would rather the tooltip be positioned with pure CSS/HTML so that it has the same visual behavior (i.e. it overlaps all other elements) but stays in its position relative to the target under DOM changes, scrolling, etc.
ETA 2: http://tjkdesign.com/articles/z-index/teach_yourself_how_elements_stack.asp (keep defaults except set cyan div 'a' to position:relative; imagine 'A' is the pane and 'a' the tooltip) seems to more closely behave as I want, but I've not been able to get it to work elsewhere. Note that if you make 'A' overflow: auto, it breaks the overlapping behavior of 'a'.
I can't think of a pure HTML/CSS solution for this.
The overflow declaration is the issue here. If the tooltip is in #pane:
you establish a positioning context within #pane, then the tooltip shows next to #some_bit (regardless of scrolling, etc.) but it gets cut-off.
you do not establish a positioning context, then the tooltip is not clipped but it has no clue where #some_bit is on the page.
I'm afraid you'll need JS to monitor where #some_bit is on the page and position the tooltip accordingly. You'd also need to kill that tooltip as soon as #some_bit is outside of the viewing area (not an issue if the trigger is mouseover).
Actually, if the trigger is mouseover then you may want to use the cursor coordinates to position the tooltip (versus calculating the position of #some_bit).
I would just put the tooltip outside of the #pane div and position it absolutely using JavaScript since you're using JS anyway.
I don't use Prototype so I don't know how it's done in Prototype, but in jQuery, you'd use $(element).position() to get the element position. If you have to do it manually, it's a little more complicated.
And you'll probably want to add a little extra logic to prevent the tooltip from extending outside of the document.
Edit: CSS used
#tooltip {
z-index: 9999;
display: none;
position: absolute;
}
JS used
Note: in jQuery, but it should be easy to change it to Prototype syntax.
$('#some_bit').hover(function() {
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
// hovered element
var offset = $(this).offset();
var top = offset.top + docViewTop;
var left = offset.left;
var width = $(this).width();
var height = $(this).height();
var right = left + width;
var bottom = top + height;
// pane
var poffset = $('#pane').offset();
var ptop = poffset.top + docViewTop;
var pleft = poffset.left;
var pwidth = $('#pane').width();
var pheight = $('#pane').height();
var pright = pleft + pwidth;
var pbottom = ptop + pheight;
// tooltip
var ttop = bottom;
var tleft = right;
var twidth = $('#tooltip').width();
var theight = $('#tooltip').height();
var tright = tleft + twidth;
var tbottom = ttop + theight;
if (tright > pright)
tleft = pright - twidth;
if (tbottom > pbottom)
ttop = pbottom - theight;
if (tbottom > docViewBottom)
ttop = docViewBottom - theight;
$('#tooltip').offset({top: ttop, left: tleft});
$('#tooltip').css('display', 'block');
}, function() {
$('#tooltip').hide();
});
Edit: See it here.