Make a kindof popup window appear using javascript - javascript

I have a HTML page & when a link is clicked I am trying to make a popup element(just a div box that appears over the link) appear above the link that was clicked. I use javascript to do this, but my problem is that the popup element gets positioned below the link when it should be above the link.
Do you know what I am doign incorrectly & how I can fix it?
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><!-- InstanceBegin template="/Templates/homepage.dwt" codeOutsideHTMLIsLocked="false" -->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<style type="text/css" media="all">
<!--
html, body, div, form, fieldset, legend, label, img { margin: 0; padding: 0; } table { border-collapse: collapse; border-spacing: 0; } th, td { text-align: center; } h1, h2, h3, h4, h5, h6, th, td, caption { font-weight:normal; } img { border: 0; }
body { padding: 20%; background-color: green; }
.container { background-color: white; }
.newEle { width: 100px; height: 100px; background-color: red; }
-->
</style>
<script type="text/javascript">
function getOffset( el )
{
var _x = 0;
var _y = 0;
while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) )
{
_x += el.offsetLeft - el.scrollLeft;
_y += el.offsetTop - el.scrollTop;
el = el.parentNode;
}
return { top: _y, left: _x };
}
function onClick( n, ele )
{
// Should display a popup box just above the HTML element called "ele"
// but what actually happens is that the box is displayed below the element
// called "ele"
var infoBox = document.createElement("div");
infoBox.style.zIndex = "5";
//infoBox.offsetRight = ele.offsetRight;
//infoBox.offsetBottom = parseInt(ele.offsetBottom, 10) - 200 + "px";
infoBox.style.x = getOffset( ele ).left + "px";
infoBox.style.y = getOffset( ele ).top - 200 + "px";
infoBox.style.width = "200px";
infoBox.style.height = "200px";
infoBox.style.backgroundColor = "blue";
infoBox.innerHTML = "Hello";
document.body.appendChild( infoBox );
}
</script>
</head>
<body>
<div class="container">
<a class="newEle" onclick="onClick(1,this)">Create New Element</a>
</div>
</body>
</html>

add this to your css.
.container, .newEle {display: block; float: left;}
Then position your elements absolutely.

