change image source on click event and add pixel - javascript

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>

Related

html not appending to the carousel on popover

I Am Trying to make a popover with a bootstrap carousel and where the carousel items are to be generated and appended from a script but I get the carousel but I am unable to append the item. I tried hard but I didn't come up with a solution.
the HTML initialized is as below
HTML:
<div class="popup" data-popup="popup-1">
<div class="popup-inner">
<i class="fas fa-bars"></i>
<div class="frame">
<div id='carousel' class='carousel slide' data-bs-ride='carousel'>
<div class='carousel-inner items-slider1'>
</div>
</div>
</div>
</div>
</div>
the script I have tried was
Javascript:
function findallchord(currentchord , currenttype) {
for (let i = 1; i < 10; i++) {
if (Raphael.chord.find(currentchord ,currenttype,i)) {
Raphael.chord("div3", Raphael.chord.find(currentchord , currenttype,i), currentchord +' ' +currenttype).element.setSize(75, 75);
}
}
}
var getChordRoots = function (input) {
if (input.length > 1 && (input.charAt(1) == "b" || input.charAt(1) == "#"))
return input.substr(0, 2);
else
return input.substr(0, 1);
};
$('.popup').on('shown.bs.popover', function () {
$('.carousel-inner').carousel();
});
$('[data-bs-toggle="popover"]').popover({
html: true,
content: function() {
return $('.popup').html();
}}).click(function() {
var oldChord = jQuery(this).text();
var currentchord = getChordRoots(oldChord);
var currenttype = oldChord.substr(currentchord.length);
findallchord(currentchord , currenttype);
var chordsiblings = $('#div3').children().siblings("svg");
for (let i = 1; i < 10; i++) {
if (Raphael.chord.find(currentchord , currenttype,i)) {
var itemid = "chord" + i;
var theDiv = "<div class='carousel-item"+((itemid=="chord1") ? ' active':'')+" ' id='"+currentchord+''+itemid+"'> "+chordsiblings[i-1].outerHTML+" </div>";
$('.items-slider1').append(theDiv);
}
}
});
I have also tried appendTo also as
$(theDiv).appendTo('.items-slider1');
Please Help to solve this
This is the output I get, the appended elements are not in the carousel
Note: I am using Bootstrap 5
Try instantiating the carousel after you've set it up
/*
$('.popup').on('shown.bs.popover', function () {
$('.carousel-inner').carousel();
});
*/
$('[data-bs-toggle="popover"]').popover({
html: true,
content: function() {
return $('.popup').html();
}}).click(function() {
var oldChord = jQuery(this).text();
var currentchord = getChordRoots(oldChord);
var currenttype = oldChord.substr(currentchord.length);
findallchord(currentchord , currenttype);
var chordsiblings = $('#div3').children().siblings("svg");
for (let i = 1; i < 10; i++) {
if (Raphael.chord.find(currentchord , currenttype,i)) {
var itemid = "chord" + i;
var theDiv = "<div class='carousel-item"+((itemid=="chord1") ? ' active':'')+" ' id='"+currentchord+''+itemid+"'> "+chordsiblings[i-1].outerHTML+" </div>";
$('.items-slider1').append(theDiv);
}
}
$('.carousel-inner').carousel();
});
It was needed to do call the click function first before popover as below
$('[data-bs-toggle="popover"]').click(function() {
var oldChord = jQuery(this).text();
var currentchord = getChordRoots(oldChord);
var currenttype = oldChord.substr(currentchord.length);
findallchord(currentchord , currenttype);
var chordsiblings = $('#div3').children().siblings("svg");
for (let i = 1; i < 10; i++) {
if (Raphael.chord.find(currentchord , currenttype,i)) {
var itemid = "chord" + i;
var theDiv = "<div class='carousel-item"+((itemid=="chord1") ? ' active':'')+" ' id='"+currentchord+''+itemid+"'> "+chordsiblings[i-1].outerHTML+" </div>";
$('.items-slider1').append(theDiv);
}
}
}).popover({
html: true,
content: function() {
return $('.popup').html();
}});

Counting different input values, add them and show result

