Alternative way to know if mouse is over an element (Javascript) - javascript

I have a script which shows a "hover element" (like a zoom) when my mouse is over it. I know it's a bit messy but here's an example:
function showOverflow2(e) {
let cell = e.currentTarget;
let clone = cell.cloneNode(true);
if (cell.children[0].scrollWidth <= cell.children[0].clientWidth) {
return false;
};
clone.innerHTML = clone.children[0].innerHTML;
clone.style.position = 'absolute';
clone.style.backgroundColor = 'white';
clone.style.borderWidth = '2px';
clone.style.lineHeight = cell.scrollHeight + 'px';
clone.style.whiteSpace = 'nowrap';
x0 = (
cell.offsetLeft +
parseFloat(
getComputedStyle(
cell.parentElement.parentElement.parentElement.parentElement
)["padding-left"].slice(0, -2)
) + 2
);
y0 = (
cell.offsetTop +
parseFloat(
getComputedStyle(
cell.parentElement.parentElement.parentElement.parentElement
)["padding-top"].slice(0, -2)
) + 2
);
xmid = x0 + (cell.clientWidth / 2);
ymid = y0 + (cell.clientHeight / 2);
let body = document.getElementsByTagName('body')[0];
body.appendChild(clone);
clone.style.height = cell.scrollHeight + 'px';
clone.style.width = clone.scrollWidth + 'px';
xf = xmid - (clone.clientWidth / 2);
yf = ymid - (clone.clientHeight / 2);
clone.style.top = yf + 'px';
clone.style.left = xf + 'px';
// FOCUS ON THIS PART
clone.addEventListener("mouseout", function() {
clone.remove();
});
// END OF FOCUS
};
let all_cells = document.getElementsByTagName('td');
for (let i = 0; i < all_cells.length; i++) {
let current_cell = all_cells[i];
if (current_cell.className !== 'buttons') {
current_cell.addEventListener("mouseover", showOverflow2);
}
}
body {
margin: 0;
}
#container {
background-color: gainsboro;
border: 2px solid black;
border-radius: 2px;
padding: 1.2%;
max-width: 50%;
}
table {
border-collapse: separate;
border-spacing: 0 0.5rem;
table-layout: fixed;
width: 100%;
}
tr {
background-color: white;
}
td {
width: calc(100%/3);
border: solid gray;
border-width: 2px 1px 2px 0;
padding: 0.7% 1%;
text-align: center;
white-space: nowrap;
}
span {
display: block;
overflow: hidden;
}
td:first-child {
border-left-width: 2px;
border-radius: 3px 0 0 3px;
}
td:last-child {
border-right-width: 2px;
border-radius: 0 3px 3px 0;
}
<div id="container">
<table id="table">
<tr>
<td class="cell1"><span>AAAAAAAAABBBCC</span></td>
<td class="cell2"><span>AAAAAAAAAABBBB</span></td>
<td class="cell3"><span>AAAAAAAAAAAAABBBBB</span></td>
</td>
</tr>
</table>
</div>
To remove the "zoom" and return things to normal, I'm simply using:
clone.addEventListener("mouseout", function() {
clone.remove();
This works fine if you are smoothly moving your mouse over the elements, but with a bigger table and faster movements, you can see for yourselves that some elements don't return to normal:
function showOverflow2(e) {
let cell = e.currentTarget;
let clone = cell.cloneNode(true);
if (cell.children[0].scrollWidth <= cell.children[0].clientWidth) {
return false;
};
clone.innerHTML = clone.children[0].innerHTML;
clone.style.position = 'absolute';
clone.style.backgroundColor = 'white';
clone.style.borderWidth = '2px';
clone.style.lineHeight = cell.scrollHeight + 'px';
clone.style.whiteSpace = 'nowrap';
x0 = (
cell.offsetLeft +
parseFloat(
getComputedStyle(
cell.parentElement.parentElement.parentElement.parentElement
)["padding-left"].slice(0, -2)
) + 2
);
y0 = (
cell.offsetTop +
parseFloat(
getComputedStyle(
cell.parentElement.parentElement.parentElement.parentElement
)["padding-top"].slice(0, -2)
) + 2
);
xmid = x0 + (cell.clientWidth / 2);
ymid = y0 + (cell.clientHeight / 2);
let body = document.getElementsByTagName('body')[0];
body.appendChild(clone);
clone.style.height = cell.scrollHeight + 'px';
clone.style.width = clone.scrollWidth + 'px';
xf = xmid - (clone.clientWidth / 2);
yf = ymid - (clone.clientHeight / 2);
clone.style.top = yf + 'px';
clone.style.left = xf + 'px';
// FOCUS ON THIS PART
clone.addEventListener("mouseout", function() {
clone.remove();
});
// END OF FOCUS
};
let all_cells = document.getElementsByTagName('td');
for (let i = 0; i < all_cells.length; i++) {
let current_cell = all_cells[i];
if (current_cell.className !== 'buttons') {
current_cell.addEventListener("mouseover", showOverflow2);
}
}
body {
margin: 0;
}
#container {
background-color: gainsboro;
border: 2px solid black;
border-radius: 2px;
padding: 1.2%;
max-width: 50%;
}
table {
border-collapse: separate;
border-spacing: 0 0.5rem;
table-layout: fixed;
width: 100%;
}
tr {
background-color: white;
}
td {
width: calc(100%/3);
border: solid gray;
border-width: 2px 1px 2px 0;
padding: 0.7% 1%;
text-align: center;
white-space: nowrap;
}
span {
display: block;
overflow: hidden;
}
td:first-child {
border-left-width: 2px;
border-radius: 3px 0 0 3px;
}
td:last-child {
border-right-width: 2px;
border-radius: 0 3px 3px 0;
}
<div id="container">
<table id="table">
<tr>
<td class="cell1"><span>AAAAAAAAABBBCC</span></td>
<td class="cell2"><span>AAAAAAAAABBBB</span></td>
<td class="cell3"><span>AAAAAAAAAAAABBBBB</span></td>
</td>
</tr>
<tr>
<td class="cell1"><span>AAAAAAAABBBCC</span></td>
<td class="cell2"><span>AAAAAAAAABBBB</span></td>
<td class="cell3"><span>AAAAAAAAAAAAABBBBB</span></td>
</td>
</tr>
<tr>
<td class="cell1"><span>AAAAAAAAABBBCC</span></td>
<td class="cell2"><span>AAAAAAAAAAABBBB</span></td>
<td class="cell3"><span>AAAAAAAAAAAAABBBBB</span></td>
</td>
</tr>
<tr>
<td class="cell1"><span>AAAAAAAAABBBCC</span></td>
<td class="cell2"><span>AAAAAAAAAABBBB</span></td>
<td class="cell3"><span>AAAAAAAAAAAAABBBBB</span></td>
</td>
</tr>
<tr>
<td class="cell1"><span>AAAAAAAAABBBCC</span></td>
<td class="cell2"><span>AAAAAAAAAAABBBB</span></td>
<td class="cell3"><span>AAAAAAAAAAAAAABBBBB</span></td>
</td>
</tr>
<tr>
<td class="cell1"><span>AAAAAAAAAABBBCC</span></td>
<td class="cell2"><span>AAAAAAAAAAaAABBBB</span></td>
<td class="cell3"><span>AAAAAAAAAAAAAAAABBBBB</span></td>
</td>
</tr>
<tr>
<td class="cell1"><span>AAAAAAAABBBCC</span></td>
<td class="cell2"><span>AAAAAAASAABBBB</span></td>
<td class="cell3"><span>AAAAAAAAAAAAAAABBBBB</span></td>
</td>
</tr>
<tr>
<td class="cell1"><span>AAAAAAAAAABBBCC</span></td>
<td class="cell2"><span>AAAAAAAAAABBBB</span></td>
<td class="cell3"><span>AAAAAAAAAAAAABBBBB</span></td>
</td>
</tr>
</table>
</div>
If I can't trust the mouseout event, what can I do to fix this?
I thought about using a eventListener on mouse movement to test if the mouse is inside the element using absolute coordinates, but probably there's a simpler solution.

You could do something similar using CSS by repeating the content (enlarged) and showing and hiding it on hover. Simple example below.
table {
padding: 30px;
}
td {
position: relative;
padding: 4px;
border: 1px solid blue;
}
.grow {
display: none;
background-color: #fff;
border: 1px solid #000;
padding: 3px;
z-index: 10;
}
td:hover .grow {
display: block;
position: absolute;
top: 0;
left: 0;
transform: scale(1.5);
}
<html>
<head></head>
<body>
<table>
<tr>
<td>asdf<span class="grow">ASDF</span></td>
<td>fasd<span class="grow">FASD</span></td>
</table>
</body>
</html>

I'm answering my own question 'cause I needed to combine some ideas to make it work well.
First I need to point out that, for some reason, the problem I described happens in the browser only when the Developer tab (f12) is open, otherwise all works fine.
But still I wanted to be certain that no cell would freeze that way, so I used css like Ed Lucas. Still, I needed Javascript to get the centering right.
After days trying this I finally found a way to center it using css that worked with absolute positioning and the child element being larger.
I didn't remove the Javascript method because it gives me flexibility of commands to trigger and revert this event.
In the end, my code is looking like this:
function showOverflow(e) {
const div = e;
const cell = div.parentElement;
const span = div.children[0];
if (span.scrollWidth <= span.clientWidth) {
return false;
}
const clone = div.cloneNode(true);
clone.classList.add('hovercell');
cell.appendChild(clone);
let cell_style = getComputedStyle(cell);
function cloneRemove(host) {
clone.remove();
clearInterval(host.id);
}
function isInside(host) {
if (cell_style['z-index'] === '0') {
cloneRemove(host);
}
}
let host = {};
host.id = setInterval(isInside.bind(null, host), 100);
clone.addEventListener("mouseleave", function() {
cloneRemove(host);
});
}
td {
border: 2px solid gray;
padding: 0.7% 1%;
text-align: center;
white-space: nowrap;
z-index: 0;
position: relative;
}
td:hover {
z-index: 2;
}
span {
display: block;
overflow: hidden;
}
.hovercell {
background-color: white;
border: 2px solid gray;
padding: 6px 8px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) scale(1.2);
}
<table>
<tbody>
<tr>
<td>
<div onclick="showOverflow(this)">
<span>A big cell--- 1</span>
</div>
</td>
<td>
<div onclick="showOverflow(this)">
<span>A big cell--- 2</span>
</div>
</td>
</tr>
</tbody>
</table>
Hope it helps someone.