(Aside from Carl Griffiths post take a look on this)
Inspecting your code, the reason why it is below your link is:
Your appending the new element after your div.
You said you have a x and y style. But it is not applying on that element.
(Use firebug for FF or in Chrome use developer-tools)
Let say you successfully add the position style on the new element.
Your next problem is, it will not visible on the page.
What I mean is, if you set the top position to -200px it will relatively position
to your body not in your link.
Possible Fix:
Instead of using document.body.appendChild( infoBox );
Add an id to your div like id="container". Then replace your append with this.
var parentContainer = document.getElementById('container');
parentContainer.insertBefore(infoBox,parentContainer.firstChild);
I'm not pretty sure about your infoBox.style.x but instead you can use this infoBox.style.left = "0px;" and infoBox.style.top = "-200px" then you must use positioning e.g. relative/absolute
If you follow the second option you must properly set the CSS style of your div. Specially this body { padding: 20%; background-color: #CCCCCC; } If you find it difficult to understand my explanation. Here a sample code (jsfiddle) it is not as perfect as you want. But you can use enhance on your needs.

I've got a component that might make this simpler - it's not as complete as framework would be, but it's pretty good at what it does:
http://depressedpress.com/javascript-extensions/dp_panelmanager/
It basically creates "panels" out of HTML elements (either existing or generated) and provides methods to work with them. Position, Size, Opacity, simple animations, collision detection, bearing, etc. It's definately got holes, but it's come in handy.
One of the examples is a simple "popup definitions" thing that should be pretty easy to modify to fit your needs.
Basically you create panels for your popups and also turn your click targets into panels (the example shows how you do that with minimal code). Then your onClick event handler might have something like this:
// Set the Popup panel to the same position as the clicked element.
PopPanel.setPosition(this.getPosition());
// Shift the position of the popup panel up 210 pixels
PopPanel.shiftPosition([-210, 0]);
// Show the panel
PopPanel.setDisplay("show");
// Fade the panel in (Animate opacity)
PopPanel.setOpacity(100, 0 , 200);
Of course you're not too far off - and the advise already given will probably fix your current problem.

Related

jQuery - Draggable Div with width and height counter (Demo code included)

All.
I've been messing with this project for a few days, trying different codes, making some progress, then getting stuck.
The below code is the closest I've come to a working example.
This one counts the WIDTH from the LEFT panel.
I need it to count the WIDTH from the RIGHT panel.
--UPDATED--
I've made it drag from the RIGHT, and it calculates its width from the RIGHT. Unfortunately, the HEIGHT is still not working when the div grows in height, but the width counts.
As you will see when you run the demo below, when you drag the bar, the left panel does not stay attached, along with other issues.
Almost as if it was designed to run one way only.
I know I am missing something here, just not sure what?
Best Viewed In Full Screen.
Thank you.
Wayne
Here is the code
var info = document.getElementById('Info');
var left = document.getElementById('drag-left');
var right = document.getElementById('drag-right');
$(function() {
$(right).resizable({
minHeight: 200,
minWidth: 320
});
$(left).resizable({
minHeight: 200,
minWidth: 320
});
});
// Left Panel
$(right).resizable({
handles: 'w',
resize: function(event, ui) {
// var width = $("body").width() - ui.size.width;
// var height = $("body").height() - ui.size.height;
var width = ui.size.width;
var height = ui.size.height;
$(left).width(left);
$(info).text("Width: " + width + "px; & Height: " + height + "px;");
}
});
/*This is to create the BAR in the middle to grab.
To change which one gets it, change the (e) to (w)
E = Left panel
W = Right Panel*/
.ui-resizable-w {
background-color: black;
}
.ui-resizable-w:hover {
cursor: col-resize;
}
* {
box-sizing: border-box;
}
p {
color: darkslategray;
}
.drag-container {
display: flex;
width:1000px;
padding:5px;
}
[class^=panel] {
padding: 60px 24px;
background-color: whitesmoke;
}
.panel-one {
width: 100%;
flex: 1 1 auto;
}
.panel-two {
width: 60%;
}
#drag-right, #drag-left {
min-height:200px;
min-width:320px;
border:1px double green;
}
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>CodePen - Simple JS Dragbar</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css">
<link href = "https://code.jquery.com/ui/1.10.4/themes/ui-lightness/jquery-ui.css" rel = "stylesheet">
<script src = "https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="https://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
</head>
<body translate="no" >
<div class="drag-container">
<div class="panel-one" id="drag-left">
<h2>Panel 1</h2>
<p>Look, everyone wants to be like Germany, but do we really have the pure strength of 'will'? But I know you in the future. I cleaned your poop. Large bet on myself in round one. Take me to your leader! My fellow Earthicans, as I have explained in my book 'Earth in the Balance'', and the much more popular ''Harry Potter and the Balance of Earth', we need to defend our planet against pollution. Also dark wizards.</p>
</div>
<div class="panel-two" id="drag-right">
<h2>Panel 2</h2>
<p>So, how 'bout them Knicks? You guys go on without me! I'm going to go… look for more stuff to steal! Guards! Bring me the forms I need to fill out to have her taken away! Do a flip! Calculon is gonna kill us and it's all everybody else's fault!</p>
</div>
</div>
<div style="float:right; height:30px; width:320px; border:1px double green; padding:40px 4px;">Width: 320px;<br />
<span id="Info">Information Goes Here</span>
</div>

How to find the absolute the coordinates of an html element?

