Wrong values from JS-Accessed DOM - javascript

I encountered a problem while tring to realize a kind of bar containing elements, that are able to slide in and out.
In order to check weather the mouse is inside one of the icons or the custom tooltip that pops up when lasting the cursor over one of them i calculated the absolute position of the elements kind like this:
(element.offsetParent) ? element.offsetTop+abstop(element.offsetParent) : element.offsetTop;
This works fine for 80 - 90 % of all icons. But some of them dont get the right position because the element.offsetTop-access gives me a value alternating to the one in the HTML-inspector of Chrome.
How can you explain this?
Any fixes?
Thanks in advance!
Max
You asked for code - so you'll get it!
Dont say i didnt warned you.
<%
ArrayList<String[]> alArticlesToShow = logic.getArticlesToShow();
if(alArticlesToShow.size() > 1)
{
%>
<div style="padding-bottom:5px; padding-top:3px;">
<%# include file="/include/new/rahmenBlauOben.jsp" %>
<div class="<%= FarbenVerlauf.blau.getRahmen() %>" style="padding-bottom:0px; padding-top:0px; height:43px">
<%
long time = System.currentTimeMillis();
String sCellWidth = "102px";
int iCellWidth = 102;
int iCurrentPos = logic.getNewArticleIndex();
// Offset berechnen
int iOffsetFactor = iCurrentPos - 4;
// if(iOffsetFactor < 0) iOffsetFactor = 0;
int iOffset = iOffsetFactor * iCellWidth;
int iFloaterSize = iCellWidth * alArticlesToShow.size();
int iTooltipSizeX = 400;
int iTooltipSizeY = 300;
String von_datum = null;
String bis_datum = null;
String von_zeit = null;
String bis_zeit = null;
if(logic.isTimeData("von_datum")) von_datum = logic.getTimeData("von_datum");
if(logic.isTimeData("bis_datum")) bis_datum = logic.getTimeData("bis_datum");
if(logic.isTimeData("von_zeit")) von_zeit = logic.getTimeData("von_zeit");
if(logic.isTimeData("bis_zeit")) bis_zeit = logic.getTimeData("bis_zeit");
String searchStationID = logic.getStationID();
%>
<script type="text/javascript">
//<!--
var iCellWidth = <%= iCellWidth %>;
var iFloatingSpeed = 2;
var fOffset = <%= iOffset %>.0;
var iOffsetFactor = <%= iOffsetFactor %>;
var iLoaded = <%= alArticlesToShow.size() %>
var iTooltipDelay = 1000
var iCellSizeX = 75;
var iCellSizeY = 40;
var iTooltipSizeX = <%= iTooltipSizeX %>;
var iTooltipSizeY = <%= iTooltipSizeY %>;
var iTooltipMoveFactor = 2;
var iTooltipScaleFactor = 4;
var iTooltipFadeFactor = 2;
var iShadowOffset = 30;
// Preisberechnung
var von_datum = '<%= von_datum %>';
var bis_datum = '<%= bis_datum %>';
var von_zeit = '<%= von_zeit %>';
var bis_zeit = '<%= bis_zeit %>';
var stationID = '<%= searchStationID %>';
//-->
</script>
<div style="float:left; width:20px; height:40px;">
<img src="/images/new/barButtonLinks.png" style="cursor:pointer" onclick="slideLeft()" />
</div>
<div style="overflow:hidden; width:95%; float:left; padding-left:5px;">
<div style="position:relative; width:<%= iFloaterSize %>px; margin-left:<%= -iOffset %>px;" id="main_floater">
<%
for(String[] article : alArticlesToShow)
{
if(alArticlesToShow.indexOf(article) == iCurrentPos)
{
%>
<%-- Der aktuell auf der Detailseite angezeigte Artikel --%>
<div style="float:left; width:<%= sCellWidth %>;">
<div style="border:2px solid #109EE3; width:75px; height:40px; margin-left:auto; margin-right:auto;">
<div style="margin-left:auto; margin-right:auto; width:40px; height:30px; padding-top:5px;" title="<%= article[2] %>">
<img src="<%= article[1] %>" />
</div>
</div>
</div>
<%
}
else
{
%>
<%-- Alle anderen Artikel --%>
<div style="float:left; width:<%= sCellWidth %>;">
<div onclick="location='<%= article[3] %>';"
onmouseover="mouseInElement('<%= article[0] %>_<%= article[4] %>');"
id="bar_<%= article[0] %>_<%= article[4] %>"
title="<%= article[2] %>"
style="border:1px solid #B3B3B3; cursor:pointer; width:75px; height:40px; margin-left:auto; margin-right:auto;">
<a href="<%= article[3] %>" style="height:40px;" onmouseover="mouseInElement('<%= article[0] %>_<%= article[4] %>');" >
<div onmouseover="mouseInElement('<%= article[0] %>_<%= article[4] %>');" style="margin-left:auto; margin-right:auto; width:40px; height:30px; padding-top:5px;">
<img src="<%= article[1] %>" onmouseover="mouseInElement('<%= article[0] %>_<%= article[4] %>');" />
</div>
</a>
</div>
</div>
<%
}
}
%>
</div>
</div>
<div style="float:right; width:20px; height:40px;">
<img src="/images/new/barButtonLinks.png" class="flippedImageH" style="cursor:pointer" onclick="slideRight()"/>
</div>
</div>
<%# include file="/include/new/rahmenBlauUnten.jsp" %>
</div>
<div class="tooltip" id="tooltip">
<%# include file="/include/new/detailpage/tooltipBlauOben.jsp" %>
<div class="tooltipMidBorders" style="height:<%= iTooltipSizeY -50 %>px; background-color:white;">
<div id="tooltipContent">
</div>
</div>
<%# include file="/include/new/detailpage/tooltipBlauUnten.jsp" %>
</div>
<div class="tooltip_shadow" id="tooltip_shadow">
</div>
<% System.out.println("Zeit in ms: " + (System.currentTimeMillis() - time) + " : ArticleBar"); %>
<%
}
%>
This is the jsp-include that displays the bar.
Sorry for the german comments, i didnt change them. Hope youll understand it either.
Now here comes the JS-File:
var fTime = 0.05;
var fOffsetAim = 0;
var iElementXPos = 0;
var iElementYPos = 0;
var mouseOverID = "";
var lockedElementID = "";
// Tooltip Bounds
var fTooltipPosX = 0.0;
var fTooltipPosXAim = 0.0;
var fTooltipPosY = 0.0;
var fTooltipPosYAim = 0.0;
var fTooltipSizeX = 0.0;
var fTooltipSizeXAim = 0.0;
var fTooltipSizeY = 0.0;
var fTooltipSizeYAim = 0.0;
var fTooltipOpacity = 0.0;
var fTooltipOpacityAim = 0.0;
var sTooltipDisplay = 'hidden';
var bTooltipVisible = false;
var XPosDone = false;
var YPosDone = false;
var XSizeDone = false;
var YSizeDone = false;
var OpacityDone = false;
var iLevelOfDetail = -1;
var sTooltipData = "";
function slideLeft()
{
iOffsetFactor--;
if(iOffsetFactor < -4)
iOffsetFactor = -4;
fOffsetAim = iOffsetFactor * iCellWidth;
move();
}
function slideRight()
{
iOffsetFactor++;
if(iOffsetFactor >= iLoaded - 5)
iOffsetFactor = iLoaded - 5;
fOffsetAim = iOffsetFactor * iCellWidth;
move();
}
function move()
{
var fDist = fOffsetAim - fOffset;
fOffset += fDist * fTime * iFloatingSpeed;
setOffset();
if(Math.abs(fDist) < 1)
{
fOffset = fOffsetAim;
}
else
{
window.setTimeout("move()", fTime);
}
}
function setOffset()
{
var floater = document.getElementById('main_floater');
floater.style.marginLeft = "" + -fOffset + "px" ;
}
function mouseInElement(articleID)
{
if(articleID != mouseOverID)
{
mouseOverID = articleID;
var element = document.getElementById("bar_" + articleID);
element.style.border = "2px solid #B0B0B0";
var rect = element.getBoundingClientRect();
iElementXPos = rect.left;
iElementYPos = rect.top;
var foo = 'stillMouseOver(\'' + articleID + '\')';
window.setTimeout(foo, iTooltipDelay)
}
}
function mouseOutElement(articleID)
{
iElementXPos = 0;
iElementYPos = 0;
var element = document.getElementById("bar_" + articleID);
element.style.border = "1px solid #B3B3B3";
mouseOverID = "";
window.setTimeout('stillMouseOut(\'' + articleID + '\')', iTooltipDelay)
}
function checkMouseOut()
{
if(mouseOverID.length != 0 || lockedElementID.length != 0)
{
if(isOut() && isOutTooltip())
{
if(mouseOverID.length != 0)
mouseOutElement(mouseOverID);
else if(lockedElementID.length != 0)
mouseOutElement(lockedElementID);
}
}
}
function isOut()
{
if(g_iMousePosX < iElementXPos - 5)
return true;
if(iElementXPos + iCellSizeX + 5 < g_iMousePosX)
return true;
if(g_iMousePosY < iElementYPos - 5)
return true;
if(iElementYPos + iCellSizeY + 5 < g_iMousePosY)
return true;
return false;
}
function isOutTooltip()
{
if(g_iMousePosX < fTooltipPosX - 5)
return true;
if(fTooltipPosX + fTooltipSizeX + 5 < g_iMousePosX)
return true;
if(g_iMousePosY < fTooltipPosY - 5)
return true;
if(fTooltipPosY + fTooltipSizeY + 40 < g_iMousePosY)
return true;
return false;
}
function getXPos(element)
{
return (element.offsetParent) ? element.offsetTop+abstop(element.offsetParent) : element.offsetTop;
/*
var x = element.offsetLeft;
if (!element.offsetParent) return x;
else return (x + getXPos(element.offsetParent));
*/
}
function getYPos (element)
{
return (element.offsetParent) ? element.offsetLeft+abstop(element.offsetParent) : element.offsetLeft;
/*
var y = element.offsetTop;
if (!element.offsetParent) return y;
else return (y + getYPos(element.offsetParent));
*/
}
function stillMouseOver(articleID)
{
if(articleID == mouseOverID)
{
if(bTooltipVisible)
{
if(LOD() < 4)
fTooltipPosXAim = iElementXPos + iCellSizeX/2 - iTooltipSizeX/2;
else
fTooltipPosX = fTooltipPosXAim = iElementXPos + iCellSizeX/2 - iTooltipSizeX/2;
XPosDone = false;
lockedElementID = articleID;
getArticleData(lockedElementID);
moveTooltip();
}
else
{
openTooltip(articleID);
}
}
}
function stillMouseOut(articleID)
{
if(bTooltipVisible)
{
if(isOut() && isOutTooltip())
{
closeTooltip();
}
}
}
function openTooltip(articleID)
{
lockedElementID = mouseOverID;
getArticleData(lockedElementID);
bTooltipVisible = true;
var tooltip = document.getElementById('tooltip');
var tooltip_shadow = document.getElementById('tooltip_shadow');
tooltip.style.display = 'block';
if(LOD() < 2)
tooltip_shadow.style.display = 'block';
fTooltipPosX = fTooltipPosXAim = iElementXPos + iCellSizeX/2 - iTooltipSizeX/2; // Set X-Position
if(LOD() < 4) // with animation
{
fTooltipPosY = iElementYPos + iCellSizeY + 50; // Y-Position
fTooltipPosYAim = iElementYPos + iCellSizeY + 10; // Y-Position Aim
fTooltipSizeX = fTooltipSizeXAim = iTooltipSizeX; // X-Size
fTooltipSizeY = 0; // Y-Size
fTooltipSizeYAim = iTooltipSizeY; // Y-Size Aim
}
else // without animation
{
fTooltipPosY = fTooltipPosYAim = iElementYPos + iCellSizeY + 10; // Set Y-Pos Hard
fTooltipSizeX = fTooltipSizeXAim = iTooltipSizeX; // X-Size
fTooltipSizeY = fTooltipSizeYAim = iTooltipSizeY; // Set Y-Size Hard
}
if(LOD() < 3) // with fading
{
fTooltipOpacity = 0; // Set Opacity
fTooltipOpacityAim = 1.0;
}
else
{
fTooltipOpacity = fTooltipOpacityAim = 1.0;
}
setAnimationDone(false);
moveTooltip(); // start animation or just set the values
}
function closeTooltip()
{
lockedElementID = "";
bTooltipVisible = false;
if(LOD() == 4)
{
tooltip.style.display = 'none';
}
else
{
if(LOD() < 4)
{
fTooltipSizeYAim = fTooltipSizeY / 2;
fTooltipPosYAim = fTooltipPosY + 50;
}
if(LOD() < 3)
{
fTooltipOpacityAim = 0.0;
}
moveTooltip();
}
}
function moveTooltip()
{
var tooltip = document.getElementById('tooltip');
var tooltip_shadow = document.getElementById('tooltip_shadow');
if(!XPosDone)
{
var XPosDist = fTooltipPosXAim - fTooltipPosX;
if(Math.abs(XPosDist) > 1)
{
fTooltipPosX += XPosDist * fTime * iTooltipMoveFactor;
}
else
{
fTooltipPosX = fTooltipPosXAim;
XPosDone = true;
}
tooltip.style.left = fTooltipPosX + "px";
tooltip_shadow.style.left = (fTooltipPosX - iShadowOffset) + "px";
}
if(!YPosDone)
{
var YPosDist = fTooltipPosYAim - fTooltipPosY;
if(Math.abs(YPosDist) > 1)
{
fTooltipPosY += YPosDist * fTime * iTooltipMoveFactor;
}
else
{
fTooltipPosY = fTooltipPosYAim;
YPosDone = true;
}
tooltip.style.top = fTooltipPosY + "px";
tooltip_shadow.style.top = (fTooltipPosY + iShadowOffset) + "px";
}
if(!XSizeDone)
{
var XSizeDist = fTooltipSizeXAim - fTooltipSizeX;
if(Math.abs(XSizeDist) > 1)
{
fTooltipSizeX += XSizeDist * fTime * iTooltipScaleFactor;
}
else
{
fTooltipSizeX = fTooltipSizeXAim;
XSizeDone = true;
}
tooltip.style.width = fTooltipSizeX + "px";
tooltip_shadow.style.width = fTooltipSizeX + "px";
}
if(!YSizeDone)
{
var YSizeDist = fTooltipSizeYAim - fTooltipSizeY;
if(Math.abs(YSizeDist) > 1)
{
fTooltipSizeY += YSizeDist * fTime * iTooltipScaleFactor;
}
else
{
fTooltipSizeY = fTooltipSizeYAim;
YSizeDone = true;
}
tooltip.style.height = fTooltipSizeY + "px";
tooltip_shadow.style.height = (fTooltipSizeY - 20) + "px";
}
if(!OpacityDone)
{
var OpacityDist = fTooltipOpacityAim - fTooltipOpacity;
if(Math.abs(OpacityDist) > 0.01)
{
fTooltipOpacity += OpacityDist * fTime * iTooltipFadeFactor;
}
else
{
fTooltipOpacity = fTooltipOpacityAim;
OpacityDone = true;
}
tooltip.style.opacity = fTooltipOpacity;
tooltip_shadow.style.opacity = fTooltipOpacity * 0.25;
}
if(XPosDone && YPosDone && XSizeDone && YSizeDone && OpacityDone)
{
// animation done -> no callback
if(bTooltipVisible)
{
setTooltipContent(sTooltipData);
}
else
{
tooltip.style.display = 'none';
tooltip_shadow.style.display = 'none';
removeTooltipContent();
}
setAnimationDone(false);
}
else
{
window.setTimeout('moveTooltip()', fTime);
}
}
function setAnimationDone(bAnimation)
{
XPosDone = bAnimation;
YPosDone = bAnimation;
XSizeDone = bAnimation;
YSizeDone = bAnimation;
OpacityDone = bAnimation;
}
function getArticleData(articleID)
{
$.post("/ajax_getData",
{id:2, articleID:articleID, von_datum:von_datum, von_zeit:von_zeit, bis_datum:bis_datum, bis_zeit:bis_zeit, stationid:stationID},
function (data)
{
sTooltipData = data;
});
}
function setTooltipContent(data)
{
var aData = data.split('|||');
var sPicturePath = aData[0];
var sArticleDescription = aData[1];
var sArticleID = aData[2];
var sPrice = aData[3];
var sArticleName = aData[4];
var aPrice = sPrice.split('_');
sPrice = aPrice[0];
var sTimePeriode = aPrice[1];
if(sTimePeriode == "")
{
sTimePeriode = von_datum + " - " + bis_datum;
}
var htmlCode = '<div style="width:' + (fTooltipSizeX - 25) + 'px; height:' + (fTooltipSizeY-50) + 'px; margin-left:10px; margin-right:10px;">' +
'<div style="height:' + (fTooltipSizeY-50)/3 + 'px;">' +
'<div style="width:' + (fTooltipSizeX-25) /2 + 'px; height:' + (fTooltipSizeY-50)/3 + 'px; float:left">' +
'<div style="width:105px; height:70px; margin-left:auto; margin-right:auto;">' +
'<img src="' + sPicturePath + '">' +
'</div>' +
'</div>' +
'<div style="width:' + (fTooltipSizeX-25) /2 + 'px; height:' + (fTooltipSizeY-50)/3 + 'px; float:left">' +
'<b>PREIS</b><br>' +
sPrice +
'</div>' +
'</div>' +
'<div style="height:' + (fTooltipSizeY-50)*2/3 + 'px;">' +
'<b>' +
sArticleName +
'</b>' +
'<br><br>' +
'<div style="overflow-y:scroll; width:100%; height:65%; border:1px solid black;">' +
'<p style="width:98%; word-wrap:break-word; padding-left:3px; padding-right:3px;">' + sArticleDescription + '</p>' +
'</div>' +
'</div>' +
'</div>';
var content = document.getElementById('tooltipContent');
content.innerHTML = htmlCode;
}
function removeTooltipContent()
{
var content = document.getElementById('tooltipContent');
content.innerHTML = "";
}
function LOD()
{
/**
* LevelOfDetail:
* 1: all animations, fade-effects and Shadows
* 2: animations and fade-effects
* 3: animations
* 4: just the tooltip
*/
if(iLevelOfDetail == -1)
{
var version = $.browser.version;
version = version.substring(0, version.indexOf('.'), version.indexOf('.') + 1);
version = isNaN(version) ? 1 : version * 1;
if($.browser.safari)
{
iLevelOfDetail = 1;
}
else if($.browser.msie)
{
if($.browser.version >= 8) iLevelOfDetail = 1;
else if($.browser.version >= 7) iLevelOfDetail = 2;
else if($.browser.version >= 6) iLevelOfDetail = 3;
}
else if($.browser.mozilla)
{
if($.browser.version >= 4) iLevelOfDetail = 1;
else if($.browser.version >= 2) iLevelOfDetail = 2;
}
else if($.browser.opera)
{
iLevelOfDetail = 1;
}
else
{
iLevelOfDetail = 4;
}
}
return iLevelOfDetail;
}
The relevant part might be in the JS in mouseInElement(articleID);
The position of the Icon is calculated incorrectly!
Again thank you very much for your help!