Related

toggle button of objects displayed using javascript doesn't seem to work as intended

I have displayed my array of objects using dom manipulation. but it seems there is something wrong with the toggle function that i have called to the buttons.
i require each button to switch from "read" to "not read" but it only works for the first object displayed. the second one toggles the first but doesn't toggle itself? could i please get an explanation as well
let clicked = false;
function toggle(){
if(!clicked){
clicked = true;
document.getElementById("readbtn").innerHTML = "Not read";
}
else{
clicked = false;
document.getElementById("readbtn").innerHTML = "Read";
}
}
function Book(name, author, ReadOrNot) {
this.name = name
this.author = author
this.ReadOrNot = ReadOrNot
}
const book1 = new Book("The Hobbit", "J.R.R Tolkien", "Read")
const book2 = new Book("A Game of Thrones", "George R.R. Martin", "Not read")
let myLibrary = []
function addBookToLibrary(...arr) {
myLibrary.push(...arr)
}
addBookToLibrary(book1)
addBookToLibrary(book2)
console.log(myLibrary)
function addBookToTable(){
let tbody = document.querySelector('tbody')
myLibrary.forEach(b =>{
let tr = document.createElement('tr')
let content = '<td>' + b.name + '</td><td>' + b.author + '</td>'
if(b.ReadOrNot == 'Read'){
content += '<td><button id="readbtn" class="btn rdbtn" onclick="toggle()">Read</button></td>'
}
else if(b.ReadOrNot == 'Not read'){
content += '<td><button id="readbtn" class="btn rdbtn" onclick="toggle()">Not read</button></td>'
}
content += '<td><button class="btn delbtn">Delete</button></td>'
tr.innerHTML = content
tbody.appendChild(tr)
})
}
addBookToTable()
*{
box-sizing: border-box;
--darkblue: #465c6b;
--blue: #779bb3;
--lightgrey: rgb(244, 242, 242);
}
table{
border-collapse: collapse;
width: 30em;
background-color: white;
border-radius: 5px;
box-shadow: 0px 10px 30px 5px rgba(0,0,0,.15);
margin: 100px auto;
}
table thead td{
background-color: rgb(38, 36, 36);
color: whitesmoke;
border-bottom: .5px solid black;
font-size: 15px;
letter-spacing: 1px;
padding: 8px;
}
table tbody td {
padding: 8px;
}
table tbody tr td:nth-child(4){
text-align: center;
}
table tbody tr td:nth-child(3){
text-align: center;
}
table thead tr td:nth-child(3){
text-align: center;
}
table td{
font-size: 18px;
color: rgb(38, 36, 36);
}
.btn.delbtn{
background-color: #990026;
min-width: 100px;
}
<table>
<thead>
<tr>
<td>Name</td>
<td>Author</td>
<td>Status</td>
<td> </td>
</tr>
</thead>
<tbody>
</tbody>
</table>

Modal Box/ Pop up is not coming