I need to find the absolute coordinates of the html element as per the screen. I know i can use getBoundingClientRect().top and getBoundingClientRect().left method to compute the coordinates as per the view port. How do i find the absolute coordinates? Another question is does window.screenX takes into account url and tab bar into account? Help is appreciated.
UPDATE
Added a special measurement:
var offset = window.outerHeight - window.innerHeight
This is the top of the browser to the bottom of the browser bar (or top of viewport). The new coords called UselessXY takes the height of the browser's bar and adds it to the Y coord. If the browser is resized, then it needs to be refreshed in order to get the new offset. This works best if the browser is maximized.
I made a function that'll display clientX, clientY, screenX, and screenY. And offset and uselessXY
Just click anywhere to get coordinates.
SNIPPET
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>COORDS</title>
<style>
*, *:before, *:after { margin: 0; padding: 0; }
body { width: 100vw; height: 100vh; position: relative; }
#display { width: 40ex; height: 50px; border: 1px solid grey; padding: 3px; position: absolute; }
</style>
</head>
<body onmousedown="coords(event)">
<figure id="display" onmouseover="this.style.left = '50%'" onclick="this.style.left = '0'">
<figcaption><u>Coordinates(X,Y)</u></figcaption>
<output id="xy"></output>
</figure>
<script>
function coords(evt) {
document.getElementById('xy').textContent = "screenXY: " + evt.screenX + ", " + evt.screenY +" | clientXY: " + evt.clientX + ", " + evt.clientY+" | Offset: "+offset+" | UselessXY: "+evt.screenX+", "+(evt.screenY + offset);
}
var offset = window.outerHeight - window.innerHeight;
</script>
</body>
</html>
How do i find the absolute coordinates?
use offsetTop
Suppose element's id is
var d = document.getElementById("socialChange");
var topPos = d.offsetTop;
Another question is does window.screenX takes into account url and tab
bar into account?
No, check the documentation here. Area covered by browser's controls are excluded out of the window.screenX and window.screenY.
x_axis = window.screenX + (window.outerWidth - window.innerWidth) + element.getBoundingClientRect().left
The above will get the absolute length from the left of the screen.
Similar case can be done for the y axis.
For the conceptual point of view, this picture can be used.

'Attaching' divs to either side of fluid content (diagram inside...)