offsetTop has lots of issues, particularly when scrolling is involved. Maybe try getBoundingClientRect() instead?

Related

Javascript stopwatch want the clock element to be a div not an input

So I have the following code, As you can see in the HTML I have a div with id=clock and an input element also with id=clock, basically if i remove the div or comment it out, the input element works fine, on the html page the clock in the input element will display the time, I would prefer it to use the div element for styling purposes; however, if i comment out the input element and use the div it does not count up, I think I understand why but I cant seem to fix it. Can someone help explain how I can do this using the following code?
var flagclock = 0;
var flagstop = 0;
var stoptime = 0;
var splitcounter = 0;
var currenttime;
var splitdate = '';
var output;
var clock;
// Start-Stop Function
function startstop() {
var startstop = document.getElementById('startstopbutton');
var startdate = new Date();
var starttime = startdate.getTime();
if (flagclock == 0) {
startstop.value = 'Stop';
flagclock = 1;
counter(starttime);
} else {
startstop.value = 'Start';
flagclock = 0;
flagstop = 1;
splitdate = '';
}
}
//Increment function
function counter(starttime) {
output = document.getElementById('output');
clock = document.getElementById('clock');
currenttime = new Date();
var timediff = currenttime.getTime() - starttime;
if (flagstop == 1) {
timediff = timediff + stoptime
}
if (flagclock == 1) {
clock.value = formattime(timediff, '');
refresh = setTimeout('counter(' + starttime + ');', 10);
} else {
window.clearTimeout(refresh);
stoptime = timediff;
}
}
function formattime(rawtime, roundtype) {
if (roundtype == 'round') {
var ds = Math.round(rawtime / 100) + '';
} else {
var ds = Math.floor(rawtime / 100) + '';
}
var sec = Math.floor(rawtime / 1000);
var min = Math.floor(rawtime / 60000);
ds = ds.charAt(ds.length - 1);
if (min >= 60) {
startstop();
}
sec = sec - 60 * min + '';
if (sec.charAt(sec.length - 2) != '') {
sec = sec.charAt(sec.length - 2) + sec.charAt(sec.length - 1);
} else {
sec = 0 + sec.charAt(sec.length - 1);
}
min = min + '';
if (min.charAt(min.length - 2) != '') {
min = min.charAt(min.length - 2) + min.charAt(min.length - 1);
} else {
min = 0 + min.charAt(min.length - 1);
}
return min + ':' + sec + ':' + ds;
}
// reset function
function resetclock() {
flagstop = 0;
stoptime = 0;
splitdate = '';
window.clearTimeout(refresh);
output.value = '';
splitcounter = 0;
if (flagclock == 1) {
var resetdate = new Date();
var resettime = resetdate.getTime();
counter(resettime);
} else {
clock.value = "00:00:0";
}
}
//Split function
function splittime() {
if (flagclock == 1) {
if (splitdate != '') {
var splitold = splitdate.split(':');
var splitnow = clock.value.split(':');
var numbers = new Array();
var i = 0
for (i; i < splitold.length; i++) {
numbers[i] = new Array();
numbers[i][0] = splitold[i] * 1;
numbers[i][1] = splitnow[i] * 1;
}
if (numbers[1][1] < numbers[1][0]) {
numbers[1][1] += 60;
numbers[0][1] -= 1;
}
if (numbers[2][1] < numbers[2][0]) {
numbers[2][1] += 10;
numbers[1][1] -= 1;
}
var mzeros = (numbers[0][1] - numbers[0][0]) < 10 ? '0' : '';
var szeros = (numbers[1][1] - numbers[1][0]) < 10 ? '0' : '';
output.value += '\t+' + mzeros + (numbers[0][1] - numbers[0][0]) + ':' + szeros + (numbers[1][1] - numbers[1][0]) + ':' + (numbers[2][1] - numbers[2][0]) + '\n';
}
splitdate = clock.value;
output.value += (++splitcounter) + '. ' + clock.value + '\n';
}
}
<input id="startstopbutton" class="buttonZ" style="width: 120px;" type="button" name="btn" id='btn' value="Start" onclick="startstop()" ;>
<input id="resetbutton" class="buttonZ" style="width: 120px;" type="button" name="btnRst1" id='btnRst1' value="Reset" onclick="resetclock()" ;>
<div id="clock" class="timerClock">00:00:00</div><br>
<!-- Clock 2 -->
<input id="clock" class="timerClock" type="text" value="00:00:0" style="text-align: center;" readonly=""><br>
<!-- Split Button -->
<input id="splitbutton" class="buttonZ" style="width: 120px; margin-right: 170px" type="button" value="Split Time" onclick="splittime();">
<!-- output for split times -->
<textarea id="output" spellcheck="false"></textarea>
You are using clock.value to set the contents of the <input> element. This will not work for <div> elements; you will need to use innerHTML instead:
clock = document.getElementById('clock'); //div#clock
// ...
clock.innerHTML = formattime(timediff, '');
have a div with id=clock and an input element also with id=clock,
This is bad. ID have to be UNIQUE. This is why when you have both present ( with same id ) the counter doesn't work. It selects just the first element with id clock which is the div.
It doesn't select the input. As you can see getElementById is singular. If you want to select both of them, add a common class and select that with getElementsByClassName(className) ( notice the plural Elements compared to Element from the ID selector ) or querySelectorAll(className) and loop through them.
I added clock-div as the id on the div
Also. div element does not have a value attribute ( unlike input ). To get or edit/manipulate the text inside a div element you should use div.innerText instead of div.value. As a side note, div can have HTML inside it (input can't) . You can access it with div.innerHTML
So basically you need to change the id of the div ( if you also want to keep the input ) and change clock.value to clock.innerText everywhere.
Another option would be to keep both input and div. And assign the value of the input to the div.innerText.
var flagclock = 0;
var flagstop = 0;
var stoptime = 0;
var splitcounter = 0;
var currenttime;
var splitdate = '';
var output;
var clock;
// Start-Stop Function
function startstop() {
var startstop = document.getElementById('startstopbutton');
var startdate = new Date();
var starttime = startdate.getTime();
if (flagclock == 0) {
startstop.value = 'Stop';
flagclock = 1;
counter(starttime);
} else {
startstop.value = 'Start';
flagclock = 0;
flagstop = 1;
splitdate = '';
}
}
//Increment function
function counter(starttime) {
output = document.getElementById('output');
// change here id
clock = document.getElementById('clock-div');
currenttime = new Date();
var timediff = currenttime.getTime() - starttime;
if (flagstop == 1) {
timediff = timediff + stoptime
}
if (flagclock == 1) {
clock.innerText = formattime(timediff, '');
refresh = setTimeout('counter(' + starttime + ');', 10);
} else {
window.clearTimeout(refresh);
stoptime = timediff;
}
}
function formattime(rawtime, roundtype) {
if (roundtype == 'round') {
var ds = Math.round(rawtime / 100) + '';
} else {
var ds = Math.floor(rawtime / 100) + '';
}
var sec = Math.floor(rawtime / 1000);
var min = Math.floor(rawtime / 60000);
ds = ds.charAt(ds.length - 1);
if (min >= 60) {
startstop();
}
sec = sec - 60 * min + '';
if (sec.charAt(sec.length - 2) != '') {
sec = sec.charAt(sec.length - 2) + sec.charAt(sec.length - 1);
} else {
sec = 0 + sec.charAt(sec.length - 1);
}
min = min + '';
if (min.charAt(min.length - 2) != '') {
min = min.charAt(min.length - 2) + min.charAt(min.length - 1);
} else {
min = 0 + min.charAt(min.length - 1);
}
return min + ':' + sec + ':' + ds;
}
// reset function
function resetclock() {
flagstop = 0;
stoptime = 0;
splitdate = '';
window.clearTimeout(refresh);
output.value = '';
splitcounter = 0;
if (flagclock == 1) {
var resetdate = new Date();
var resettime = resetdate.getTime();
counter(resettime);
} else {
clock.innerText = "00:00:0";
}
}
//Split function
function splittime() {
if (flagclock == 1) {
if (splitdate != '') {
var splitold = splitdate.split(':');
var splitnow = clock.value.split(':');
var numbers = new Array();
var i = 0
for (i; i < splitold.length; i++) {
numbers[i] = new Array();
numbers[i][0] = splitold[i] * 1;
numbers[i][1] = splitnow[i] * 1;
}
if (numbers[1][1] < numbers[1][0]) {
numbers[1][1] += 60;
numbers[0][1] -= 1;
}
if (numbers[2][1] < numbers[2][0]) {
numbers[2][1] += 10;
numbers[1][1] -= 1;
}
var mzeros = (numbers[0][1] - numbers[0][0]) < 10 ? '0' : '';
var szeros = (numbers[1][1] - numbers[1][0]) < 10 ? '0' : '';
output.value += '\t+' + mzeros + (numbers[0][1] - numbers[0][0]) + ':' + szeros + (numbers[1][1] - numbers[1][0]) + ':' + (numbers[2][1] - numbers[2][0]) + '\n';
}
splitdate = clock.innerText;
output.innerText += (++splitcounter) + '. ' + clock.value + '\n';
}
}
<input id="startstopbutton" class="buttonZ" style="width: 120px;" type="button" name="btn" id='btn' value="Start" onclick="startstop()" ;>
<input id="resetbutton" class="buttonZ" style="width: 120px;" type="button" name="btnRst1" id='btnRst1' value="Reset" onclick="resetclock()" ;>
<div id="clock-div" class="timerClock">00:00:00</div><br>
<!-- Clock 2 -->
<input id="clock" class="timerClock" type="text" value="00:00:0" style="text-align: center;" readonly=""><br>
<!-- Split Button -->
<input id="splitbutton" class="buttonZ" style="width: 120px; margin-right: 170px" type="button" value="Split Time" onclick="splittime();">
<!-- output for split times -->
<textarea id="output" spellcheck="false"></textarea>

change image source on click event and add pixel

I am trying to change one image source with id using javascript, also I would like to add/remove width to the picture depending on whether we click on + or - button.
var changeimg = function() {
var sun_to_eclipse = document.getElementById("sun");
if (sun_to_eclipse.src == "images/soleil.jpg") {
sun_to_eclipse.src = "images/eclipse.jpg";
} else {
sun_to_eclipse.src = "images/soleil.jpg";
}
}
var addpx = function() {
var sun_to_eclipse = document.getElementById("sun");
if (sun_to_eclipse.width <= "500") {
sun_to_eclipse.style.width = sun_to_eclipse.style.width + "20px"
}
}
var removepx = function() {
var sun_to_eclipse = document.getElementById("sun");
if (sun_to_eclipse.width >= "250") {
sun_to_eclipse.style.width = sun_to_eclipse.style.width - "20px"
}
}
var setupListeners = function() {
var plus = document.getElementById("plus");
var minus = document.getElementById("minus");
var sun_to_eclipse = document.getElementById("sun");
sun_to_eclipse.addEventListener("click", changeimg);
plus.addEventListener("click", addpx);
minus.addEventListener("click", removepx);
}
window.addEventListener("load", setupListeners);
<div id="doc">
<div id="buttons">
<button id="plus">+</button>
<button id="minus">-</button>
</div>
<img id="sun" src="https://pbs.twimg.com/profile_images/641353910561566720/VSxsyxs7_400x400.jpg" alt="sunny" />
</div>
Any idea what's wrong?
To Fetch the Width use .clientWidth instead of .style.width
So for addpx use sun_to_eclipse.clientWidth + 20 + "px"; and
for minus use sun_to_eclipse.clientWidth - 20 + "px";
var changeimg = function() {
var sun_to_eclipse = document.getElementById("sun");
if (sun_to_eclipse.src == "https://camo.githubusercontent.com/e9c5fe6cb160f55f564723b8c1679170c74f5e53/687474703a2f2f73392e706f7374696d672e6f72672f7a336e707077797a332f73686565705f333530782e6a7067") {
sun_to_eclipse.src = "http://www.ptahai.com/wp-content/uploads/2016/06/Best-Reverse-Image-Search-Engines-Apps-And-Its-Uses-2016.jpg";
} else {
sun_to_eclipse.src = "https://camo.githubusercontent.com/e9c5fe6cb160f55f564723b8c1679170c74f5e53/687474703a2f2f73392e706f7374696d672e6f72672f7a336e707077797a332f73686565705f333530782e6a7067";
}
}
var addpx = function() {
var sun_to_eclipse = document.getElementById("sun");
if (sun_to_eclipse.clientWidth <= "500") {
sun_to_eclipse.style.width = sun_to_eclipse.clientWidth + 20 + "px";
}
}
var removepx = function() {
var sun_to_eclipse = document.getElementById("sun");
if (sun_to_eclipse.clientWidth >= "250") {
sun_to_eclipse.style.width = sun_to_eclipse.clientWidth - 20 + "px";
}
}
var setupListeners = function() {
var plus = document.getElementById("plus");
var minus = document.getElementById("minus");
var sun_to_eclipse = document.getElementById("sun");
sun_to_eclipse.addEventListener("click", changeimg);
plus.addEventListener("click", addpx);
minus.addEventListener("click", removepx);
}
window.addEventListener("click", setupListeners);
#sun {
width: 300px;
}
<div id="doc">
<div id="buttons">
<button id="plus">+</button>
<button id="minus">-</button>
</div>
<img id="sun" src="https://cdn.pixabay.com/photo/2018/03/11/20/42/mammals-3218028_1280.jpg" alt="sunny" />
</div>
the problem is with your setting widths. style.width will return text with some number plus the unit at the end. use offsetWidth property.
var sun = false;
var changeimg = function() {
var sun_to_eclipse = document.getElementById("sun");
if (sun == false) {
sun_to_eclipse.src = "images/eclipse.jpg";
sun = true;
} else {
sun_to_eclipse.src = "images/soleil.jpg";
sun = false;
}
}
var addpx = function() {
var sun_to_eclipse = document.getElementById("sun");
if (sun_to_eclipse.width <= "500") {
sun_to_eclipse.style.width = sun_to_eclipse.offsetWidth + 20 + "px"
}
}
var removepx = function() {
var sun_to_eclipse = document.getElementById("sun");
if (sun_to_eclipse.width >= "250") {
sun_to_eclipse.style.width = sun_to_eclipse.offsetWidth - 20 + "px"
}
}
var setupListeners = function() {
var plus = document.getElementById("plus");
var minus = document.getElementById("minus");
var sun_to_eclipse = document.getElementById("sun");
sun_to_eclipse.addEventListener("click", changeimg);
plus.addEventListener("click", addpx);
minus.addEventListener("click", removepx);
}
window.addEventListener("load", setupListeners);
<div id="doc">
<div id="buttons">
<button id="plus">+</button>
<button id="minus">-</button>
</div>
<img id="sun" src="https://pbs.twimg.com/profile_images/641353910561566720/VSxsyxs7_400x400.jpg" alt="sunny" />
</div>
IMAGE ONCLICK: its not working properly because img.src contains the full address to the image. eg
document.getElementById("sun").src;
"file:///C:/Users/Abhinav/Desktop/images/soleil.jpg"
you can fix that using a variable
var sun = false;
var changeimg = function() {
var sun_to_eclipse = document.getElementById("sun");
if (sun == false) {
sun_to_eclipse.src = "images/eclipse.jpg";
sun = true;
} else {
sun_to_eclipse.src = "images/soleil.jpg";
sun = false;
}
}
Making use of offsetWidth to achieve this.
var changeimg = function() {
var sun_to_eclipse = document.getElementById("sun");
if (sun_to_eclipse.src == "images/soleil.jpg") {
sun_to_eclipse.src = "images/eclipse.jpg";
} else {
sun_to_eclipse.src = "images/soleil.jpg";
}
}
var addpx = function() {
var sun_to_eclipse = document.getElementById("sun");
if (sun_to_eclipse.width <= "500") {
sun_to_eclipse.style.width = sun_to_eclipse.offsetWidth + 20 + "px"
}
}
var removepx = function() {
var sun_to_eclipse = document.getElementById("sun");
if (sun_to_eclipse.width >= "250") {
sun_to_eclipse.style.width = sun_to_eclipse.offsetWidth - 20 + "px"
}
}
var setupListeners = function() {
var plus = document.getElementById("plus");
var minus = document.getElementById("minus");
var sun_to_eclipse = document.getElementById("sun");
sun_to_eclipse.addEventListener("click", changeimg);
plus.addEventListener("click", addpx);
minus.addEventListener("click", removepx);
}
window.addEventListener("load", setupListeners);
<div id="doc">
<div id="buttons">
<button id="plus" onClick =>+</button>
<button id="minus">-</button>
</div>
<img id="sun" src="https://pbs.twimg.com/profile_images/641353910561566720/VSxsyxs7_400x400.jpg" alt="sunny" />
</div>