This is my code I am selecting two columns , and then I am taking the difference of correspoding cells and creating new column, and displaying it in a single table. I want to display it as a pop-up(modal box). Like on selecting two input checkboxes the resultant table should come as a form of popup and after closing it, i can again select any checkboxes and again a table should be formed and display as popup
But when I am doing this way its is not coming as a pop and the same table is getting appended. Can anyone please help with this one?
function hidemodal() {
$("#myModal").hide();
}
const table = document.getElementById("main-table"),
checkboxes = table.querySelectorAll('.header > input[type="checkbox"]');
let columns = {};
for (let i = 0; i < checkboxes.length; i++) {
checkboxes[i].addEventListener("input", onInput);
}
function onInput(e) {
const input = e.target,
column = input.parentNode.cellIndex,
tds = table.querySelectorAll('td:nth-child(' + (column + 1) + ')');
if (input.checked) {
let list = [];
for (let i = 0; i < tds.length; i++) {
list[list.length] = tds[i].textContent;
}
columns[column] = list;
}
else {
delete columns[column];
}
if (Object.keys(columns).length > 1)
showDifference();
else
table.classList.remove("result");
}
function showDifference() {
var array1 = [];
var array2 = [];
var a = Object.keys(columns)[0], b = Object.keys(columns)[1]
const result = columns[a].map((el, i) => {
first = columns[a][i];
array1.push(first)
second = columns[b][i];
array2.push(second)
const regex = /\d+/;
const firstNumber = parseInt(first.match(regex));
const secondNumber = parseInt(second.match(regex));
const diff = Math.abs(firstNumber - secondNumber);
return `$${diff}`;
})
buildTable();
// var tablediff;
var modalBody = $('<div id="modalContent"></div>');
function buildTable() {
var table = document.createElement("TABLE");
table.setAttribute("id", "myTable");
document.body.appendChild(table);
for (let i = 0; i < 3; i++) {
var y = document.createElement("TR");
y.setAttribute("id", "myTr" + i)
document.getElementById("myTable").appendChild(y);
var z = document.createElement("TD");
var t = document.createTextNode(array1[i]);
var z1 = document.createElement("TD");
var s = document.createTextNode(array2[i]);
var z2 = document.createElement("TD");
var r = document.createTextNode(result[i]);
z.appendChild(t);
z1.appendChild(s);
z2.appendChild(r);
document.getElementById("myTr" + i).appendChild(z);
document.getElementById("myTr" + i).appendChild(z1)
document.getElementById("myTr" + i).appendChild(z2)
}
}
modalBody.append(table);
$(".modal-body").html(modalBody);
}
table {
border: 1px solid white;
text-align: center;
padding: 6px;
background: #e1edf9;
}
td {
border: 1px solid white;
text-align: center;
padding: 6px;
}
td:first-child,
tr:first-child {
background-color: #003a6a !important;
color: white !important;
}
.table-scroll {
position: relative;
width: 100%;
z-index: 1;
margin: auto;
overflow: auto;
}
.table-scroll table {
width: 100%;
min-width: 1280px;
margin: auto;
border-collapse: separate;
border-spacing: 0;
}
.table-wrap {
position: relative;
}
.table-scroll tr:first-child {
background: #333;
color: #fff;
position: -webkit-sticky;
position: sticky;
top: 0;
}
td:first-child {
position: -webkit-sticky;
position: sticky;
left: 0;
z-index: 2;
background: #ccc;
}
.table-scroll tfoot tr {
position: -webkit-sticky;
position: sticky;
bottom: 0;
background: #666;
color: #fff;
z-index: 4;
}
tr:first-child {
z-index: 5;
}
#media screen and (max-width: 500px) {
td:first-child {
position: -webkit-sticky;
position: sticky;
left: 0;
z-index: 2;
background: #ccc;
max-width: 140px;
}
}
.main-table:not(.result) th.result,
.main-table:not(.result) td.result {
display: none;
}
<div id="table-scroll" class="table-scroll">
<table class="data" id="main-table">
<tbody>
<tr>
<th class="header">Three</th>
<th class="header">Four<input type="checkbox" value="on" name="cb4" /></th>
<th class="header">Five<input type="checkbox" value="on" name="cb5" /></th>
<th class="header">Five<input type="checkbox" value="on" name="cb5" /></th>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>12</td>
<td>22</td>
<td>32</td>
<td>34</td>
</tr>
<tr>
<td>21</td>
<td>22</td>
<td>23</td>
<td>7</td>
</tr>
</tbody>
</table>
</div>
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" onclick="hidemodal ()">×</button>
</div>
<div class="modal-body"></div>
</div>
</div>
</div>
You are using the same table variable for #main-table and for the results table. However the results table variable is only available inside buildTable(), and when you use modalBody.append(table); outside of that function, you are moving the #main-table instead. So for your own sake, try avoid recycle variable names.
Also, you don't have to use getElementById for the element you just created via createElement()
function hidemodal() {
document.body.classList.remove("popup");
}
function showmodal() {
document.body.classList.add("popup");
}
const table = document.getElementById("main-table"),
checkboxes = table.querySelectorAll('.header > input[type="checkbox"]');
let columns = {};
for (let i = 0; i < checkboxes.length; i++) {
checkboxes[i].addEventListener("input", onInput);
}
function onInput(e) {
const input = e.target,
column = input.parentNode.cellIndex,
tds = table.querySelectorAll('td:nth-child(' + (column + 1) + ')');
if (input.checked) {
let list = [];
for (let i = 0; i < tds.length; i++) {
list[list.length] = tds[i].textContent;
}
columns[column] = list;
} else {
delete columns[column];
}
if (Object.keys(columns).length > 1)
showDifference();
else
table.classList.remove("result");
}
function showDifference() {
var array1 = [];
var array2 = [];
var a = Object.keys(columns)[0],
b = Object.keys(columns)[1]
const result = columns[a].map((el, i) => {
first = columns[a][i];
array1.push(first)
second = columns[b][i];
array2.push(second)
const regex = /\d+/;
const firstNumber = parseInt(first.match(regex));
const secondNumber = parseInt(second.match(regex));
const diff = Math.abs(firstNumber - secondNumber);
return `$${diff}`;
})
// var tablediff;
var modalBody = $('<div id="modalContent"></div>');
buildTable();
function buildTable() {
var modalTable = document.createElement("TABLE");
modalTable.setAttribute("id", "myTable");
modalBody.html(modalTable);
for (let i = 0; i < 3; i++) {
var y = document.createElement("TR");
y.setAttribute("id", "myTr" + i)
modalTable.appendChild(y);
var z = document.createElement("TD");
var t = document.createTextNode(array1[i]);
var z1 = document.createElement("TD");
var s = document.createTextNode(array2[i]);
var z2 = document.createElement("TD");
var r = document.createTextNode(result[i]);
z.appendChild(t);
z1.appendChild(s);
z2.appendChild(r);
y.appendChild(z);
y.appendChild(z1)
y.appendChild(z2)
}
return table;
}
// modalBody.append(table);
$(".modal-body").html(modalBody);
showmodal();
}
table {
border: 1px solid white;
text-align: center;
padding: 6px;
background: #e1edf9;
}
td {
border: 1px solid white;
text-align: center;
padding: 6px;
}
td:first-child,
tr:first-child {
background-color: #003a6a !important;
color: white !important;
}
.table-scroll {
position: relative;
width: 100%;
z-index: 1;
margin: auto;
overflow: auto;
}
.table-scroll table {
width: 100%;
min-width: 1280px;
margin: auto;
border-collapse: separate;
border-spacing: 0;
}
.table-wrap {
position: relative;
}
.table-scroll tr:first-child {
background: #333;
color: #fff;
position: -webkit-sticky;
position: sticky;
top: 0;
}
td:first-child {
position: -webkit-sticky;
position: sticky;
left: 0;
z-index: 2;
background: #ccc;
}
.table-scroll tfoot tr {
position: -webkit-sticky;
position: sticky;
bottom: 0;
background: #666;
color: #fff;
z-index: 4;
}
tr:first-child {
z-index: 5;
}
#media screen and (max-width: 500px) {
td:first-child {
position: -webkit-sticky;
position: sticky;
left: 0;
z-index: 2;
background: #ccc;
max-width: 140px;
}
}
.main-table:not(.result) th.result,
.main-table:not(.result) td.result {
display: none;
}
body:not(.popup)>.modal {
display: none;
}
body.popup> :not(.modal) {
-webkit-filter: blur(1px);
-moz-filter: blur(1px);
-o-filter: blur(1px);
-ms-filter: blur(1px);
filter: blur(1px);
}
.modal {
background-color: rgba(127, 127, 127, 0.5);
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
z-index: 999;
display: flex;
}
.modal>.modal-dialog {
margin: auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="table-scroll" class="table-scroll">
<table class="data" id="main-table">
<tbody>
<tr>
<th class="header">Three</th>
<th class="header">Four<input type="checkbox" value="on" name="cb4" /></th>
<th class="header">Five<input type="checkbox" value="on" name="cb5" /></th>
<th class="header">Five<input type="checkbox" value="on" name="cb5" /></th>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>12</td>
<td>22</td>
<td>32</td>
<td>34</td>
</tr>
<tr>
<td>21</td>
<td>22</td>
<td>23</td>
<td>7</td>
</tr>
</tbody>
</table>
</div>
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" onclick="hidemodal ()">×</button>
</div>
<div class="modal-body"></div>
</div>
</div>
</div>

How to simplify my JS functions in a nutrition calculator?

https://codepen.io/TBD007/pen/zYxgWbv
Trying to avoid having to write a function for each button's onclick event. Currently i am using a separate function for each onclick. I am pretty sure there is a way to put all that into one single function but i just can't figure it out on my own.. Any idea to simplify the js code in order to calculate the values? Help is very much appreciated!
function test() {
var summe = document.getElementById("txtResult").innerHTML;
var x = document.getElementById("test").getAttribute("value");
document.getElementById("txtResultItem").innerHTML = x;
}
function test2() {
var summe = document.getElementById("txtResult").innerHTML;
var x = document.getElementById("test2").getAttribute("value");
document.getElementById("txtResultItem").innerHTML = x;
}
function test3() {
var summe = document.getElementById("txtResult").innerHTML;
var x = document.getElementById("test3").getAttribute("value");
document.getElementById("txtResultItem").innerHTML = x;
}
Here's a the full snippet:
var result = document.getElementById("txtResult").innerHTML;
function test() {
var summe = document.getElementById("txtResult").innerHTML;
var x = document.getElementById("test").getAttribute("value");
document.getElementById("txtResultItem").innerHTML = x;
}
function test2() {
var summe = document.getElementById("txtResult").innerHTML;
var x = document.getElementById("test2").getAttribute("value");
document.getElementById("txtResultItem").innerHTML = x;
}
function test3() {
var summe = document.getElementById("txtResult").innerHTML;
var x = document.getElementById("test3").getAttribute("value");
document.getElementById("txtResultItem").innerHTML = x;
}
function test4() {
var summe = document.getElementById("txtResult").innerHTML;
var x = document.getElementById("test4").getAttribute("value");
document.getElementById("txtResultItem").innerHTML = x;
}
function test5() {
var summe = document.getElementById("txtResult").innerHTML;
var x = document.getElementById("test5").getAttribute("value");
document.getElementById("txtResultItem").innerHTML = x;
}
function test6() {
var summe = document.getElementById("txtResult").innerHTML;
var x = document.getElementById("test6").getAttribute("value");
document.getElementById("txtResultItem").innerHTML = x;
}
function test7() {
var summe = document.getElementById("txtResult").innerHTML;
var x = document.getElementById("test7").getAttribute("value");
document.getElementById("txtResultItem").innerHTML = x;
}
function test8() {
var summe = document.getElementById("txtResult").innerHTML;
var x = document.getElementById("test8").getAttribute("value");
document.getElementById("txtResultItem").innerHTML = x;
}
function test9() {
var summe = document.getElementById("txtResult").innerHTML;
var x = document.getElementById("test9").getAttribute("value");
document.getElementById("txtResultItem").innerHTML = x;
}
function test10() {
var summe = document.getElementById("txtResult").innerHTML;
var x = document.getElementById("test10").getAttribute("value");
document.getElementById("txtResultItem").innerHTML = x;
}
function test11() {
var summe = document.getElementById("txtResult").innerHTML;
var x = document.getElementById("test11").getAttribute("value");
document.getElementById("txtResultItem").innerHTML = x;
}
function test12() {
var summe = document.getElementById("txtResult").innerHTML;
var x = document.getElementById("test12").getAttribute("value");
document.getElementById("txtResultItem").innerHTML = x;
}
function test13() {
var summe = document.getElementById("txtResult").innerHTML;
var x = document.getElementById("test13").getAttribute("value");
document.getElementById("txtResultItem").innerHTML = x;
}
function test14() {
var summe = document.getElementById("txtResult").innerHTML;
var x = document.getElementById("test14").getAttribute("value");
document.getElementById("txtResultItem").innerHTML = x;
}
function add() {
var y = document.getElementById("txtResultItem").innerHTML;
var z = document.getElementById("txtResult").innerHTML;
document.getElementById("txtResult").innerHTML = Number(y) + Number(z);
}
function sub() {
var y = document.getElementById("txtResultItem").innerHTML;
var z = document.getElementById("txtResult").innerHTML;
document.getElementById("txtResult").innerHTML = Number(z) - Number(y);
}
function clearentry() {
document.getElementById("txtResultItem").innerHTML = 0;
document.getElementById("txtResult").innerHTML = 0;
}
.main {
width: 100%;
height: 100vh;
background: linear-gradient(to right, rgba(26, 26, 43, 0.496), rgba(26, 26, 43, 0.86)), url("https://www.miss.at/wp-content/uploads/2019/11/Technik-Panne-McDonalds-muss-400.000-Euro-an-Gewinner-zahlen-1024x683.jpg");
background-position: center;
background-size: cover;
background-repeat: no-repeat;
display: flex;
justify-content: center;
align-items: center;
}
button {
height: 60px;
width: 60px;
border: 2px solid silver;
box-shadow: 2px 2px 5px black;
position: relative;
}
#txtResult {
width: 257px;
height: 40px;
text-align: right;
background: rgba(40, 40, 53, 0.69);
margin-bottom: 5px;
box-shadow: inset -2px -2px 1px gray;
}
#txtResultItem {
width: 257px;
height: 40px;
text-align: right;
background: rgba(40, 40, 53, 0.69);
margin-bottom: 5px;
box-shadow: inset -2px -2px 1px gray;
}
button {
height: 60px;
width: 60px;
background-size: contain;
}
#btnClearEntry {
font-family: 'Raleway';
max-height: 60px;
max-width: 60px;
}
#btn1 {
background-image: url("https://img.scoop.it/aImnklIQUA5uWH212vRoWjl72eJkfbmt4t8yenImKBVvK0kTmF0xjctABnaLJIm9");
}
#btn2 {
background-image: url("https://www.mcdonalds.com/is/image/content/dam/ca/nfl/web/nutrition/products/nutrition/en/mcdonalds-big-mac.png?$Nutritional_Desktop$");
}
#btn3 {
background-image: url("https://www.mcdonalds.com/is/image/content/dam/ca/nfl/web/nutrition/products/nutrition/en/mcdonalds-hamburger.png?$Nutritional_Desktop$");
}
#btn4 {
background-image: url("https://www.mcdonalds.com/is/image/content/dam/ca/nfl/web/nutrition/products/nutrition/en/mcdonalds-6-chicken-mcnuggets.png?$Nutritional_Desktop$");
}
#btn5 {
background-image: url("https://www.mcdonalds.com/is/image/content/dam/ca/nfl/web/nutrition/products/nutrition/en/mcdonalds-crispy-caesar-chicken-mcwrap.png?$Nutritional_Desktop$");
}
#btn6 {
background-image: url("https://www.mcdonalds.com/is/image/content/dam/ca/nfl/web/nutrition/products/nutrition/en/mcdonalds-fries-medium.png?$Nutritional_Desktop$");
}
#btn7 {
background-image: url("https://www.mcdonalds.com/is/image/content/dam/ca/nfl/web/nutrition/products/nutrition/en/mcdonalds-blueberry-muffin-hero.png?$Nutritional_Desktop$");
}
#btn8 {
background-image: url("https://www.mcdonalds.com/is/image/content/dam/ca/nfl/web/nutrition/products/nutrition/en/mcdonalds-coca-cola.png?$Nutritional_Desktop$");
}
#btn9 {
background-image: url("https://www.mcdonalds.com/is/image/content/dam/ca/nfl/web/nutrition/products/nutrition/en/mcdonalds-side-caesar-salad.png?$Nutritional_Desktop$");
}
#btn10 {
background-image: url("https://www.mcdonalds.com/is/image/content/dam/ca/nfl/web/nutrition/products/nutrition/en/mcdonalds-egg-mcmuffin.png?$Nutritional_Desktop$");
}
#btn11 {
background-image: url("https://www.mcdonalds.com/is/image/content/dam/ca/nfl/web/nutrition/products/nutrition/en/mcdonalds-filet-o-fish.png?$Nutritional_Desktop$");
}
#btn12 {
background-image: url("https://www.mcdonalds.com/is/image/content/dam/ca/nfl/web/nutrition/products/nutrition/en/mcdonalds-quarter-pounder-cheese.png?$Nutritional_Desktop$");
}
#btn13 {
background-image: url("https://www.mcdonalds.com/is/image/content/dam/ca/nfl/web/nutrition/products/nutrition/en/mcdonalds-baked-apple-pie.png?$Nutritional_Desktop$");
}
#btn14 {
background-image: url("https://www.mcdonalds.com/is/image/content/dam/ca/nfl/web/nutrition/products/nutrition/en/mcdonalds-hot-fudge-sundae.png?$Nutritional_Desktop$")
}
#logo {
background-image: url("http://www.mcdonalds.at/sites/default/files/cms/social_media/sharelogo.png");
height: 60px;
width: 60px;
border: 0px solid rgba(40, 40, 53, 0.89);
box-shadow: 2px 2px 9px black;
}
#btnClearEntry {
background: rgba(40, 40, 53, 0.79);
border: 1px solid white;
color: white;
width: 62px;
height: 62px;
box-shadow: 2px 2px 7px black;
}
#btnplus {
color: white;
background: red;
border: 1px solid silver;
font-size: 18px;
width: 60px;
height: 60px;
box-shadow: 2px 2px 7px black;
}
#btnminus {
color: white;
background: rgba(255, 223, 15, 1);
border: 1px solid silver;
font-size: 30px;
width: 60px;
height: 60px;
box-shadow: 2px 2px 7px black;
}
#logo {
border: 1px solid white;
}
.calculator {
box-shadow: 2px 2px 10 px rgba(0, 0, 0, 0.648);
padding: 5px;
}
button:hover {
position: relative;
}
button[aria-label]:hover:after {
content: attr(aria-label);
padding: 4px 8px;
position: absolute;
left: 0;
top: 100%;
white-space: nowrap;
z-index: 20;
background: red;
color: yellow;
font-family: 'Raleway';
}
<head>
<link href="https://fonts.googleapis.com/css?family=Raleway&display=swap" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<div class="main">
<div class="calculator">
<table>
<tr>
<td colspan="4">
<div style="color:white; font-family:sans-serif;font-size:20px;" id="txtResult" readonly="readonly"></div>
</td>
</tr>
<tr>
<td colspan="4">
<div style="color:white; font-family:sans-serif;font-size:16px;" id="txtResultItem"></div>
</td>
</tr>
<tr>
<td id="test" value="475"><button onclick="test()" id="btn1" aria-label="Happy Meal"></button></td>
<td id="test2" value="540">
<button onclick="test2()" id="btn2" aria-label="Big Mac"></button>
</td>
<td><button aria-label="All Products" id="logo" ></button></td>
<td><button id="btnClearEntry" onclick="clearentry()">CE</button></td>
</tr>
<tr>
<td id="test3" value="200"><button onclick="test3()" id="btn3" aria-label="Hamburger"></button></td>
<td id="test4" value="250"><button onclick="test4()" id="btn4" aria-label="6 Chicken Nuggets"></button></td>
<td id="test5" value="570"><button onclick="test5()" id="btn5" aria-label="Crispy Chicken Wrap"></button></td>
<td><button id="btnplus" onclick="add()"><b>+</b></button></td>
</tr>
<tr>
<td id="test6" value="350"><button onclick="test6()" id="btn6" aria-label="Big Fries"></button></td>
<td id="test7" value="430"><button onclick="test7()" id="btn7" aria-label="Blueberry Muffin"></button></td>
<td id="test8" value="190"><button onclick="test8()" id="btn8" aria-label="Coke"></button></td>
<td><button id="btnminus" onclick="sub()"><b>-</b></button></td>
</tr>
<tr>
<td id="test9" value="360"><button onclick="test9()" id="btn9" aria-label="Cesars salad"></button></td>
<td id="test10" value="290"><button onclick="test10()" id="btn10" aria-label="Egg McMuffin"></button></td>
<td id="test11" value="360"><button onclick="test11()" id="btn11" aria-label="Fish Mac"></button></td>
<td id="test12" value="490"><button onclick="test12()" id="btn12" aria-label="Royal with Cheese"></button></td>
</tr>
<tr>
<td></td>
<td id="test13" value="270"><button onclick="test13()" id="btn13" aria-label="Baked Apple Pie"></button></td>
<td id="test14" value="340"><button onclick="test14()" id="btn14" aria-label="Mc Sundae"></button></td>
<td></td>
</tr>
</table>
</div>
</div>
</body>
Here is a shorter version
I use the following techniques
unobtrusive event handler
object to hold the names and values
DOM manipulation (sorry I got lazy on the operators)
removed the button from the link and used an image instead for the logo
const buttons = {
"Happy Meal": 475,
"Big Mac": 540,
"Hamburger": 200,
"6 Chicken Nuggets": 250,
"Crispy Chicken Wrap": 570,
"Big Fries": 350,
"Blueberry Muffin": 430,
"Coke": 190,
"Cesars salad": 360,
"Egg McMuffin": 290,
"Fish Mac": 360,
"Royal with Cheese": 490,
"Baked Apple Pie": 270,
"Mc Sundae": 340
}
const operators = [
'<img src="http://www.mcdonalds.at/sites/default/files/cms/social_media/sharelogo.png" aria-label="All Products" id="logo" ></img>',
'<button id="btnClearEntry" onclick="clearentry()">CE</button>',
'<button id="btnplus" onclick="add()"><b>+</b></button>',
'<button id="btnminus" onclick="sub()"><b>-</b></button>'
]
const tb = document.querySelector(".calculator table tbody");
let cnt = 0;
let tr = document.createElement("tr");
for (let but in buttons) {
cnt++;
td = document.createElement("td");
td.innerHTML = '<button type="button" id="btn' + cnt + '" aria-label="' + but + '" value="' + buttons[but] + '"></button>';
tr.appendChild(td)
if (cnt % 3 === 0) {
if (operators.length > 0) {
td = document.createElement("td");
td.innerHTML = operators.shift()
}
tr.appendChild(td);
tb.appendChild(tr);
tr = document.createElement("tr");
}
}
tb.appendChild(tr);
tb.addEventListener("click", function(e) {
const tgt = e.target;
if (tgt.type && tgt.type === "button") {
document.getElementById("txtResultItem").innerHTML = tgt.value;
}
});
function add() {
var y = document.getElementById("txtResultItem").innerHTML;
var z = document.getElementById("txtResult").innerHTML;
document.getElementById("txtResult").innerHTML = Number(y) + Number(z);
}
function sub() {
var y = document.getElementById("txtResultItem").innerHTML;
var z = document.getElementById("txtResult").innerHTML;
document.getElementById("txtResult").innerHTML = Number(z) - Number(y);
}
function clearentry() {
document.getElementById("txtResultItem").innerHTML = 0;
document.getElementById("txtResult").innerHTML = 0;
}
.main {
width: 100%;
height: 100vh;
background: linear-gradient(to right, rgba(26, 26, 43, 0.496), rgba(26, 26, 43, 0.86)), url("https://www.miss.at/wp-content/uploads/2019/11/Technik-Panne-McDonalds-muss-400.000-Euro-an-Gewinner-zahlen-1024x683.jpg");
background-position: center;
background-size: cover;
background-repeat: no-repeat;
display: flex;
justify-content: center;
align-items: center;
}
button {
height: 60px;
width: 60px;
border: 2px solid silver;
box-shadow: 2px 2px 5px black;
position: relative;
}
#txtResult {
width: 257px;
height: 40px;
text-align: right;
background: rgba(40, 40, 53, 0.69);
margin-bottom: 5px;
box-shadow: inset -2px -2px 1px gray;
}
#txtResultItem {
width: 257px;
height: 40px;
text-align: right;
background: rgba(40, 40, 53, 0.69);
margin-bottom: 5px;
box-shadow: inset -2px -2px 1px gray;
}
button {
height: 60px;
width: 60px;
background-size: contain;
}
#btnClearEntry {
font-family: 'Raleway';
max-height: 60px;
max-width: 60px;
}
#btn1 {
background-image: url("https://img.scoop.it/aImnklIQUA5uWH212vRoWjl72eJkfbmt4t8yenImKBVvK0kTmF0xjctABnaLJIm9");
}
#btn2 {
background-image: url("https://www.mcdonalds.com/is/image/content/dam/ca/nfl/web/nutrition/products/nutrition/en/mcdonalds-big-mac.png?$Nutritional_Desktop$");
}
#btn3 {
background-image: url("https://www.mcdonalds.com/is/image/content/dam/ca/nfl/web/nutrition/products/nutrition/en/mcdonalds-hamburger.png?$Nutritional_Desktop$");
}
#btn4 {
background-image: url("https://www.mcdonalds.com/is/image/content/dam/ca/nfl/web/nutrition/products/nutrition/en/mcdonalds-6-chicken-mcnuggets.png?$Nutritional_Desktop$");
}
#btn5 {
background-image: url("https://www.mcdonalds.com/is/image/content/dam/ca/nfl/web/nutrition/products/nutrition/en/mcdonalds-crispy-caesar-chicken-mcwrap.png?$Nutritional_Desktop$");
}
#btn6 {
background-image: url("https://www.mcdonalds.com/is/image/content/dam/ca/nfl/web/nutrition/products/nutrition/en/mcdonalds-fries-medium.png?$Nutritional_Desktop$");
}
#btn7 {
background-image: url("https://www.mcdonalds.com/is/image/content/dam/ca/nfl/web/nutrition/products/nutrition/en/mcdonalds-blueberry-muffin-hero.png?$Nutritional_Desktop$");
}
#btn8 {
background-image: url("https://www.mcdonalds.com/is/image/content/dam/ca/nfl/web/nutrition/products/nutrition/en/mcdonalds-coca-cola.png?$Nutritional_Desktop$");
}
#btn9 {
background-image: url("https://www.mcdonalds.com/is/image/content/dam/ca/nfl/web/nutrition/products/nutrition/en/mcdonalds-side-caesar-salad.png?$Nutritional_Desktop$");
}
#btn10 {
background-image: url("https://www.mcdonalds.com/is/image/content/dam/ca/nfl/web/nutrition/products/nutrition/en/mcdonalds-egg-mcmuffin.png?$Nutritional_Desktop$");
}
#btn11 {
background-image: url("https://www.mcdonalds.com/is/image/content/dam/ca/nfl/web/nutrition/products/nutrition/en/mcdonalds-filet-o-fish.png?$Nutritional_Desktop$");
}
#btn12 {
background-image: url("https://www.mcdonalds.com/is/image/content/dam/ca/nfl/web/nutrition/products/nutrition/en/mcdonalds-quarter-pounder-cheese.png?$Nutritional_Desktop$");
}
#btn13 {
background-image: url("https://www.mcdonalds.com/is/image/content/dam/ca/nfl/web/nutrition/products/nutrition/en/mcdonalds-baked-apple-pie.png?$Nutritional_Desktop$");
}
#btn14 {
background-image: url("https://www.mcdonalds.com/is/image/content/dam/ca/nfl/web/nutrition/products/nutrition/en/mcdonalds-hot-fudge-sundae.png?$Nutritional_Desktop$")
}
#logo {
height: 60px;
width: 60px;
border: 0px solid rgba(40, 40, 53, 0.89);
box-shadow: 2px 2px 9px black;
}
#btnClearEntry {
background: rgba(40, 40, 53, 0.79);
border: 1px solid white;
color: white;
width: 62px;
height: 62px;
box-shadow: 2px 2px 7px black;
}
#btnplus {
color: white;
background: red;
border: 1px solid silver;
font-size: 18px;
width: 60px;
height: 60px;
box-shadow: 2px 2px 7px black;
}
#btnminus {
color: white;
background: rgba(255, 223, 15, 1);
border: 1px solid silver;
font-size: 30px;
width: 60px;
height: 60px;
box-shadow: 2px 2px 7px black;
}
#logo {
border: 1px solid white;
}
.calculator {
box-shadow: 2px 2px 10 px rgba(0, 0, 0, 0.648);
padding: 5px;
}
button:hover {
position: relative;
}
button[aria-label]:hover:after {
content: attr(aria-label);
padding: 4px 8px;
position: absolute;
left: 0;
top: 100%;
white-space: nowrap;
z-index: 20;
background: red;
color: yellow;
font-family: 'Raleway';
}
<head>
<link rel="stylesheet" type="text/css" href="default.css">
<link href="https://fonts.googleapis.com/css?family=Raleway&display=swap" rel="stylesheet">
<script type="text/javascript" src="calc.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<div class="main">
<div class="calculator">
<table>
<tr>
<td colspan="4">
<div style="color:white; font-family:sans-serif;font-size:20px;" id="txtResult" readonly="readonly"></div>
</td>
</tr>
<tr>
<td colspan="4">
<div style="color:white; font-family:sans-serif;font-size:16px;" id="txtResultItem"></div>
</td>
</tr>
<tbody>
</tbody>
</table>
</div>
</div>
</body>
You can replace all of these functions with this;
function test(elementId){
var summe = document.getElementById("txtResult").innerHTML ;
var x = document.getElementById(elementId).getAttribute("value");
document.getElementById("txtResultItem").innerHTML = x;
}
and then in your onClick handlers do something like
test('test')
test('test2')
test('test3')
and just pass in the id of the element as a string value to the function.
So, only variable among your functions is the id of the element from which you are getting x, you can write a function that accepts this variable as parameter and pass it to the function when calling it
function test(id){
var summe = document.getElementById("txtResult").innerHTML ;
var x = document.getElementById(id).getAttribute("value");
document.getElementById("txtResultItem").innerHTML = x;
}
<button onclick="test('test')">
Try this , add an argument for a function with numerics as 1,2,3..etc and pass that value and append the same in the document.getElementById("test"+itemValue).getAttribute("value") value.
Dynamically pass the inputs from the click event.
function test(itemValue){
var summe = document.getElementById("txtResult").innerHTML ;
var x=document.getElementById("test"+itemValue).getAttribute("value");
document.getElementById("txtResultItem").innerHTML=x;
}
Check below snipet
function test(){
thisObj=event.target;
var summe = document.getElementById("txtResult").innerHTML ;
var x=thisObj.getAttribute("value");
document.getElementById("txtResultItem").innerHTML=x;
}
<div id="txtResult"></div>
<input type="button" value="1" onclick="test()" />
<input type="button" value="2" onclick="test()" />
<input type="button" value="3" onclick="test()" />
<div id="txtResultItem"></div>
You can use this reference at onclick event handler (without passing extra arguments like test3 etc)
function test(item){
console.log(item.value)
}
<div><button value="1" onclick="test(this)">1</button></div>
<div><button value="2" onclick="test(this)">2</button></div>
<div><button value="3" onclick="test(this)">3</button></div>
Or you can use event.target:
function test(){
var item = event.target;
console.log(item.value)
}
<div><button value="1" onclick="test()">1</button></div>
<div><button value="2" onclick="test()">2</button></div>
<div><button value="3" onclick="test()">3</button></div>
You can use a single function that passes in the id of the element you want to use as var x.
Javascript
function test_reuse(elid){
var summe = document.getElementById("txtResult").innerHTML ;
var x=document.getElementById(elid).getAttribute("value");
document.getElementById("txtResultItem").innerHTML=x;
}
Sample HTML element
<td id="test3" value="200"><button onclick="test_reuse('test3')" id="btn3" aria-label="Hamburger"></button></td>
You could have your buttons fire an event upon click, and given the event you can get the ID of the corresponding button and update the UI accordingly.
<td id="test3" value="200"><button onclick="test_general(event)" id="btn3" aria-label="Hamburger"></button></td>
....
//JS
function test_general(event){
var button_id = event.target.id
// DO SOMETHING NOW THAT YOU HAVE THE ID OF BUTTON
console.log(button_id)
}
Few pointers:
Having id on element can help you uniquely identify but the it becomes huge to keep track of. Use classes or composite selectors to achieve this.
Adding onClick on markup will pose a security threat as anyone can inspect your element and see whats going on. Using .addEventListener will encapsulate the code and keeps markup clean.
Having 1-1 mapping of button/ handler is an overkill. You can add any meta information as a part of data- tag and can be retrieved to process.
Following is the updated code: https://codepen.io/TBD007/pen/zYxgWbv which addresses above pointers.
Please note, I added data-number attribute in HTML