I'm trying to figure out the best way to attach two fixed width divs to a fluid center div. I've searched around for an answer to this problem but most people require a 3 column layout to fill the entire width of the screen, whereas I would like a variable amount of whitespace either side.
The intention is that the fluid div will wrap around images scaled to a fixed height but variable width.
Ideally if the edge of the screen is reached the two fixed divs wont go any further. Could this be done with pure css/a framework or is it easier to use javascript? I'm using node.js server-side if it helps.
Right now I'm using inline-block as a way to make it work, but it seems buggy when using percentage widths. It doesn't resize correctly the until page is refreshed, so I was hoping there was a better way.
Center the div containing fluid and fixed elements and, then float:left them.
Demo: http://jsfiddle.net/2utM4/4/
Where is the width coming from? [edit] added offsetWidth.
Here is a javascript approach -- I included an equal-heights routine.
It has the max-width check. The code is commented.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>Title</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<style type="text/css">
* { outline:1px dotted #000; } /* all things */
body { padding:0; border:0; margin:0; }
#bodyid { }
#header, #footer { background:#eee; clear:both; }
#middle3 { background:#fee; clear:both; margin:auto; }
#fixedl { background:#efe; float:left; width:50px; }
#fluid1 { background:#eef; float:left; }
#fixedr { background:#efe; float:left; width:50px; }
</style>
<script type="text/javascript">
function f1() { // process center 3 cols
var wfluid1 = document.getElementById("fluid1").offsetWidth;
var wfixedl = wfixedr = 50; // are fixed
var wfluid1 = Math.min(wfluid1, screen.width - wfixedl - wfixedr); // max
var wmiddle3 = wfixedl + wfluid1 + wfixedr;
document.getElementById("middle3").style.width = wmiddle3 + "px";
document.getElementById("fluid1").style.width = wfluid1 + "px";
colsequal(new Array("fixedl", "fluid1", "fixedr")); // equal heights
}
function colsequal(v1) { // makes column heights equal
var h = document.getElementById(v1[0]).offsetHeight;
for (i=1; i<v1.length; i++) { // get maximum height
h = Math.max(h, document.getElementById(v1[i]).offsetHeight); }
for (i=0; i<v1.length; i++) { // make all maximum
document.getElementById(v1[i]).style.height = h + "px"; }
}
</script>
</head>
<body onload="f1();">
<div id="bodyid">
<div id="header">Header</div>
<div id="middle3">
<div id="fixedl">Fixed<br />1</div>
<div id="fluid1">Fluid<br />1<br />2<br />3</div>
<div id="fixedr">Fixed<br />1<br />2</div>
</div>
<div id="footer">Footer</div>
</div><!-- bodyid -->
</body>
</html>

Created div elements' random margins not working

Problem and source code
I'm trying to create <div>s within another <div> at the click of a button. When the button is clicked, a new inner <div> is created (within the outer <div>) with a unique id. I have this part working but here's where I'm running into an issue: I want each inner <div> to have a random margin-top.
Javascript
function pressButton() {
number += 1;
makeDiv(number);
};
function makeDiv(x) {
var innerDiv = document.createElement("innerDiv" + x);
outer.appendChild(innerDiv);
innerDiv.setAttribute("style", "margin-top:" + Math.floor(Math.random()*51) + ";display:inline-block;width:48px;height:48px;background-color:#000;");
};
CSS:
#outer {
position:absolute;
white-space:nowrap;
height:118px;
overflow:auto;
width:100%;
padding:2px;
}
Result (after button is clicked 4 times)
<div id="outer">
<innerDiv1 style="margin-top:15;display:inline-block;width:48px;height:48px;background-color:#000;"></innerDiv1>
<innerDiv2 style="margin-top:23;display:inline-block;width:48px;height:48px;background-color:#000;"></innerDiv2>
<innerDiv3 style="margin-top:37;display:inline-block;width:48px;height:48px;background-color:#000;"></innerDiv3>
<innerDiv4 style="margin-top:0;display:inline-block;width:48px;height:48px;background-color:#000;"></innerDiv4>
</div>
The result (which I got from inspecting the inner elements in my browser) looks like everything worked - all the margin-tops are random like I wanted. However, the visual result is this:
As you can see, the black inner <div>s all have the same margin-top. What am I doing wrong? How can I make the created <div>s all have random margin-tops?
The CSS spec requires that a length (other than zero) that is missing a unit be treated as an error (and thus ignored). Therefore, add px to the end of your generated margin number, and all should be well.
Live Demo
Description
This happens, because you set the display:inline-block; property. This makes them all to be in one line, so they will allign to the innerDivx that has the highest margin-top.
Delete the display:inline-block; property and give them float:left;. If you want to keep the gap between them, also add margin-left:5px;. And don't forget that margin-top's value needs a unit. I think you wanted to use px.
Also <innerDivx> is not a valid HTML tag. You should change them to a <div> and use innerDivx as an id attribute. Also your tags use almost the same CSS styles so you should put the same ones to a class and add the class instead.
Full solution code
HTML
<button id="button1">Add box</button>
<div id="outer"></div>
JavaScript
var number = 0;
document.getElementById("button1").addEventListener("click", pressButton, false);
function pressButton() {
++number;
makeDiv(number);
};
function makeDiv(x) {
var innerDiv = document.createElement("div");
outer.appendChild(innerDiv);
innerDiv.className += " box";
innerDiv.setAttribute("id", "innerDiv" + x);
innerDiv.setAttribute("style", "margin-top:" + Math.floor(Math.random()*51) + "px;");
};
CSS
#outer {
position: absolute;
white-space: nowrap;
height: 118px;
overflow: auto;
width: 100%;
padding: 2px;
}
.box {
float: left;
width: 48px;
height: 48px;
background-color: #000;
margin-left: 5px;
}
This is likely caused by the position model used for inline-block elements - they're all being vertically-aligned at their bottom line in a row.
I suggest that you simplify this and use position: block with float: left
http://jsfiddle.net/2y5bJ/4/
I also suggest that you stick to standard elements to ensure cross-browser compatibility - don't create your own elements called innerDiv1 etc, but use div elements with unique IDs.
function makeDiv(x) {
var innerDiv = document.createElement("div");
outer.appendChild(div);
innerDiv.setAttribute('id', 'innerDiv' + x);
innerDiv.setAttribute("style", "margin-top:" + Math.floor(Math.random()*51) + "px;");
};
I think there is no tag available with name
<innerDiv1>
This may be the cause.