Button does nothing when pressed

I've been working on my own project for a little bit, and I'm currently working on adding another button in. Now I've set it up pretty similar to the other ones, but it isn't working when I press it. For my code, the firstx2, secondx2, and first building buttons all work fine, But when you try and click on the second building button, it doesn't do anything. I probably made a small typo or missed a line, but I can't seem to find it anywhere. To get to the second building button, you have to have already clicked on both multipliers and the first building. Thanks for your help!
<!DOCTYPE html>
<html>
<body>
<p>Click to get started!</p>
<button onclick="addPoints()">Add points</button>
<button id="btn_multiply" onclick="firstx2()" style="display:none;">x2 Multiplier. Cost: 100</button>
<button id="firstbuild" onclick="build1()" style="display:none;">Building 1. Cost x</button>
<button id="multiply2" onclick="secondx2()" style="display:none;">x2 Multiplier. Cost: 1000</button>
<button id="secondbuild" onlcick="build2()" style="display:none;">Building 2. Cost x</button>
<script>
var points = 10099;
var pointMulti = 1;
var buyupgrade = 0;
var b1cost = 200;
var b1count = 0;
var b2cost = 1000;
var b2count = 0;
var currentpoints = setInterval(pointupdate, 500);
function addPoints() {
points += pointMulti;
var pointsArea = document.getElementById("pointdisplay");
pointsArea.innerHTML = "You have " + Math.round(points) + " points!";
if(points >= 100 && buyupgrade == 0) {
var multiply_button = document.getElementById("btn_multiply");
multiply_button.style.display = "inline";
}
}
function firstx2() {
if (buyupgrade == 0) {
pointMulti *= 2;
buyupgrade++;
points -= 100;
var multiplierArea = document.getElementById("multidisplay");
multiplierArea.innerHTML = "Your multiplier is: " + pointMulti;
var multiply_button = document.getElementById("btn_multiply");
multiply_button.style.display = "none";
if (buyupgrade == 1) {
var firstbuild = document.getElementById("firstbuild");
firstbuild.style.display = "inline";
firstbuild.innerText = "Building 1. Cost " + b1cost;
var show2ndx2 = document.getElementById("secondx2");
multiply2.style.display = "inline";
}
}
}
function pointupdate() {
document.getElementById("pointdisplay").innerHTML = "You have " + Math.round(points) + " points!";
}
function build1() {
if (points >= b1cost) {
points -= b1cost;
b1count++;
b1cost *= 1.10;
document.getElementById("b1").innerHTML = "You have " + b1count + " of building 1!"
firstbuild.innerText = "Building 1. Cost " + Math.round(b1cost);
var build1add = setInterval(build1points, 1000);
var secondbuild = document.getElementById("secondbuild");
secondbuild.style.display = "inline";
secondbuild.innerText = "Building 2. Cost " + b2cost;
}
}
function build2() {
if (points >= b2cost) {
points -= b2cost;
b2count++;
b2cost *= 1.10;
document.getElementById("b2").innerHTML = "You have " + b2count + " of building 2!"
secondbuild.innerText = "Building 2. Cost " + Math.round(b2cost);
var build2add = setInterval(build2points, 1000);
}
}
function build1points() {
points += 1;
}
function build2points() {
points += 4;
}
function secondx2() {
if (buyupgrade == 1 && points >= 1000) {
pointMulti *= 2;
points -= 1000;
document.getElementById("multidisplay").innerHTML = "Your multiplier is: " + pointMulti;
multiply2.style.display = "none";
}
}
</script>
<p id="pointdisplay"></p>
<p id="multidisplay"></p>
<p id="b1"></p>
<p id="b2"></p>
</body>
</html>
it should be onclick not onlcick in <button id="secondbuild" onlcick="build2()" style="display:none;">Building 2. Cost x</button>
<!DOCTYPE html>
<html>
<body>
<p>Click to get started!</p>
<button onclick="addPoints()">Add points</button>
<button id="btn_multiply" onclick="firstx2()" style="display:none;">x2 Multiplier. Cost: 100</button>
<button id="firstbuild" onclick="build1()" style="display:none;">Building 1. Cost x</button>
<button id="multiply2" onclick="secondx2()" style="display:none;">x2 Multiplier. Cost: 1000</button>
<button id="secondbuild" onclick="build2()" style="display:none;">Building 2. Cost x</button>
<script>
var points = 10099;
var pointMulti = 1;
var buyupgrade = 0;
var b1cost = 200;
var b1count = 0;
var b2cost = 1000;
var b2count = 0;
var currentpoints = setInterval(pointupdate, 500);
function addPoints() {
points += pointMulti;
var pointsArea = document.getElementById("pointdisplay");
pointsArea.innerHTML = "You have " + Math.round(points) + " points!";
if(points >= 100 && buyupgrade == 0) {
var multiply_button = document.getElementById("btn_multiply");
multiply_button.style.display = "inline";
}
}
function firstx2() {
if (buyupgrade == 0) {
pointMulti *= 2;
buyupgrade++;
points -= 100;
var multiplierArea = document.getElementById("multidisplay");
multiplierArea.innerHTML = "Your multiplier is: " + pointMulti;
var multiply_button = document.getElementById("btn_multiply");
multiply_button.style.display = "none";
if (buyupgrade == 1) {
var firstbuild = document.getElementById("firstbuild");
firstbuild.style.display = "inline";
firstbuild.innerText = "Building 1. Cost " + b1cost;
var show2ndx2 = document.getElementById("secondx2");
multiply2.style.display = "inline";
}
}
}
function pointupdate() {
document.getElementById("pointdisplay").innerHTML = "You have " + Math.round(points) + " points!";
}
function build1() {
if (points >= b1cost) {
points -= b1cost;
b1count++;
b1cost *= 1.10;
document.getElementById("b1").innerHTML = "You have " + b1count + " of building 1!"
firstbuild.innerText = "Building 1. Cost " + Math.round(b1cost);
var build1add = setInterval(build1points, 1000);
var secondbuild = document.getElementById("secondbuild");
secondbuild.style.display = "inline";
secondbuild.innerText = "Building 2. Cost " + b2cost;
}
}
function build2() {
if (points >= b2cost) {
points -= b2cost;
b2count++;
b2cost *= 1.10;
document.getElementById("b2").innerHTML = "You have " + b2count + " of building 2!"
secondbuild.innerText = "Building 2. Cost " + Math.round(b2cost);
var build2add = setInterval(build2points, 1000);
}
}
function build1points() {
points += 1;
}
function build2points() {
points += 4;
}
function secondx2() {
if (buyupgrade == 1 && points >= 1000) {
pointMulti *= 2;
points -= 1000;
document.getElementById("multidisplay").innerHTML = "Your multiplier is: " + pointMulti;
multiply2.style.display = "none";
}
}
</script>
<p id="pointdisplay"></p>
<p id="multidisplay"></p>
<p id="b1"></p>
<p id="b2"></p>
</body>
</html>
I think you should check your button(secondbuild)
the keyword onclick is wrong
Spelling Mistake. onclick not oncilck.
<button id="secondbuild" onlcick="build2()" style="display:none;">Building 2. Cost x</button> <script>