"float: left" div gets pushed down on input focus

I have the following form for lyrics upload. I've changed the design of the form a little bit, and now facing a weird problem.
I've created a fake-datalist using JS. On input focus, a fake-datalist (an ul element) is appended next to the input element. Its position is set to absolute so it shouldn't disrupt the flow of the document when it appears. However, it does. I can't seem to identify the problem. Once the datalist appears, the div next to the table gets pushed down. Table width isn't changing when the datalist appears, so it's not squizing the div and pushing it down.
Code Pen
var artists = [{"artist":"3 Doors Down"},{"artist":"5 Seconds of Summer"},{"artist":"Adele"},{"artist":"Alicia Keys"},{"artist":"Amanda Abizaid"},{"artist":"Avril Lavigne"}];
var albums = [{"album":"The Better Life","year":"2000","cover":"3_doors_down_2000_the_better_life.jpg"},{"album":"Away from the Sun","year":"2002","cover":"3_doors_down_2002_away_from_the_sun.jpg"},{"album":"Seventeen Days","year":"2005","cover":"3_doors_down_2005_seventeen_days.jpg"},{"album":"3 Doors Down","year":"2008","cover":"3_doors_down_2008_3_doors_down.jpg"},{"album":"Time of My Life","year":"2011","cover":"3_doors_down_2011_time_of_my_life.jpg"}];
var songs = [{"song":"Kryptonite","track_no":"1"},{"song":"Duck and Run","track_no":"3"},{"song":"Be Like That","track_no":"5"},{"song":"So I Need You","track_no":"11"}];
function datalist(element) {
return new datalist.prototype.init(element);
}
datalist.prototype = {
init: function(element) {
if (!element) {
this.element = document.createElement("ul");
this.element.classList.add("datalist");;
this.hide();
} else {
this.element = element;
}
},
update: function(queryElement) {
this.clear();
var lookUpArray = queryElement.name + "s";
var results = this.search(window[lookUpArray], queryElement.value, queryElement.name);
for (var i = 0; i < results.length; i++) {
var li = document.createElement("li");
var value = results[i][queryElement.name];
switch (queryElement.name) {
case "album":
li.setAttribute("data-year", results[i].year);
break;
case "song":
li.setAttribute("data-track_no", results[i].track_no);
break;
}
if (queryElement.value != "") {
var re = new RegExp(queryElement.value, "gi");
value = value.replace(re, "<span class=\"highlight\">" + "$&" + "</span>");
}
li.innerHTML = value;
this.element.appendChild(li);
}
return results.length;
},
search: function(lookUpArray, string, queryType) {
var results = [];
for (var i = 0; i < lookUpArray.length; i++) {
if (lookUpArray[i][queryType].toLowerCase().search(string.toLowerCase()) != -1) {
results.push(lookUpArray[i]);
}
}
return results;
},
clear: function() {
this.element.innerHTML = "";
},
hide: function() {
this.element.style.display = "none";
},
show: function() {
this.element.style.display = "";
},
remove: function() {
this.element.parentElement.removeChild(this.element);
},
for: function(sibling) {
sibling.parentElement.appendChild(this.element);
this.hide();
},
};
datalist.prototype.init.prototype = datalist.prototype;
var lastVisitedInput = null;
$("#lyrics-form").on("focus", "input.datalist-input", function() {
if (this.parentElement.children.length == 1) {
this.parentElement.appendChild(datalist().element);
}
if (lastVisitedInput) {
datalist(lastVisitedInput.nextElementSibling).hide();
}
lastVisitedInput = this;
if (datalist(this.nextElementSibling).update(this)) {
datalist(this.nextElementSibling).show();
} else {
datalist(this.nextElementSibling).hide();
}
});
$(document).on("click", function(e) {
if (lastVisitedInput) {
var exceptions = getExceptions(lastVisitedInput);
if (!contains(exceptions, e.target)) {
datalist(lastVisitedInput.nextElementSibling).remove();
lastVisitedInput = null;
}
}
});
$("#lyrics-form").on("input", "input.datalist-input", function() {
if (datalist(this.nextElementSibling).update(this)) {
datalist(this.nextElementSibling).show();
} else {
datalist(this.nextElementSibling).hide();
}
});
$("#lyrics-form").on("click", "li", function() {
this.parentElement.previousElementSibling.value = this.innerText;
$(this.parentElement.previousElementSibling).trigger("input");
});
function getRecord(input) {
var lookUpArray = window[input.name + "s"];
for (var i = 0; i < lookUpArray.length; i++) {
if (input.value == lookUpArray[i][input.name]) {
return lookUpArray[i];
}
}
return false;
}
function getExceptions(input) {
var exceptions = [
input,
input.nextElementSibling,
];
for (var i = 0; i < input.nextElementSibling.children.length; i++) {
exceptions.push(input.nextElementSibling.children[i]);
}
return exceptions;
}
function contains(array, item) {
for (var i = 0; i < array.length; i++) {
if (array[i] === item) {
return true;
}
}
return false;
}
* { margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline; } *, *:before, *:after { box-sizing: inherit; } body { line-height: 1.5; font-family: sans-serif; } input[type="button"], input[type="submit"] { cursor: pointer; } textarea, input[type="text"], input[type="search"], input[type="number"], input[type="password"] { border: 1px solid rgba(0,0,0,.2); padding: 4px; margin: 1px; } table { border-collapse: collapse; border-spacing: 0; }
body {
background-color: rgb(230, 230, 230);
font-family: Arial, sans-serif;
font-size: 14px;
color: rgba(0, 0, 0, .8);
box-sizing: border-box;
}
#main {
height: 500px;
background: white;
box-shadow: 0 0 2px rgba(0, 0, 0, .1), 0 2px 2px rgba(0, 0, 0, .1);
margin: 20px auto;
display: table;
padding: 20px;
}
#songInput {
overflow: auto;
}
#songTable td {
position: relative;
}
#songTable,
#coverDiv {
float: left;
}
#coverDiv {
margin-left: 20px;
}
#artist,
#album,
#song {
width: 250px;
}
#artist {
width: 300px;
width: 100%;
}
#year,
#track_no {
width: 70px;
}
#songTable td {
padding-bottom: 20px;
}
#songTable td:first-child {
padding-right: 10px;
}
#songTable .int-input {
padding-left: 20px;
padding-right: 10px;
}
#coverDiv > * {
display: block;
}
#coverDiv img {
width: 137px;
height: 137px;
border: 1px solid rgba(0, 0, 0, .2);
margin: 1px;
}
#coverUpload {
margin: 1px;
margin-top: 10px;
width: 250px;
}
#lyricsBox {
width: 100%;
height: 400px;
margin-top: 15px;
}
#submit {
width: 100%;
margin-top: 15px;
}
.datalist {
border: 1px solid silver;
box-shadow: 0 2px 5px rgba(0, 0, 0, .5);
position: absolute;
top: 32px;
left: 1px;
background: white;
padding: 5px;
max-height: 195px;
width: 180px;
width: 100%;
overflow-y: scroll;
z-index: 1000;
}
.datalist li {
padding: 2px 5px;
cursor: default;
}
.datalist li:hover {
background: rgba(0, 0, 0, .05);
color: black;
}
.datalist .highlight {
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="main">
<form action="addlyrics.php" id="lyrics-form" method="post" autocomplete="off" enctype="multipart/form-data">
<div id="songInput">
<table id="songTable">
<tr>
<td>Artist</td>
<td colspan="3">
<input type="search" name="artist" id="artist" class="datalist-input" placeholder="Artist" required />
</td>
</tr>
<tr>
<td>Album</td>
<td>
<input type="search" name="album" id="album" class="datalist-input" placeholder="Album" required />
</td>
<td class="int-input">Year</td>
<td>
<input type="number" name="year" id="year" class="input-num" placeholder="Year" required />
</td>
</tr>
<tr>
<td>Song</td>
<td>
<input type="search" name="song" id="song" class="datalist-input" placeholder="Name" required />
</td>
<td class="int-input">#</td>
<td>
<input type="number" name="track_no" id="track_no" class="input-num" placeholder="ID" required />
</td>
</tr>
</table>
<div id="coverDiv">
<img src="covers/blank.gif" id="cover" />
<input type="file" name="cover" id="coverUpload" accept="image/*" />
</div>
</div>
<textarea name="lyrics" placeholder="Lyrics" id="lyricsBox" /></textarea>
<input type="submit" id="submit" class="button" />
</form>
</div>
Removing overflow: auto; from #songInput, the parent element of the table and the div, solved the problem. Although, I don't understand why overflow: auto; on the parent would push the div down. Dynamically added ul.datalist's position is set to absolute, and when it appears, the only thing it might do is extend the height of the table, which shouldn't effect the div at the right.

Any error in my JQuery code? The lottory can only move one step after click start

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>lottery</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
.container{
position: absolute;
top: 0;
left:0;
width: 100%;
height: 100%;
background: #333;
}
.nine{
position: relative;
margin: 20px auto;
height: 300px;
width: 300px;
}
.items{
background: #eee;
border-radius: 50px;
width: 80px;
height: 80px;
text-align: center;
}
.active{
background-color: red;
color: #fff;
box-shadow: 0 0 16px rgba(33,154,219,.8), 0 1px 2px rgba(0,0,0,.2) ;
}
.btn-start{
background-color: #3385ff;
cursor: pointer;
color: #fff
}
</style>
</head>
<body>
<div class="container">
<table class="nine">
<tbody>
<tr>
<td class="items" data-index="1">1</td>
<td class="items" data-index="2">2</td>
<td class="items" data-index="3">3</td>
</tr>
<tr>
<td class="items active" data-index="8">8</td>
<td class="items btn-start" data-index="9">start</td>
<td class="items" data-index="4">4</td>
</tr>
<tr>
<td class="items" data-index="7">7</td>
<td class="items" data-index="6">6</td>
<td class="items" data-index="5">5</td>
</tr>
</tbody>
</table>
</div>
<script type="text/javascript" src="../js/jquery-2.1.4.min.js"></script>
<script type="text/javascript">
var gRunning = false;
$(".btn-start").click(function(e){
if(gRunning){
return;
}
gRunning = true;
next(parseInt(Math.random()*50));
});
function next(time){
var activeItem = $(".items.active"),
activeIndex = activeItem.data("index"),
max = $(".items").length -1,
nextTime = time + 5* time/50,
nextIndex = 1,
nextItem = null;
if (activeIndex = max) {
nextIndex = 1;
}
else{
nextIndex = activeIndex + 1;
}
activeItem.removeClass("active");
nextItem = $(".items[data-index="+nextIndex+"]").addClass("active");
if (time>800) {
gRunning = false;
var info = nextItem.text();
alert("Congrats, you got "+ info);
}
else{
window.setTimeout(function(){
next(nextTime);
},nextTime);
}
}
</script>
</body>
</html>
This code stop at data-index:1 after I click the "start" button,then after a while, the alert box will pop up,"congrants, you got 1". any error in the code cause it didn't move forward??? It should be roll several circles then slow down then stop and pop out the alert box.
if (activeIndex = max) {
This is setting activeIndex to max every time, so nextIndex will always be 1.
Use
if (activeIndex == max) {
This is assignment, not comparison:
if (activeIndex = max)
Use ==
if (activeIndex == max)

Categories

Resources