I want to make a "drink counter". There are 3 inputs which add another drink onclick. Every drink has a specific value in alcohol (var bier, var wein, var soju).
So on every count up (click), the script is supposed to:
count up the value in the respective input [this works]
add up all the numbers and drinks multiplied by their alcohol value, so added_up = bier_full + soju_full + wein_full;
If you look at the code, you will notice that I'm quite the noob. Help would be much appreciated. I can't think of a way to add all the drinks*alc. values up and display them in the id="status".
HTML:
var full = 100;
var bier = 12.7;
var wein = 10;
var soju = 3.5;
status = document.getElementById("status");
var bier_c = parseInt(document.getElementById("beer").value);
var soju_c = parseInt(document.getElementById("soju").value);
var wein_c = parseInt(document.getElementById("wine").value);
var bier_i = document.getElementById("bier_info");
var soju_i = document.getElementById("soju_info");
var wein_i = document.getElementById("wein_info");
function reset() {
bier_c = 0;
soju_c = 0;
wein_c = 0;
document.getElementById("beer").value = "0";
document.getElementById("soju").value = "0";
document.getElementById("wine").value = "0";
};
function bier_s() {
bier_c++;
document.getElementById("beer").value = bier_c;
bier_full = bier_c * bier;
bier_i.innerHTML = bier_full;
return bier_full;
};
function soju_s() {
soju_c++;
document.getElementById("soju").value = soju_c;
soju_full = soju_c * soju;
soju_i.innerHTML = soju_full;
return soju_full;
};
function wein_s() {
wein_c++;
document.getElementById("wine").value = wein_c;
wein_full = wein_c * wein;
wein_i.innerHTML = wein_full;
return wein_full;
};
added_up = bier_full + soju_full + wein_full;
alert(added_up);
<label>Beer</label><input id="beer" type="button" style="width: 50px;" onclick="bier_s();" value="0">
<label>Soju</label><input id="soju" type="button" style="width: 50px;" onclick="soju_s();" value="0">
<label>Wine</label><input id="wine" type="button" style="width: 50px;" onclick="wein_s();" value="0">
<br/>
<h2 class="c_red" id="status">Let's go!</h2>
<div class="am_info">
<p>Bier: <span id="bier_info"></span></p>
<p>Soju: <span id="soju_info"></span></p>
<p>Wine: <span id="wein_info"></span></p>
</div>
just add a method that runs every time the other methods runs =D
var full = 100;
var bier = 12.7;
var wein = 10;
var soju = 3.5;
var bier_full = 0, soju_full = 0, wein_full = 0;
status = document.getElementById("status");
var bier_c = parseInt(document.getElementById("beer").value);
var soju_c = parseInt(document.getElementById("soju").value);
var wein_c = parseInt(document.getElementById("wine").value);
var bier_i = document.getElementById("bier_info");
var soju_i = document.getElementById("soju_info");
var wein_i = document.getElementById("wein_info");
function reset() {
bier_c = 0;
soju_c = 0;
wein_c = 0;
document.getElementById("beer").value = "0";
document.getElementById("soju").value = "0";
document.getElementById("wine").value = "0";
};
function bier_s() {
bier_c++;
document.getElementById("beer").value = bier_c;
bier_full = bier_c * bier;
bier_i.innerHTML = bier_full;
addUp()
return bier_full;
};
function soju_s() {
soju_c++;
document.getElementById("soju").value = soju_c;
soju_full = soju_c * soju;
soju_i.innerHTML = soju_full;
addUp()
return soju_full;
};
function wein_s() {
wein_c++;
document.getElementById("wine").value = wein_c;
wein_full = wein_c * wein;
wein_i.innerHTML = wein_full;
addUp()
return wein_full;
};
function addUp(){
added_up = bier_full + soju_full + wein_full;
alert(added_up);
}
<label>Beer</label><input id="beer" type="button" style="width: 50px;" onclick="bier_s();" value="0">
<label>Soju</label><input id="soju" type="button" style="width: 50px;" onclick="soju_s();" value="0">
<label>Wine</label><input id="wine" type="button" style="width: 50px;" onclick="wein_s();" value="0">
<br/>
<h2 class="c_red" id="status">Let's go!</h2>
<div class="am_info">
<p>Bier: <span id="bier_info"></span></p>
<p>Soju: <span id="soju_info"></span></p>
<p>Wine: <span id="wein_info"></span></p>
</div>

jQuery formatting negative numbers

