I have created a simple tooltip custom tag in ColdFusion that has worked great in IE quirks mode. But now we're moving towards cross-browser support and the placement script is not working correctly when Firefox is put into strict mode. The code is designed to place the tooltip immediately below the element that the user is hovering over, but in strict mode the tooltip is instead appearing about 12-13 pixels too high.
Could someone please tell me why this is occuring? Is the 'top' being reported incorrectly for the hover element, or is absolute positioning working incorrectly for the tooltip element?
Below is some simplified test code that shows the problem; remove the 'DOCTYPE' tag to make it work correctly. Note that this works correctly on IE8 in both quirks mode and standards mode.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<link rel="stylesheet" type="text/css" href="common/css/standard.css" media="screen">
<link rel="stylesheet" type="text/css" href="common/css/standard_projector.css" media="projection">
<title>OTIS Shell</title>
<script>
var stillOver = 0;
function tipShowHide(tipID, deed) {
for (i=1; i<=numTips; i++) {
if (i != stillOver) {
document.getElementById('ToolTip' + i).style.visibility = 'hidden';
document.getElementById('ToolTip' + i).style.display = 'none';
}
}
if (stillOver == tipID) {
if (deed == 1) {
tipTop = getRealTop(document.getElementById('ToolTipParent' + tipID)) + document.getElementById('ToolTipParent' + tipID).offsetHeight;
tipLeft = getRealLeft(document.getElementById('ToolTipParent' + tipID));
tipTop = getRealTop(document.getElementById('ToolTipParent' + tipID)) + document.getElementById('ToolTipParent' + tipID).offsetHeight;
document.getElementById('ToolTip' + tipID).style.top = tipTop + 'px';
document.getElementById('ToolTip' + tipID).style.left = tipLeft + 'px';
document.getElementById('ToolTip' + tipID).style.visibility = 'visible';
document.getElementById('ToolTip' + tipID).style.display = 'block';;
} else {
stillOver = 0;
document.getElementById('ToolTip' + tipID).style.visibility = 'hidden';
document.getElementById('ToolTip' + tipID).style.display = 'none';
}
}
}
function tipOver(tipID, tipDelay) {
stillOver = tipID;
setTimeout("tipShowHide(" + tipID + ", 1)", tipDelay);
}
function getRealLeft(el) {
if (arguments.length==0)
el = this;
xPos = el.offsetLeft;
tempEl = el.offsetParent;
while (tempEl != null){
xPos += tempEl.offsetLeft;
tempEl = tempEl.offsetParent;
}
return xPos;
}
function getRealTop(el) {
if (arguments.length==0)
el = this;
yPos = el.offsetTop;
tempEl = el.offsetParent;
while (tempEl != null){
yPos += tempEl.offsetTop;
tempEl = tempEl.offsetParent;
}
return yPos;
}
var numTips = 1;
</script>
</head>
<body>
<DIV ID="ToolTip1" style="z-index:999; position:absolute; top:0px; left:0px; visibility:hidden; display:none; width:685px; color:#000000; border:1px solid #000000; background-color:#ffffee;" >
<table style="width:200px;">
<tr valign="top">
<td style="width:350px;">
<span style="text-decoration:underline; font-weight:bold;">Test Stuff</span><br>
Test text
</td>
</tr>
</table>
</DIV>
<SPAN ID="ToolTipParent1" ONMOUSEOVER="tipOver(1, 1000);" ONMOUSEOUT="tipShowHide(1, 2);">
<div id="dynaKeyDiv" align="left" class="tableControlHeaderDiv" style="width:#tableWidth#px;">
<table id="dynaKeyTable" border="1" class="tableControlHeader" cellpadding="2" cellspacing="0" style="width:#tableWidth#px;">
<tr>
<td style="width:100%; font-weight:bold;">
Test Element
</td>
</tr>
</table>
</div>
</SPAN>
</body>
</html>
It's invalid to have a div inside a span. You should use a validator to check for those kinds of errors.
If you use a div for the ToolTipParent1 element, your problem goes away.
Related
I created a table using JavaScript, but it doesn't render using my css. so how can I make it work? actually i need more help, my idea is to create a screen that has one button and once you click on it a menu which is a table of one column starting at the top of the screen and end at the end of the screen should be showing. the table would be scrollable and each row has text (url text) with no url line under the text, so when you click on it the page open in all of the screen behind the table and the button. the button should be always showing (but it disappears when i click on it).
the main.js file is
function makeTableHTML() {
var x = document.createElement("TABLE");
x.setAttribute("id", "myTable");
var myArray = [ [ "Name, http://www.google.com" ],
[ "Name, http://www.google.com" ] ];
var result = '<table width = "300">';
for (var i = 0; i < myArray.length; i++) {
result += "<tr><td>";
if (i < 10) {
result += "0" + i + " ";
} else {
result += i + " ";
}
result += '<a href="' + myArray[i][0] + '">';
result += myArray[i][1] + "</a>";
result += "<td></tr>";
}
result += "</table>";
document.write(result);
document.getElementById("channelsmenu").classList.toggle(result);
}
function hideTableHTML() {
var x = document.getElementById('channelsmenu');
x.style.display = 'none';
}
and my html is
<!DOCTYPE html>
<html>
<head>
<title>5Star-IPTV</title>
<link rel="stylesheet" type="text/css" href="css/style.css" />
<script src="js/main.js"></script>
</head>
<body>
<div>
<table>
<tr>
<td>
<div id="channelsmenu" class="dropdown-content"></div>
</td>
<td class="buttons-col"><input type="image"
src="channels-menu.png" class="buttons" alt="channels menue"
onMouseOver="this.src='channels-menu-1.png'"
onMouseOut="this.src='channels-menu.png'" onclick="makeTableHTML()" /></td>
<td class="buttons-col"><input type="image"
src="return-button.png" alt="return button" class="buttons"
onMouseOver="this.src='return-button-1.png'"
onMouseOut="this.src='return-button.png'" onclick="hideTableHTML()" /></td>
</tr>
</table>
</div>
</body>
</html>
and this is the css
table {
width: 100%;
border: 1px solid black;
background-color: #808080;
}
tr {
width: 100%;
align: right;
}
th, td {
text-align: right;
} background-color: #808080;
}
.buttons-col {
text-align: center;
width: 90px;
padding-top: 5px;
}
in HTML you open "th" and close it as "tr". Secondly, please learn to write/format your code properly - it'll be easier to read your code and to help you.
Besides, use the < script > tag at the end of the HTML or run your JS in the function on event DOMContentLoaded
i am trying to get the users screen size and resize an image to fit their screen size my current code works but only in firefox. In IE and Chrome the image never resize could somebody please help me?
http://jsfiddle.net/dwcribbs/ZK4tK/2/
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="../style.css">
<script type="text/javascript" src="../javascript.js"></script>
<script>
window.onload = function(){
var w =screen.availWidth - 20 + "px";
var h =screen.availHeight - 80 + "px";
document.getElementById('full').style= "height:" + h + ";" + "width:" + w; +";";
alert(h+w);
checkCookie();
document.getElementsByClassName('box1')[0].addEventListener('click', correct, false);
document.getElementsByClassName('box1')[0].addEventListener('mouseover', shade, false);
document.getElementsByClassName('box1')[0].addEventListener('mouseout', unshade, false);
document.getElementsByClassName('bg')[0].addEventListener('click', wrong, false);
function shade()
{
document.getElementById('button').style= "background-color: #ADD8E6; opacity:.4;";
}
function unshade()
{
document.getElementById('button').style= " ";
}
function loc()
{
var lo = "OS2.html";
return lo;
}
}
</script>
</head>
<body>
<div style="color: red;" onclick=" alert('Open Microsoft Power Point without *searching* for it\nSave it in the documents library (using backstage-view, save as), with the default name');" id="help">
<center>
?
</center>
</div>
<div class="wrap">
<img id="full" style = "height: 500px; width: 500px;"class="bg" src = "../Pic/desktop.png" >
<div id="button" style=" " class="box box1"></div>
</div>
</body>
</html>
Thanks!
Instead of
document.getElementById('full').style = "height:" + h + ";" + "width:" + w;
+";"; // Useless NaN
you should use [Demo]
var s = document.getElementById('full').style;
s.height = h;
s.width = w;
or [Demo]
document.getElementById('full')
.setAttribute('style', "height:" + h + ";" + "width:" + w);
I have two pages with almost the same code. Both have this CSS code and the two divs:
<style type="text/css">
.visfarve { position:relative; float:left; padding:5px; border:1px solid #666; }
.farver { border:1px solid black; width:75px; height:10px; }
.valgtfarve { width:95px; height:15px; display:block; background-color:white; text-align:center; }
</style>
<div id="vis" style="display:block; font-size:11px;">
Vis farver
</div>
<div id="skjul" style="display:none; font-size:11px;">
Skjul farver
</div>
One page then has this construct:
<table style="width:730px;">
<tr>
<td width="510px">
<div id="visfarve" style="display:none; margin-top:11px;">&npsp;</div>
</td>
<td id="viser" style="border-radius:10px; width:220px; height:inherit"></td>
</tr>
</table>
The other page has this obstruction:
<div id="visfarve" style="display:none; margin-top:11px;"> </div>
<div id="viser" style="margin-top:50px; border-radius:10px; display:none;"> </div>
They share these two js functions:
var farve1 = ["3D3D34","463834","3F383D","433839","333F44","3B3B40","38413D","304344","483C33","313F48","37463B","35453F"];
var farve2 = ["S8505-Y20R","7812-Y87R","S8010-R30B","S8010-R10B","8108-R93B","8207-R38B","S8502-G","S8010-B30G","S8010-Y70R","S8010-R90B","S8010-G10Y","S8010-B90G"];
function colors(vis) {
var setheight = 0;
for(i=farve1.length-1;i>-1;i--) { skriv += "<div class='visfarve' onmouseover=\"document.getElementById('viser').style.background = '#" + farve1[i] + "';\" onmouseout=\"document.getElementById('viser').style.background = 'white';\" onclick='valgtfarve(\"" + farve2[i] + "\",\"#" + farve1[i] + "\");'><table><tr><td class='farver' title='Klik for at vælge' style='background-color:#" + farve1[i] + ";'></td></tr><tr><td><p>" + farve2[i] + "</p></td></tr></table></div>"; setheight += 10; }
document.getElementById('visfarve').innerHTML = skriv;
if(vis) {
document.getElementById('vis').style.display = "none";
document.getElementById('skjul').style.display = "block";
document.getElementById('visfarve').style.display = "block";
document.getElementById('viser').style.display = "block";
document.getElementById('viser').style.height = setheight + "px";
}
else {
document.getElementById('vis').style.display = "block";
document.getElementById('skjul').style.display = "none";
document.getElementById('visfarve').style.display = "none";
document.getElementById('viser').style.display = "none";
document.getElementById('viser').style.height = 0 + "px";
}
}
function valgtfarve(kode, farve) {
if(!valgt) {
if(confirm("Tones en maling kan den ikke returneres.\nAccepter fraskrivelse af returret for tonet maling?")) { valgt = true; }
else {
document.getElementById('vis').style.display = "block";
document.getElementById('skjul').style.display = "none";
document.getElementById('viser').style.height = "0px";
document.getElementById('visfarve').style.display = "none"; return false;
}}
document.getElementById('valgtfarve').value = kode;
document.getElementById('valgtfarve').style.backgroundColor = farve;
}
When I use the div construct the floating divs lies niceley next to each other with 5 divs in each line and breaks when the container div edge is reached. However, inside the td the divs insists on each having the full width of the td - resulting in only one div per line.
How do I get divs inside a td to keep width and float left?
Let's start from a jsFiddle link : Here
I think it's a good practice when you post question.
Please explain where is the problem, in the jsfiddle page I don't see your bug.
I did only little modification, no relevant code changes.
I only defined the variable
var skriv = "";
I am working on developing an asp.net control that I need to be able to drop into other applications. The control is basically a custom dropdown in which a div gets displayed or hidden when another element is clicked.
The problem I am having is in trying to get the dynamic div to align below the element that gets clicked. I wrote a javascript function which should, in theory, allow me to specify two elements and the desired alignment and then move the second element to the correct position in relation to the first element.
I have three test cases which relate to places where I currently expect this control will be used, my current markup and javascript work in all three cases for IE7 but fails for one of the cases in FF3.5 and IE8-standards mode. I have been playing with this for a while and have yet to come up with an answer that fixes the problem case without breaking one of the others. (Note that 90+% of my users are on IE7 with a slow migration towards IE8)
I am looking for any suggestions other than adding a compatibility mode directive to the page, that does fix things in IE8 but I would prefer an alternative if one is possible since I may not always have control over where this is used. Here is an HTML doc which illustrates the relevant markup and javascript along with the test cases. Case three is the one which has problems, instead of aligning neatly under the input element the div is overlapping vertically and offset to the right by a distance equivalent to the width of the select element.
(Note that the real pages utilize a reset style sheet adapted from the one published by Eric Meyer, including/omitting this style sheet has no relevant effect on these test cases.)
<!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" >
<head>
<title></title>
</head>
<body>
<script type="text/javascript">
var VAlign = { "top": -1, "center": 0, "bottom": 1 };
var HAlign = { "left": -1, "center": 0, "right": 1 };
function AlignElements(element1, vAlign1, hAlign1, element2, vAlign2, hAlign2) {
var List1 = BuildOffsetList(element1);
var List2 = BuildOffsetList(element2);
var Index1 = List1.length - 1;
var Index2 = List2.length - 1;
while (Index1 >= 0 && Index2 >= 0 && List1[Index1] == List2[Index2]) {
Index1--;
Index2--;
}
element2.style.top = "";
element2.style.left = "";
var OT1 = 0;
var OL1 = 0;
var OT2 = 0;
var OL2 = 0;
while (Index1 >= 0) {
OT1 += List1[Index1].offsetTop;
OL1 += List1[Index1].offsetLeft;
Index1--;
}
while (Index2 >= 0) {
OT2 += List2[Index2].offsetTop;
OL2 += List2[Index2].offsetLeft;
Index2--;
}
var top = (OT1 - OT2);
if (vAlign1 == VAlign.bottom) {
top += element1.offsetHeight;
} else if (vAlign1 == VAlign.center) {
top += (element1.offsetHeight / 2);
}
if (vAlign2 == VAlign.bottom) {
top -= element2.offsetHeight;
} else if (vAlign2 == VAlign.center) {
top -= (element2.offsetHeight / 2);
}
var left = (OL1 - OL2);
if (hAlign1 == HAlign.right) {
left += element1.offsetWidth;
} else if (hAlign1 == HAlign.center) {
left += (element1.offsetWidth / 2);
}
if (hAlign2 == HAlign.right) {
left -= element2.offsetWidth;
} else if (hAlign2 == HAlign.center) {
left -= (element2.offsetWidth / 2);
}
element2.style.top = top + "px";
element2.style.left = left + "px";
}
function BuildOffsetList(elelment) {
var I = 0;
var List = new Array();
var Element = elelment;
while (Element) {
List[I] = Element;
Element = Element.offsetParent;
I++;
}
return List;
}
</script>
Case 1
<div>
<div id="control1" style=" display:inline; position:relative;">
<div id="control1_div1" style="background-color:Blue; height:75px; width:150px; position:absolute;"></div>
<input id="control1_txt1" type="text" style="width:150px;" />
<script type="text/javascript">
AlignElements(document.getElementById("control1_txt1"), VAlign.bottom, HAlign.left, document.getElementById("control1_div1"), VAlign.top, HAlign.left);
</script>
</div>
</div>
<div style="height:100px;"></div>
Case 2
<div>
<div id="Nav" style="float:left; width:200px; height:150px; background-color:Aqua;"></div>
<div id="Content" style="margin-left:200px; height:150px; background-color:#ddd;">
<div style="margin-left:100px;">
<h5 style="float:left; margin-left:-100px; width:90px; margin-right:10px; text-align:right; font-weight:.9em;">Label</h5>
<div id="control2" style=" display:inline; position:relative;">
<div id="control2_div1" style="background-color:Blue; height:75px; width:150px; position:absolute;"></div>
<input id="control2_txt1" type="text" style="width:150px;" />
<script type="text/javascript">
AlignElements(document.getElementById("control2_txt1"), VAlign.bottom, HAlign.left, document.getElementById("control2_div1"), VAlign.top, HAlign.left);
</script>
</div>
</div>
</div>
</div>
<div style="height:100px;"></div>
Case 3
<div>
<select><option>something</option></select>
<br />
<select><option>something else</option></select>
<div id="control3" style=" display:inline; position:relative;">
<div id="control3_div1" style="background-color:Blue; height:75px; width:150px; position:absolute;"></div>
<input id="control3_txt1" type="text" style="width:150px;" />
<script type="text/javascript">
AlignElements(document.getElementById("control3_txt1"), VAlign.bottom, HAlign.left, document.getElementById("control3_div1"), VAlign.top, HAlign.left);
</script>
</div>
</div>
</body>
</html>
The third case is breaking apart because of the inline display of the parent div - it cause the relative position to have no effect as far as I know.
To test such case use float instead, here is working example:
http://jsfiddle.net/yahavbr/estYF/1/
Thanks to Shadow Wizard for getting me thinking in the right direction. Turns out that the issue is that my absolutely positioned elements do not move to their 0,0 point when I clear the top and left properties. If I change the code to explicitly put them at 0,0 before calculating the offset difference then everything works beautifully.
element2.style.top = "";
element2.style.left = "";
becomes
element2.style.top = "0px";
element2.style.left = "0px";
I have problems with mouseover in Mozilla and Chrome after making it work in IE, for sure I can tell you that my code worked perfectly in Chrome at least, because that's my default browser and I used it for debugging when creating the Javascript and it worked nicely... until I tried to make it work in IE too.
Here I post the full code of the webpage I'm having trouble with:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="WebbShop.aspx.cs" Inherits="FSwebportal.WebbShop" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<style>
.prodShow{width: 100%; text-align:center;border:0; float:right; position:inherit; padding-left:310px;}
#prodFollow{display:block; width:100%; height:100%; position:fixed; overflow:hidden;}
#orderSett{display:block; position:relative; float:left; padding-top:inherit;}
.ShowBig{width:290px;height:290px; padding-top:10px;}
.pTb{width:50px;}
.order{background-color:Transparent;margin:3px;}
.txtArea{border:0;overflow:auto;width:200px;height:100px;}
.prodRow{background-image:url("produktbakgrund.png"); background-repeat:repeat;}
.row{background-color:Transparent;width:100%;margin: 0px auto;display:inline-table;}
.col{background-color:Transparent;width:100%;margin:3px;}
</style>
<title></title>
</head>
<body>
<form id="form1" runat="server">
<center><input type="button" value="Visa allt" onclick="javascript:appendRow()" class="append_row" /></center>
<hr />
<div id="prodFollow">
<table id="dumbTable">
<tr>
<td>
<img id="sideImg" class="ShowBig" src="" alt=""/>
</td>
</tr>
<tr>
<td>
<h3><b>Specifikationer:</b></h3>
<select name="">
</select>
</td>
</tr>
</table>
</div>
<table id="itemList" class="prodShow" cellspacing="0">
<thead>
<tr class="prodRow">
<th>Bild</th>
<th>Förklaring</th>
<th>Artikelnummer</th>
<th>Pris</th>
</tr>
</thead>
</table>
<script type="text/javascript">
function appendRow() {
var tbl = document.getElementById('itemList');
var len = <%= aspInfo.Count %>;
var arr = new Array(len);
var currIndex = 0;
var imgID=0;
<%
for (int x = 0; x < aspInfo.Count; x++) {
Response.Write("arr["+x+"]= '"+ aspInfo[x]+"';");
}
%>
for(row =0; row < arr.length/4;row++)
{
var rad = tbl.insertRow(tbl.rows.length);
rad.setAttribute('class','prodRow');
for (c = 0; c < tbl.rows[row].cells.length; c++)
{
if(c < 1)
{
createCell(rad.insertCell(c), arr[currIndex], 'col',imgID);
imgID++;
}
else {
if(c < 3)
{
createCell(rad.insertCell(c),"<Label class=txtArea>" + arr[currIndex] + "</Label>", 'row',imgID);
}
else
{
createCell(rad.insertCell(c),"<Label class=txtArea>" + arr[currIndex] + " SKR</Label><br>Antal:<input type=text class=pTb /><input type=button width=100px value='Lägg i varukorg'></input>", 'order',imgID);
}
}
currIndex++;
}
}
}
function createCell(cell, text, style,imgID) {
if (style == 'col') {
var arrLen = <% = largeImg.Count %>;
var imgArr = new Array(arrLen);
<%
for (int x = 0; x < largeImg.Count; x++) {
Response.Write("imgArr["+x+"]= '"+ largeImg[x]+"';");
}
%>
var div = document.createElement('div');
div.setAttribute('class', style);
div.setAttribute('className', style);
div.innerHTML = "<a href='#'><img id='" + imgID + "' src='" + text + "' onmouseover=javascript:onImg('" + imgArr[imgID] + "') border='0' alt='Animg' /></a>";
cell.appendChild(div);
}
else {
var div = document.createElement('div');
div.setAttribute('class', style);
div.setAttribute('className', style);
div.innerHTML = text;
cell.appendChild(div);
}
}
</script>
<script type="text/javascript" language="javascript">
function onImg(bigImg) {
var img = document.getElementById('sideImg#');
img.src = bigImg;
alert(img.src.toString());
}
</script>
</form>
</body>
</html>
I hope you can solve it for me.
// wrong var img = document.getElementById('sideImg#');
var img = document.getElementById('#sideImg');
Hope this helps
Thanks for your reply John.
I've figured out the problem, and it was not the code that was wrong.
It was my own fault, created a div to contain a picuture on the left hand side.
Problem was that the div did not think the left hand side was enough but covered full width of the page there by hideing the pictures behind it:P
Well hope this helps someone else doing the same mistake in the future.
regards David