jquery failing to update background-color css

I have a grid generator, it uses Javascript and jQuery to generate blocks in a grid that are displayed with HTML and CSS. I am trying to set up a button that will change the :hover behavior of the blocks (specifically, change their background-color). I am unable to do this and I'm not sure why my code is not working. I will copy and paste it here and I apologize that it is very long. You can see it in action here: http://codepen.io/anon/pen
HTML
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js">
</script>
<script type="text/javascript" src="script.js"></script>
<title> Odin #2 by Max Pleaner </title>
<link rel="stylesheet" type="text/css" href='stylesheet.css'>
</head>
<body>
<p> Welcome to my Odin Project #2 page. This is me showing off my basic JS and jQuery skills. If you move your mouse through the blocks you can see frogs come out of hiding. If you press the clear button below you can select a new number of blocks to fill the same space.</p>
<button id="button"> Generate a number of blocks of your liking that will position themselves to all fit in the 960px by 960px grid. </button>
<button id="button2"> <strike> Click here to generate new blocks and make hovering on blocks produce random colors.</strike> Why isn't this button working?! It's drawing new blocks fine, but not changing the :hover style as intended. </button>
<div id="square_holder">
</div>
<img src="Q6w802v.jpg" alt="froggy" ></img>
</body>
</html>
CSS
body {
background-color: grey;
}
p {
color: aqua;
}
#square_holder {
width: 960px;
}
.block {
background-color: green;
display:inline-block;
border: 1px solid black;
width: 232px;
height: 232px;
}
.block:hover {
background-color: blue;
//background-image:url("Q6w802v.jpg");
background-size: contain;
}
JS
$(document).ready(function(){
draw_grid(4);
$('#button').click(function(){
get_input();
});
$('#button2').click(function(){
get_input();
$('.block:hover').css("background-image", "none").css("background-color", get_random_color());
});
});
var draw_grid = function (blocks) {
var totalno = Math.pow(blocks, 2);
var dimension = (960 - 1 -(blocks * 2))/blocks;
for(var i = 0; i < totalno; i++){
$("#square_holder").append("<div class='block' id=" + i + "></div>");
};
$(".block").css("height", dimension).css("width", dimension);
}
var get_input = function(){
alert('Do you want to change the number of boxes?<b></b>');
$('#square_holder').empty();
var user_entry = prompt("What number do you choose?");
alert("Watch in awe as the grid fills ..... ");
draw_grid(user_entry);
}
var get_random_color = function() {
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++ ) {
color += letters[Math.round(Math.random() * 15)];
}
return color;
};
You need to use background, not background-color. Taken from the MDN page for background-image:
The CSS background-image property sets one or several background images for an element. The images are drawn on successive stacking context layers, with the first specified being drawn as if it is the closest to the user. The borders of the element are then drawn on top of them, and the background-color is drawn beneath them.
This translates into a declaration of background-image at all (even as none) will sit on top of background-color. Therefore, if you set background instead of background-color, it will supercede all other property-specific declarations.

Categories