I am working on a local weather site through freecodecamp. I was wondering if anyone could help me figure out how to assign jQuery to show parenthesis around negative numbers. i.e. when it is -5 degrees I am trying to get it to say (-5).
Here is the jQuery I am currently working with...
$(document).ready(function() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var long;
var lat;
lat = position.coords.latitude;
long = position.coords.longitude;
var api = "http://api.openweathermap.org/data/2.5/weather?lat=" + lat + "&lon=" + long + "&appid=79b001616877b59c717616181ee219ec";
$.getJSON(api, function(info) {
var farh;
var cels;
var kelvin;
var tempMin;
var minTemp;
var tempMax;
var maxTemp;
var tempMinC;
var minTempC;
var tempMaxC;
var maxTempC;
var strF = ("\u00B0'F'");
var tempSwitch = false;
kelvin = info.main.temp;
farh = Math.round((kelvin) * (9 / 5) - 459.67);
cels = Math.round(kelvin - 273);
tempMinC = info.main.temp_min;
minTempC = Math.round(tempMinC - 273);
tempMaxC = info.main.temp_max;
maxTempC = Math.round(tempMaxC - 273);
tempMin = info.main.temp_min;
minTemp = Math.round((tempMin) * (9 / 5) - 459.67);
tempMax = info.main.temp_max;
maxTemp = Math.round((tempMax) * (9 / 5) - 459.67);
var city = info.name;
var weatherInfo = info.weather[0].description;
var forecastLow = minTemp;
var forecastHigh = maxTemp;
var forecastLowC = minTempC;
var forecastHighC = maxTempC;
var currCond = info.weather[0].icon;
$('#farh').html(farh);
$('#city').html(city);
$('#weatherInfo').html(weatherInfo);
$('#forecastLow').html(forecastLow);
$('#forecastHigh').html(forecastHigh);
$('#currCond').html(currCond);
$('#switch').click(function() {
if (tempSwitch === false) {
$('#farh').html(cels);
$('#forecastLow').html(forecastLowC)
$('#forecastHigh').html(forecastHighC)
tempSwitch = true;
} else {
$('#farh').html(farh);
$('#forecastLow').html(forecastLow);
$('#forecastHigh').html(forecastHigh);
tempSwitch = false;
}
});
});
});
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<h2 class="weather-header" id="city"></h2>
<h1><span class="curr-temp" id="farh"></span><span class="curr-temp">&deg</span></h1>
<div class="col-md-5"></div>
<div class="col-md-2">
<label class="switched">
<input type="checkbox" id="switch">
<div class="slider"></div>
</label>
</div>
<div class="col-md-5"></div>
<h3><span class="hi-lo" id="forecastLow"></span> Low - <span class="hi-lo" id="forecastHigh"></span> High</h3>
<p class="forecast" id="weatherInfo"></p>
You can create a function like this to format your Output:
function formatTemperature(value){
if(value < 0)
return "(" + value + ")";
else
return value;
};
and wrap your values calling this function, passing the values.
I've updated your snippet example.
$(document).ready(function() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var long;
var lat;
lat = position.coords.latitude;
long = position.coords.longitude;
var api = "http://api.openweathermap.org/data/2.5/weather?lat=" + lat + "&lon=" + long + "&appid=79b001616877b59c717616181ee219ec";
$.getJSON(api, function(info) {
var farh;
var cels;
var kelvin;
var tempMin;
var minTemp;
var tempMax;
var maxTemp;
var tempMinC;
var minTempC;
var tempMaxC;
var maxTempC;
var strF = ("\u00B0'F'");
var tempSwitch = false;
kelvin = info.main.temp;
farh = Math.round((kelvin) * (9 / 5) - 459.67);
cels = Math.round(kelvin - 273);
tempMinC = info.main.temp_min;
minTempC = Math.round(tempMinC - 273);
tempMaxC = info.main.temp_max;
maxTempC = Math.round(tempMaxC - 273);
tempMin = info.main.temp_min;
minTemp = Math.round((tempMin) * (9 / 5) - 459.67);
tempMax = info.main.temp_max;
maxTemp = Math.round((tempMax) * (9 / 5) - 459.67);
var city = info.name;
var weatherInfo = info.weather[0].description;
var forecastLow = minTemp;
var forecastHigh = maxTemp;
var forecastLowC = minTempC;
var forecastHighC = maxTempC;
var currCond = info.weather[0].icon;
function formatTemperature(value){
if(value < 0)
return "(" + value + ")";
else
return value;
}
$('#farh').html(farh);
$('#city').html(city);
$('#weatherInfo').html(weatherInfo);
$('#forecastLow').html(forecastLow);
$('#forecastHigh').html(forecastHigh);
$('#currCond').html(currCond);
$('#switch').click(function() {
if (tempSwitch === false) {
$('#farh').html(formatTemperature(cels));
$('#forecastLow').html(formatTemperature(forecastLowC));
$('#forecastHigh').html(formatTemperature(forecastHighC));
tempSwitch = true;
} else {
$('#farh').html(formatTemperature(farh));
$('#forecastLow').html(formatTemperature(forecastLow));
$('#forecastHigh').html(formatTemperature(forecastHigh));
tempSwitch = false;
}
});
});
});
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<h2 class="weather-header" id="city"></h2>
<h1><span class="curr-temp" id="farh"></span><span class="curr-temp">&deg</span></h1>
<div class="col-md-5"></div>
<div class="col-md-2">
<label class="switched">
<input type="checkbox" id="switch">
<div class="slider"></div>
</label>
</div>
<div class="col-md-5"></div>
<h3><span class="hi-lo" id="forecastLow"></span> Low - <span class="hi-lo" id="forecastHigh"></span> High</h3>
<p class="forecast" id="weatherInfo"></p>