Adding variables and output to html

I am using Bootstrap buttons set with data-toggle="button" that toggles the active class on the button so I figured I would use hasClass to update the variables. As you can tell I am new to javascript/jquery. I then push the variables out to html and want it to update based on the buttons being selected or de-selected, I just can't quite what method I should use. Is AJAX necessary?
Snippet:
var priceA = 300;
var priceB = 400;
var imgBtn = 0;
var mscBtn = 0;
var outputPrice = priceA + imgBtn + mscBtn;
$('#showPrice').html(outputPrice);
$('.priceTable button').click(function() {
$(this).toggleClass('active');
if ($(this).hasClass('active')) {
imgBtn = 25;
} else {
imgBtn = 0;
}
$('#showPrice').html(outputPrice);
});
.active {background-color:red;}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h2 id="showPrice"></h2>
<table class="priceTable">
<tr>
<td>
<button type="button" class="btn btn-lg priceButton imageBtn" id="imageBtn">Image Gallery</button>
<button type="button" class="btn btn-lg priceButton" id="musicBtn" role="button" aria-pressed="false">Music Player</button>
</td>
</tr>
</table>
Use jQuery's click() and hasClass() to check and trigger your variable updates
Something like this:
$('#imageBtn').click(function(){
if ($(this).hasClass("active")){
imgBtn = 25;
}
});
Problem solved! I am sure there is a much easier way but this is what I was able to figure out and it works. Any improvement suggestions would be appreciated as I use them as a learning experience.
Here is jquery that includes additional buttons. When a button is selected, it adds that to the price range of priceA and priceB. When deselected, it reduces it again from the price range.
var priceA = 300;
var priceB = 400;
var imgBtn = 0;
var mscBtn = 0;
var vidBtn = 0;
var strBtn = 0;
var blgBtn = 0;
var othBtn = 0;
$('#showPrice, #showPrice2').html('$' + priceA + ' - ' + '$' + priceB);
$('.priceTable button').click(function(){
$(this).toggleClass('active');
if($('.imageBtn').hasClass('active')) {
imgBtn = 25;
} else {imgBtn = 0;}
if($('.musicBtn').hasClass('active')) {
mscBtn = 50;
} else {mscBtn = 0;}
if($('.videoBtn').hasClass('active')) {
vidBtn = 50;
} else {vidBtn = 0;}
if($('.storeBtn').hasClass('active')) {
strBtn = 75;
} else {strBtn = 0;}
if($('.blogBtn').hasClass('active')) {
blgBtn = 75;
} else {blgBtn = 0;}
if($('.otherBtn').hasClass('active')) {
othBtn = 75;
} else {othBtn = 0;}
});
function calcPrice (){
var outputPriceA = priceA + imgBtn + mscBtn + vidBtn + strBtn + blgBtn + othBtn;
var outputPriceB = priceB + imgBtn + mscBtn + vidBtn + strBtn + blgBtn + othBtn;
$('#showPrice, #showPrice2').html('$' + outputPriceA + ' - ' + '$' + outputPriceB);
};