Dynamically changing pictures based on text input

I am writing a webpage at the moment where I am converting temperature to Fahrenheit from Celsius and vice versa. While doing that if the temperature is in a certain degree I need to display a picture and if it is in a different range I need to display another picture(and one more time). I have got the right picture displaying at the right time, but I can't seem to figure out how to get the pictures to switch, and instead they just continually add up.
<!DOCTYPE html>
<html>
<head>
<script>
function convertTemp(fAfter)
{
var c = document.getElementById('c'), f = document.getElementById('f');
var fAfter;
var cAfter
if(c.value != '')
{
f.value = (c.value * 9 / 5 + 32);
fAfter = (c.value * 9 / 5 + 32);
c.value = c.value;
return fAfter;
}
else
{
c.value = ((f.value - 32) * 5 / 9);
f.value = f.value;
fAfter = f.value;
return fAfter;
}
}
function changePicture()
{
var A = convertTemp();
if (A > 50)
{
var img = document.createElement('img');
img.src = "warm.gif";
document.body.appendChild(img);
}
else if (A < 50 & A > 32)
{
var img = document.createElement('img');
img.src = "cool.gif";
document.body.appendChild(img);
}
else
{
var img = document.createElement('img');
img.src = "cold.gif";
document.body.appendChild(img);
}
}
function clearBoth()
{
var c = document.getElementById('c');
c.value = '';
var f =document.getElementById('f');
f.value= '';
}
var button = document.getElementById("convert");
</script>
</head>
<body>
<input placeholder = "Celsius" id="c" onclick='clearBoth()' >&#176C</br>
<input placeholder = "Fahrenheit" id="f" onclick='clearBoth()' >&#176F</br>
<button type="button" id="convert" onclick="convertTemp() & changePicture()">Convert</button>
</body>
<p>
</p>
</html>
You can create an img that is available on the global scope and change it's src attribute according to the input value. Initially you can hide the image.
HTML :
<body>
<input placeholder = "Celsius" id="c" onclick='clearBoth()' >&#176C</br>
<input placeholder = "Fahrenheit" id="f" onclick='clearBoth()' >&#176F</br>
<img src="" id="tempImage"/>
<button type="button" id="convert">Convert</button>
</body>
javaScript :
var img = document.getElementById("tempImage");
img.style.display = 'none';
function convertTemp(fAfter)
{
var c = document.getElementById('c'), f = document.getElementById('f');
var fAfter;
var cAfter
if(c.value != '')
{
f.value = (c.value * 9 / 5 + 32);
fAfter = (c.value * 9 / 5 + 32);
c.value = c.value;
return fAfter;
}
else
{
c.value = ((f.value - 32) * 5 / 9);
f.value = f.value;
fAfter = f.value;
return fAfter;
}
}
function changePicture()
{
var A = convertTemp();
img.style.display = '';
if (A > 50)
{
img.src = "http://3.bp.blogspot.com/-I5le-iONsuc/UDwY0gx6LMI/AAAAAAAAAnk/2VVq3KX7e2I/s1600/600px-Capital_C.png";
}
else if (A < 50 & A > 32)
{
img.src = "http://static.tumblr.com/148af423ee41cdb24507f372f95bd4d0/wuvn5qh/ovFmzk9sh/tumblr_static_f-word-1ha91xq.png";
}
else
{
img.src = "http://static.tumblr.com/148af423ee41cdb24507f372f95bd4d0/wuvn5qh/ovFmzk9sh/tumblr_static_f-word-1ha91xq.png";
}
}
function clearBoth()
{
var c = document.getElementById('c');
c.value = '';
var f =document.getElementById('f');
f.value= '';
}
var button = document.getElementById("convert");
button.onclick = changePicture;
jsFiddle

Wrong values from JS-Accessed DOM

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?

Categories

Resources