Textarea. On Shift + Enter, apend html line break.How?

I found a textarea plugin on the internet and modified it a bit to suite my needs. It works the way I want to except for one minor detail.
As you can see, it expands and collapses the textarea as I type or delete characters.
Iif I press enter, it generates a comment div containing the contents I've typed in the textarea.
My question is, **how to I append a <br /> to my new_comment variable each time a user presses Shift + Enter?
/*!
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <jevin9#gmail.com> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return. Jevin O. Sewaruth
* ----------------------------------------------------------------------------
*
* Autogrow Textarea Plugin Version v2.0
* http://www.technoreply.com/autogrow-textarea-plugin-version-2-0
*
* Date: March 13, 2011
*/
jQuery.fn.autoGrow = function(){
return this.each(function(){
// Variables
var colsDefault = this.cols;
var rowsDefault = this.rows;
//Functions
var grow = function() {
growByRef(this);
}
var onFocus = function(obj) {
if ($(this).val() != 'Write a comment...') {
return;
} else {
$(this).parents(".comment_new_container").children("img").show();
//$(this).height(34);
$(this).width(745);
$(this).val('');
}
}
var onBlur = function(obj) {
if ($(this).val().length == 0) {
$(this).parents(".comment_new_container").children("img").hide();
//$(this).height(16);
$(this).width(795);
$(this).val('Write a comment...');
}
}
var growByRef = function(obj) {
var new_comment = '';
if (!obj.shiftKey && obj.keyCode == 13) {
obj.preventDefault();
new_comment += '<div class="comment_container" id="001">';
new_comment += '<i class="comment_delete"> </i>';
new_comment += '<img src="img/avatar45.png" />';
new_comment += 'Mickey Mouse';
new_comment += '<br/>';
new_comment += '<div class="comment_content">' + $(this).val(); + '</div> <!-- End comment_content -->';
new_comment += '<div class="comment_timestamp">13 minutes ago</div> <!-- End comment_timestamp -->';
new_comment += '</div> <!-- End comment_container -->';
$(new_comment).insertBefore($(this).parents(".comment_new_container"));
var comment_total = parseInt($('.social_menu_right li a').children('.meta.comment_total').text(), 10) + 1;
$('.social_menu_right li a').children('.meta.comment_total').text(comment_total);
$(this).val('Write a comment...');
$(this).blur();
growByRef(this);
} else {
var linesCount = 0;
var lines = obj.value.split('\n');
for (var i=lines.length-1; i>=0; --i)
{
linesCount += Math.floor((lines[i].length / colsDefault) + 1);
}
if (linesCount >= rowsDefault) {
obj.rows = linesCount + 1;
} else {
obj.rows = rowsDefault;
}
}
}
var characterWidth = function (obj){
var characterWidth = 0;
var temp1 = 0;
var temp2 = 0;
var tempCols = obj.cols;
obj.cols = 1;
temp1 = obj.offsetWidth;
obj.cols = 2;
temp2 = obj.offsetWidth;
characterWidth = temp2 - temp1;
obj.cols = tempCols;
return characterWidth;
}
// Manipulations
$(this).css("width","auto");
$(this).css("height","auto");
$(this).css("overflow","hidden");
this.style.width = ((characterWidth(this) * this.cols) + 6) + "px";
$(this).bind("focus", onFocus);
$(this).bind("blur", onBlur);
$(this).bind("keypress", growByRef);
$(this).bind("keyup", grow);
});
};
Thank you guys.
try adding this at the top of the growByRef function :
if (obj.shiftKey && obj.keyCode == 13) {
$(this).val($(this).val() + "\n");
return;
}
check out these two links here
This case is similar to yours here

Categories

Resources