Connect two div by line with jquery function - javascript

I have two groups of quiz.
The first group is correct but the second group is not showing the line between two points.
The users click the point on the left and click the point on the right, then JavaScript creates a "canvas" line from the first element to the second element.
(I apologise for my english, it's my second language)
(function($) {
$.fn.connect = function(param) {
var _canvas;
var _ctx;
var _lines = new Array(); //This array will store all lines (option)
var _me = this;
var _parent = param || document;
var _lengthLines = $(_parent + ' .group1 .node').length;
var _selectFirst = null;
//Initialize Canvas object
_canvas = $('<canvas/>')
.attr('width', $(_me).width())
.attr('height', $(_me).height())
.css('position', 'absolute');
$(_parent).prepend(_canvas);
//$(_canvas).insertBefore(_parent);
this.drawLine = function(option) {
//It will push line to array.
_lines.push(option);
this.connect(option);
};
this.drawAllLine = function(option) {
/*Mandatory Fields------------------
left_selector = '.class',
data_attribute = 'data-right',
*/
if (option.left_selector != '' && typeof option.left_selector !== 'undefined' && $(option.left_selector).length > 0) {
$(option.left_selector).each(function(index) {
var option2 = new Object();
$.extend(option2, option);
option2.left_node = $(this).attr('id');
option2.right_node = $(this).data(option.data_attribute);
if (option2.right_node != '' && typeof option2.right_node !== 'undefined') {
_me.drawLine(option2);
}
});
}
};
//This Function is used to connect two different div with a dotted line.
this.connect = function(option) {
_ctx = _canvas[0].getContext('2d');
//
_ctx.beginPath();
try {
var _color;
var _dash;
var _left = new Object(); //This will store _left elements offset
var _right = new Object(); //This will store _right elements offset
var _error = (option.error == 'show') || false;
/*
option = {
left_node - Left Element by ID - Mandatory
right_node - Right Element ID - Mandatory
status - accepted, rejected, modified, (none) - Optional
style - (dashed), solid, dotted - Optional
horizantal_gap - (0), Horizantal Gap from original point
error - show, (hide) - To show error or not
width - (2) - Width of the line
}
*/
if (option.left_node != '' && typeof option.left_node !== 'undefined' && option.right_node != '' && typeof option.right_node !== 'undefined' && $(option.left_node).length > 0 && $(option.right_node).length > 0) {
//To decide colour of the line
switch (option.status) {
case 'accepted':
_color = '#0969a2';
break;
case 'rejected':
_color = '#e7005d';
break;
case 'modified':
_color = '#bfb230';
break;
case 'none':
_color = 'grey';
break;
default:
_color = 'grey';
break;
}
//To decide style of the line. dotted or solid
switch (option.style) {
case 'dashed':
_dash = [4, 2];
break;
case 'solid':
_dash = [0, 0];
break;
case 'dotted':
_dash = [4, 2];
break;
default:
_dash = [4, 2];
break;
}
/*
console.log($(option.left_node));
$(option.left_node)
$(option.right_node).data('connect',true);
*/
//If left_node is actually right side, following code will switch elements.
$(option.right_node).each(function(index, value) {
_left_node = $(option.left_node);
_right_node = $(value);
_left_node.attr('data-connect', true);
_right_node.attr('data-connect', true);
if (_left_node.offset().left >= _right_node.offset().left) {
_tmp = _left_node
_left_node = _right_node
_right_node = _tmp;
}
//Get Left point and Right Point
_left.x = _left_node.offset().left + _left_node.outerWidth();
_left.y = _left_node.offset().top + (_left_node.outerHeight() / 2);
_right.x = _right_node.offset().left;
_right.y = _right_node.offset().top + (_right_node.outerHeight() / 2);
//Create a group
//var g = _canvas.group({strokeWidth: 2, strokeDashArray:_dash});
//Draw Line
var _gap = option.horizantal_gap || 0;
_ctx.moveTo(_left.x, _left.y);
if (_gap != 0) {
_ctx.lineTo(_left.x + _gap, _left.y);
_ctx.lineTo(_right.x - _gap, _right.y);
}
_ctx.lineTo(_right.x, _right.y);
if (!_ctx.setLineDash) {
_ctx.setLineDash = function() {}
} else {
_ctx.setLineDash(_dash);
}
_ctx.lineWidth = option.width || 2;
_ctx.strokeStyle = _color;
_ctx.stroke();
});
//option.resize = option.resize || false;
} else {
if (_error) alert('Mandatory Fields are missing or incorrect');
}
} catch (err) {
if (_error) alert('Mandatory Fields are missing or incorrect');
}
//console.log(_canvas);
};
//It will redraw all line when screen resizes
$(window).resize(function() {
console.log(_me);
_me.redrawLines();
});
$(_parent + ' .group1 .node span').click(function() {
//console.log($(this).attr('data-connect'));
//[data-use="false"]
_this = this;
if ($(_this).attr('data-connect') != 'true' && $(_this).attr('data-use') == 'false') {
$(_parent + ' .group1 .node span').attr('data-use', 'false');
$(_this).attr('data-use', 'true');
_selectFirst = _this;
} else if ($(_this).attr('data-connect') == 'true') {
//console.log($(this).attr('data-id'));
//console.log(entry);
_lines.forEach(function(entry, index) {
if ($(_this).attr('data-id') == entry.id_left) {
$(entry.left_node).attr('data-use', 'false').attr('data-connect', 'false')
$(entry.right_node).attr('data-use', 'false').attr('data-connect', 'false')
_lines.splice(index, 1)
}
});
_me.redrawLines();
}
});
$(_parent + ' .group2 .node span[data-use="false"]').click(function() {
if ($(_parent + ' .group1 .node span[data-use="true"]').length == 1 && _selectFirst != null) {
if ($(this).attr('data-connect') != 'true') {
_me.drawLine({
id_left: $(_selectFirst).attr('data-id'),
id_right: $(this).attr('data-id'),
left_node: _selectFirst,
right_node: this,
horizantal_gap: 10,
error: 'show',
width: 1,
status: 'accepted'
});
$(_selectFirst).attr('data-use', 'false');
$(_selectFirst).attr('data-connect', 'true');
$(this).attr('data-use', 'false');
$(this).attr('data-connect', 'true');
}
}
});
this.redrawLines = function() {
_ctx.clearRect(0, 0, $(_me).width(), $(_me).height());
_lines.forEach(function(entry) {
entry.resize = true;
_me.connect(entry);
});
};
return this;
};
}(jQuery));
.clearfix {
clear: both;
}
body {
padding: 0px;
margin: 0px;
}
.nodes {
width: 500px
}
.node {
width: 100px;
background: #ddd;
color: #fff;
margin-bottom: 10px;
}
.group1 span {
background: #666;
border-radius: 50%;
width: 10px;
height: 10px;
margin-top: 5px;
}
.group2 span {
border: 1px solid #666;
border-radius: 50%;
width: 10px;
height: 10px;
margin-top: 5px;
}
.node span:hover {
background: #ff0000;
cursor: pointer;
}
.group1 {
float: left;
}
.group2 {
float: right;
}
.group2 .node span {
float: left;
position: relative;
left: -15px;
}
.group1 .node span {
float: right;
position: relative;
right: -15px;
}
.node span[data-connect=true] {
background: #ff00ff !important;
}
.node span[data-use=true] {
background: #ff0000 !important;
}
<div id="parentNodes_11">
<div class="nodes">
<div class="group1">
<div class="node">1<span class="node1" data-connect="false" data-id="0" data-use="false"></span></div>
<div class="node">2 <span class="node2" data-connect="false" data-id="1" data-use="false"></span></div>
<div class="node">3 <span class="node3" data-connect="false" data-id="2" data-use="false"></span></div>
</div>
<div class="group2">
<div class="node">A <span class="node4" data-connect="false" data-id="0" data-use="false"></span></div>
<div class="node">B <span class="node5" data-connect="false" data-id="1" data-use="false"></span></div>
<div class="node">C <span class="node6" data-connect="false" data-id="2" data-use="false"></span></div>
</div>
<div class="clearfix"></div>
</div>
</div>
<br>
<div id="parentNodes_12">
<div class="nodes">
<div class="group1">
<div class="node">1<span class="node1" data-connect="false" data-id="0" data-use="false"></span></div>
<div class="node">2 <span class="node2" data-connect="false" data-id="1" data-use="false"></span></div>
<div class="node">3 <span class="node3" data-connect="false" data-id="2" data-use="false"></span></div>
</div>
<div class="group2">
<div class="node">A <span class="node4" data-connect="false" data-id="0" data-use="false"></span></div>
<div class="node">B <span class="node5" data-connect="false" data-id="1" data-use="false"></span></div>
<div class="node">C <span class="node6" data-connect="false" data-id="2" data-use="false"></span></div>
</div>
<div class="clearfix"></div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#parentNodes_11 .nodes').connect('#parentNodes_11');
$('#parentNodes_12 .nodes').connect('#parentNodes_12');
});
</script>

This is due to the use of absolute coordinates for lines instead of relative ones, so your lines doesn't fit on the canvas.
You can just do the parent offset adjustment and it will work like this:
(function($) {
$.fn.connect = function(param) {
var _canvas;
var _ctx;
var _lines = new Array(); //This array will store all lines (option)
var _me = this;
var _parent = param || document;
var _lengthLines = $(_parent + ' .group1 .node').length;
var _selectFirst = null;
//Initialize Canvas object
_canvas = $('<canvas/>')
.attr('width', $(_me).width())
.attr('height', $(_me).height())
.css('position', 'absolute');
$(_parent).prepend(_canvas);
//$(_canvas).insertBefore(_parent);
this.drawLine = function(option) {
//It will push line to array.
_lines.push(option);
this.connect(option);
};
this.drawAllLine = function(option) {
/*Mandatory Fields------------------
left_selector = '.class',
data_attribute = 'data-right',
*/
if (option.left_selector != '' && typeof option.left_selector !== 'undefined' && $(option.left_selector).length > 0) {
$(option.left_selector).each(function(index) {
var option2 = new Object();
$.extend(option2, option);
option2.left_node = $(this).attr('id');
option2.right_node = $(this).data(option.data_attribute);
if (option2.right_node != '' && typeof option2.right_node !== 'undefined') {
_me.drawLine(option2);
}
});
}
};
//This Function is used to connect two different div with a dotted line.
this.connect = function(option) {
_ctx = _canvas[0].getContext('2d');
//
_ctx.beginPath();
try {
var _color;
var _dash;
var _left = new Object(); //This will store _left elements offset
var _right = new Object(); //This will store _right elements offset
var _error = (option.error == 'show') || false;
/*
option = {
left_node - Left Element by ID - Mandatory
right_node - Right Element ID - Mandatory
status - accepted, rejected, modified, (none) - Optional
style - (dashed), solid, dotted - Optional
horizantal_gap - (0), Horizantal Gap from original point
error - show, (hide) - To show error or not
width - (2) - Width of the line
}
*/
if (option.left_node != '' && typeof option.left_node !== 'undefined' && option.right_node != '' && typeof option.right_node !== 'undefined' && $(option.left_node).length > 0 && $(option.right_node).length > 0) {
//To decide colour of the line
switch (option.status) {
case 'accepted':
_color = '#0969a2';
break;
case 'rejected':
_color = '#e7005d';
break;
case 'modified':
_color = '#bfb230';
break;
case 'none':
_color = 'grey';
break;
default:
_color = 'grey';
break;
}
//To decide style of the line. dotted or solid
switch (option.style) {
case 'dashed':
_dash = [4, 2];
break;
case 'solid':
_dash = [0, 0];
break;
case 'dotted':
_dash = [4, 2];
break;
default:
_dash = [4, 2];
break;
}
/*
console.log($(option.left_node));
$(option.left_node)
$(option.right_node).data('connect',true);
*/
//If left_node is actually right side, following code will switch elements.
$(option.right_node).each(function(index, value) {
_left_node = $(option.left_node);
_right_node = $(value);
_left_node.attr('data-connect', true);
_right_node.attr('data-connect', true);
if (_left_node.offset().left >= _right_node.offset().left) {
_tmp = _left_node
_left_node = _right_node
_right_node = _tmp;
}
//Get Left point and Right Point
_left.x = _left_node.offset().left + _left_node.outerWidth();
_left.y = _left_node.offset().top + (_left_node.outerHeight() / 2) - _left_node.parents('.nodes').offset().top;
_right.x = _right_node.offset().left;
_right.y = _right_node.offset().top + (_right_node.outerHeight() / 2) - _right_node.parents('.nodes').offset().top;
//Create a group
//var g = _canvas.group({strokeWidth: 2, strokeDashArray:_dash});
//Draw Line
var _gap = option.horizantal_gap || 0;
_ctx.moveTo(_left.x, _left.y);
if (_gap != 0) {
_ctx.lineTo(_left.x + _gap, _left.y);
_ctx.lineTo(_right.x - _gap, _right.y);
}
_ctx.lineTo(_right.x, _right.y);
if (!_ctx.setLineDash) {
_ctx.setLineDash = function() {}
} else {
_ctx.setLineDash(_dash);
}
_ctx.lineWidth = option.width || 2;
_ctx.strokeStyle = _color;
_ctx.stroke();
});
//option.resize = option.resize || false;
} else {
if (_error) alert('Mandatory Fields are missing or incorrect');
}
} catch (err) {
if (_error) alert('Mandatory Fields are missing or incorrect');
}
//console.log(_canvas);
};
//It will redraw all line when screen resizes
$(window).resize(function() {
console.log(_me);
_me.redrawLines();
});
$(_parent + ' .group1 .node span').click(function() {
//console.log($(this).attr('data-connect'));
//[data-use="false"]
_this = this;
if ($(_this).attr('data-connect') != 'true' && $(_this).attr('data-use') == 'false') {
$(_parent + ' .group1 .node span').attr('data-use', 'false');
$(_this).attr('data-use', 'true');
_selectFirst = _this;
} else if ($(_this).attr('data-connect') == 'true') {
//console.log($(this).attr('data-id'));
//console.log(entry);
_lines.forEach(function(entry, index) {
if ($(_this).attr('data-id') == entry.id_left) {
$(entry.left_node).attr('data-use', 'false').attr('data-connect', 'false')
$(entry.right_node).attr('data-use', 'false').attr('data-connect', 'false')
_lines.splice(index, 1)
}
});
_me.redrawLines();
}
});
$(_parent + ' .group2 .node span[data-use="false"]').click(function() {
if ($(_parent + ' .group1 .node span[data-use="true"]').length == 1 && _selectFirst != null) {
if ($(this).attr('data-connect') != 'true') {
_me.drawLine({
id_left: $(_selectFirst).attr('data-id'),
id_right: $(this).attr('data-id'),
left_node: _selectFirst,
right_node: this,
horizantal_gap: 10,
error: 'show',
width: 1,
status: 'accepted'
});
$(_selectFirst).attr('data-use', 'false');
$(_selectFirst).attr('data-connect', 'true');
$(this).attr('data-use', 'false');
$(this).attr('data-connect', 'true');
}
}
});
this.redrawLines = function() {
_ctx.clearRect(0, 0, $(_me).width(), $(_me).height());
_lines.forEach(function(entry) {
entry.resize = true;
_me.connect(entry);
});
};
return this;
};
}(jQuery));
.clearfix {
clear: both;
}
body {
padding: 0px;
margin: 0px;
}
.nodes {
width: 500px
}
.node {
width: 100px;
background: #ddd;
color: #fff;
margin-bottom: 10px;
}
.group1 span {
background: #666;
border-radius: 50%;
width: 10px;
height: 10px;
margin-top: 5px;
}
.group2 span {
border: 1px solid #666;
border-radius: 50%;
width: 10px;
height: 10px;
margin-top: 5px;
}
.node span:hover {
background: #ff0000;
cursor: pointer;
}
.group1 {
float: left;
}
.group2 {
float: right;
}
.group2 .node span {
float: left;
position: relative;
left: -15px;
}
.group1 .node span {
float: right;
position: relative;
right: -15px;
}
.node span[data-connect=true] {
background: #ff00ff !important;
}
.node span[data-use=true] {
background: #ff0000 !important;
}
<div id="parentNodes_11">
<div class="nodes">
<div class="group1">
<div class="node">1<span class="node1" data-connect="false" data-id="0" data-use="false"></span></div>
<div class="node">2 <span class="node2" data-connect="false" data-id="1" data-use="false"></span></div>
<div class="node">3 <span class="node3" data-connect="false" data-id="2" data-use="false"></span></div>
</div>
<div class="group2">
<div class="node">A <span class="node4" data-connect="false" data-id="0" data-use="false"></span></div>
<div class="node">B <span class="node5" data-connect="false" data-id="1" data-use="false"></span></div>
<div class="node">C <span class="node6" data-connect="false" data-id="2" data-use="false"></span></div>
</div>
<div class="clearfix"></div>
</div>
</div>
<br>
<div id="parentNodes_12">
<div class="nodes">
<div class="group1">
<div class="node">1<span class="node1" data-connect="false" data-id="0" data-use="false"></span></div>
<div class="node">2 <span class="node2" data-connect="false" data-id="1" data-use="false"></span></div>
<div class="node">3 <span class="node3" data-connect="false" data-id="2" data-use="false"></span></div>
</div>
<div class="group2">
<div class="node">A <span class="node4" data-connect="false" data-id="0" data-use="false"></span></div>
<div class="node">B <span class="node5" data-connect="false" data-id="1" data-use="false"></span></div>
<div class="node">C <span class="node6" data-connect="false" data-id="2" data-use="false"></span></div>
</div>
<div class="clearfix"></div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#parentNodes_11 .nodes').connect('#parentNodes_11');
$('#parentNodes_12 .nodes').connect('#parentNodes_12');
});
</script>

Related

Calculator display

If you calculate (45 - 5), the calculator will return 40 but if you click on the 5 it will concatenate 40 and 5 and it will make '405', I wanted the calculator to clear the display when I press the 5 to start a new operation so that the user doesn't have to manually clear the calculator with AC, I know I need to program a method that checks if an operation has been completed or not but I can't get it to work, can you help me? what I need to do? what code do i need to write to make this work? my github: https://github.com/JackHeroes/Calculator
class CalcController{
constructor(){
this._timeEl = document.querySelector('#time');
this._dateEl = document.querySelector('#date');
this._historicEl = document.querySelector('#historic');
this._displayCalcEl = document.querySelector('#display');
this._audio = new Audio('/audio/click.wav');
this._audioOnOff = false;
this._currentDate;
this._locale = 'pt-BR';
this._operation = [];
this._readyToClear = false;
this._lastNumber = '';
this._lastOperator = '';
this.initialize();
this.initButtonsEvents();
this.initKeyboard();
}
initialize(){
this.playAudio(true);
this.setDisplayDateTime();
setInterval(() =>{
this.setDisplayDateTime();
}, 1000);
this.setLastNumberToDisplay();
document.querySelector('#audio').addEventListener('click', e =>{
this.toggleAudio();
})
let icon = document.querySelector('#audio');
icon.addEventListener('click', e =>{
if(icon.classList.contains('bi-volume-up-fill')){
icon.classList.remove('bi-volume-up-fill');
icon.classList.add('bi-volume-mute-fill');
} else{
icon.classList.remove('bi-volume-mute-fill');
icon.classList.add('bi-volume-up-fill');
}
});
}
toggleAudio(){
this._audioOnOff = !this._audioOnOff;
}
playAudio(){
if(this._audioOnOff){
this._audio.currentTime = 0;
this._audio.play();
}
}
initKeyboard(){
document.addEventListener('keyup' , e =>{
this.playAudio();
switch(e.key){
case 'Escape':
this.clearAll();
break;
case 'Backspace':
this.clearEntry();
break;
case '+':
case '-':
case '*':
case '/':
this.addOperation(e.key);
break;
case 'Enter':
case '=':
this.calc();
break;
case ',':
case '.':
this.addDot();
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
this.addOperation(parseInt(e.key));
break;
}
});
}
setDisplayDateTime(){
this.displayTime = this.currentDate.toLocaleTimeString(this._locale)
this.displayDate = this.currentDate.toLocaleDateString(this._locale, {day: '2-digit', month: 'long', year: 'numeric'})
}
setLastNumberToDisplay(){
let lastNumber = this.getLastItem(false);
if(!lastNumber) lastNumber = [0];
this.displayCalc = lastNumber;
}
addEventListenerAll(element, events, fn){
events.split(' ').forEach(event =>{
element.addEventListener(event, fn, false);
});
}
clearAll(value){
let alreadyCalled = false;
if (!alreadyCalled) {
this._operation = [];
this._lastNumber = '';
this._lastOperator = '';
this.setLastNumberToDisplay();
if(value) this.addOperation(value);
this._readyToClear = false;
alreadyCalled = true;
}
}
clearEntry(){
this._operation.pop();
this.setLastNumberToDisplay();
}
ClearLast(){
}
getLastOperation(){
return this._operation[this._operation.length-1];
}
setLastOperation(value){
this._operation[this._operation.length-1] = value;
}
isOperator(value){
return (['+','-','*','/'].indexOf(value) > -1);
}
pushOperation(value){
this._operation.push(value);
if(this._operation.length > 3){
this.calc();
}
}
addOperation(value){
if(isNaN(this.getLastOperation())){
if(this.isOperator(value)){
this.setLastOperation(value);
} else{
this.pushOperation(value);
this.setLastNumberToDisplay();
}
} else{
if(this.isOperator(value)){
this.pushOperation(value);
} else{
let newValue;
if(this.getLastOperation().toString() !== '0'){
newValue = this.getLastOperation().toString() + value.toString();
} else{
newValue = value.toString();
}
this.setLastOperation(newValue);
this.setLastNumberToDisplay();
}
}
if (this._readyToClear){
this.clearAll(value);
this._readyToClear = false;
return
}
}
addDot(){
let lastOperation = this.getLastOperation();
if(typeof lastOperation === 'string' && lastOperation.split('').indexOf('.') > -1) return;
if(this.isOperator(lastOperation) || lastOperation === undefined){
this.pushOperation('0.');
} else{
this.setLastOperation(lastOperation.toString() + '.');
}
this.setLastNumberToDisplay();
}
getResult(){
return eval(this._operation.join(''));
}
getLastItem(isOperator = true){
let lastItem;
for(let i = this._operation.length - 1; i >= 0; i--){
if(this.isOperator(this._operation[i]) == isOperator){
lastItem = this._operation[i];
break;
}
}
if(lastItem == 0){
return lastItem;
} else if(!lastItem){
lastItem = (isOperator) ? this._lastOperator : this._lastNumber;
}
return lastItem;
}
calc() {
let last = '';
this._lastOperator = this.getLastItem();
if (this._operation.length < 3) {
let firstItem = this._operation[0];
this._operation = [firstItem, this._lastOperator, this._lastNumber];
} else if (this._operation.length > 3) {
last = this._operation.pop();
this._lastNumber = this.getResult();
} else if (this._operation.length == 3) {
this._lastNumber = this.getLastItem(false);
}
let result = this.getResult();
this._operation = [result];
if (last) this._operation.push(last);
this.setLastNumberToDisplay();
}
setError(){
this.displayCalc = 'Erro';
}
execBtn(value){
this.playAudio();
switch(value){
case 'ac':
this.clearAll();
break;
case 'ce':
this.clearEntry();
break;
case 'cl':
this.ClearLast();
break;
case 'division':
this._readyToClear = false;
this.addOperation('/');
break;
case 'multiplication':
this._readyToClear = false;
this.addOperation('*');
break;
case 'subtraction':
this._readyToClear = false;
this.addOperation('-');
break;
case 'addition':
this._readyToClear = false;
this.addOperation('+');
break;
case 'dot':
this.addDot();
break;
case 'equal':
this.calc();
this._readyToClear = true;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
this.addOperation(parseInt(value));
break;
default:
this.setError();
break;
}
}
initButtonsEvents(){
let buttons = document.querySelectorAll('#buttons > section > button');
buttons.forEach((btn, index) =>{
this.addEventListenerAll(btn, 'click drag', e =>{
let textBtn = btn.className.replace('btn-', '');
this.execBtn(textBtn);
});
});
}
get displayTime(){
return this._timeEl.innerHTML;
}
set displayTime(value){
return this._timeEl.innerHTML = value;
}
get displayDate(){
return this._dateEl.innerHTML
}
set displayDate(value){
return this._dateEl.innerHTML = value
}
get displayHistoric(){
return this._historicEl.innerHTML
}
set displayHistoric(value){
return this._historicEl.innerHTML = value
}
get displayCalc(){
return this._displayCalcEl.innerHTML;
}
set displayCalc(value){
if (value.toString().length > 10){
this.setError();
return false;
}
this._displayCalcEl.innerHTML = value;
}
get currentDate(){
return new Date();
}
set currentDate(value){
this._currentDate = value;
}
}
window.calculator = new CalcController;
#font-face {
font-family: 'Digital-7';
src: url('/font/digital-7.ttf');
}
#calculator-container {
height: 100vh;
width: 100vh;
}
#calculator {
background-color: #B5ACEA;
border-radius: .5rem;
box-shadow: 0px 10px 0px 0px #8468EC;
width: fit-content;
}
#audio {
color: #F5F5F5;
cursor: pointer;
font-size: 2rem;
}
#display-container {
background-color: #3D2C8D;
border-radius: .5rem;
box-shadow: inset 0px 5px 0px 0px #1C0C5B;
font-family: 'Digital-7', sans-serif;
height: fit-content;
}
#time,
#date,
#historic,
#display {
color: #F5F5F5;
}
#historic {
height: 1rem;
}
#display {
font-size: 3rem;
height: 4rem;
}
#buttons button {
background-color: #3D2C8D;
border-radius: .5rem;
box-shadow: 0px 5px 0px 0px #1C0C5B;
color: #F5F5F5;
font-size: 1.5rem;
height: 5rem;
margin-bottom: .5rem;
margin-top: .5rem;
transition-duration: 1s, .1s;
transition-property: background-color, transform;
transition-timing-function: ease;
width: 5rem;
}
#buttons button:hover {
background-color: #1C0C5B;
}
#buttons button:active {
transform: translateY(5px);
}
#buttons .btn-ac,
#buttons .btn-ce,
#buttons .btn-cl,
#buttons .btn-equal {
background-color: #8468EC;
}
#buttons .btn-equal {
flex-grow: 2;
}
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Calculator</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.3.0-alpha1/dist/js/bootstrap.bundle.min.js" integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons#1.10.3/font/bootstrap-icons.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container-fluid d-flex justify-content-center align-items-center" id="calculator-container">
<div class="container-fluid p-4" id="calculator">
<section class="mb-2">
<i class="bi bi-volume-up-fill" id="audio"></i>
</section>
<section class="display mb-2" id="display-container">
<div class="d-flex justify-content-between ps-2 pe-2 pt-2">
<p class="m-0" id="time"></p>
<p class="m-0" id="date"></p>
</div>
<div class="d-flex justify-content-end ps-2 pe-2">
<p class="m-0" id="historic"></p>
</div>
<div class="d-flex justify-content-end ps-2 pe-2 pb-2">
<p class="m-0" id="display">0</p>
</div>
</section>
<div id="buttons">
<section class="d-flex gap-2">
<button class="btn-ac">AC</button>
<button class="btn-ce">CE</button>
<button class="btn-cl"><i class="bi bi-x-octagon"></i></button>
<button class="btn-division">÷</button>
</section>
<section class="d-flex gap-2">
<button class="btn-7">7</button>
<button class="btn-8">8</button>
<button class="btn-9">9</button>
<button class="btn-multiplication">x</button>
</section>
<section class="d-flex gap-2">
<button class="btn-4">4</button>
<button class="btn-5">5</button>
<button class="btn-6">6</button>
<button class="btn-subtraction">-</button>
</section>
<section class="d-flex gap-2">
<button class="btn-1">1</button>
<button class="btn-2">2</button>
<button class="btn-3">3</button>
<button class="btn-addition">+</button>
</section>
<section class="d-flex gap-2">
<button class="btn-0">0</button>
<button class="btn-dot">.</button>
<button class="btn-equal">=</button>
</section>
</div>
</div>
</div>
<script src="/js/controller/CalcController.js"></script>
<script src="/js/calculator.js"></script>
</body>
</html>
Your code needs some additional state (by this I mean data or information) so that it knows if it should clear the display when a new button is pressed. A simple boolean variable would suffice such as shouldClear which the code sets to true when you press equals and back to false again after pressing any other button and clearing the display.

i'm having a lit of problem with my javascript game

i copied this little javascript game from github i started editing i made some new levels and whole new graphic design for the game. basiclly i did it for fun made new keybinds for the keyboard since it's playable for keyboard only.
then i had this idea to create a button that acts like a keyboard or directly make the character move
i tried but it don't work
so here is my "controller.js" which is responsible for the character movements
with"htmlfile.html"
const Controller = function() {
this.left = new Controller.ButtonInput();
document.getElementById("clickMe").onclick = this.right = new Controller.ButtonInput();;
this.up = new Controller.ButtonInput();
this.keyDownUp = function(type, keycode) {
var down = (type == "keydown") ? true : false;
//old//
switch(keycode) {
case 37: this.left.getInput(down); break;
case 38: this.up.getInput(down); break;
case 39: this.right.getInput(down); break;
// case 81: this.left.getInput(down); break;
// case 90: this.up.getInput(down); break;
// case 68: this.right.getInput(down);
//new//
}
};
};
//new//
//1- document.getElementById("clickMe").onclick = doFunction;
//2-document.getElementById("demo").onclick =
this.keyDownUp = function(type, button) {
var down = (type == "keydown") ? true : false;
$("input[type='button']").click(function() {
switch(button) {
case '1': this.left.getInput(down); break; //notice BREAK
case '2': this.right.getInput(down); break;
case '3': this.up.getInput(down); break;
}
});
}
Controller.prototype = {
constructor : Controller
};
Controller.ButtonInput = function() {
this.active = this.down = false;
};
Controller.ButtonInput.prototype = {
constructor : Controller.ButtonInput,
getInput : function(down) {
if (this.down != down) this.active = down;
this.down = down;
}
};
<!DOCTYPE html>
<html>
<head>
<script src="jquery-2.1.1.min.js"></script>
<!-- Added this meta tag 04/07/2018 -->
<meta name = "viewport" content = "user-scalable=no,width=device-width">
<link href = "rabbit-trap.css" rel = "stylesheet" type = "text/css">
<!--input type="text" id="demo-->
<title>Rabbit Trap</title>
</head>
<body>
<br>
<br>
<br>
<br>
<br>
<!center>
<!-- Added a menu to navigate projects from the main page -->
<div id = "menu">
<p>menu</p>
<div id = "menu-list">
<br>
part1
part2
part3
part4
part5
part6
part7
</div>
</div>
<canvas></canvas>
<!-- Since Rabbit Trap is a multi-part series and I didn't feel like writing
html and css for every single part, I decided to dynamically add the appropriate
js file containing the game logic for each part based on url parameters. -->
<script type = "text/javascript">
let part = String(window.location).split("?")[1];
/* Added on 03/09/2018 to allow reusing scripts from previous parts. */
let parts = {
"01":["01/controller-01.js", "01/display-01.js", "01/engine-01.js", "01/game-01.js", "01/main-01.js"],
"02":["02/controller-02.js", "02/display-02.js", "01/engine-01.js", "02/game-02.js", "02/main-02.js"],
"03":["02/controller-02.js", "03/display-03.js", "01/engine-01.js", "03/game-03.js", "03/main-03.js"],
"04":["02/controller-02.js", "04/display-04.js", "01/engine-01.js", "04/game-04.js", "03/main-03.js"],
"05":["02/controller-02.js", "05/display-05.js", "01/engine-01.js", "05/game-05.js", "05/main-05.js"],
"06":["02/controller-02.js", "05/display-05.js", "06/engine-06.js", "06/game-06.js", "06/main-06.js"],
"07":["02/controller-02.js", "05/display-05.js", "06/engine-06.js", "07/game-07.js", "07/main-07.js"],
};
switch(part) {
case "01": case "02": case "03": case "04": case "05": case "06": case "07": break;
default:
part = "05";
}
//new//
//<input type="button" value="button" id="movebutton" /> <!--removed inline JS-->
//new//
for (let index = 0; index < parts[part].length; index ++) {
let script = document.createElement("script");
script.setAttribute("type", "text/javascript");
script.setAttribute("src", parts[part][index]);
document.head.appendChild(script);
}
let menu = document.getElementById("menu");
let menu_list = document.getElementById("menu-list");
menu.addEventListener("click", function(event) {
menu_list.style.display = (menu_list.style.display == "none") ? "grid" : "none";
});
menu_list.style.display = "none";
</script>
<input id="clickMe" type="button" value="clickme" onclick="right" />
<input type="button" value="Change" id="1">
<input type="button" value="Change" id="2">
<input type="button" value="Change" id="3">
<!/center>
<!--new-->
<input type="button" value="button" id="demon" /?> <!--removed inline JS-->
<button id="demo" onclick="right">right</button>
</body>
</html>
sorry i know it's soo dirty code but i will try to clear the junk my self
all i need is help to create a button for movements "left,right,up"
thank you if you make it to the end and i appreciate your help
Here is an example on moving a square using both keyboard and mouse(button elements)
var pos = [0, 0], box = document.querySelector("#box"),
directions = {"37": "Left", "38": "Up", "39": "Right", "40": "Down"};
document.querySelector("#controls").onclick =
document.querySelector("body").onkeyup = function(e) {
var direction = e.type === "click" && e.target.nodeName === "BUTTON" ?
e.target.textContent : directions[e.keyCode];
switch(direction) {
case "Right": {
box.style.left = `${pos[0] + 50 > 300 ? 300 : pos[0] += 50}px`;
break;
}
case "Left": {
box.style.left = `${pos[0] - 50 < 0 ? 0 : pos[0] -= 50}px`;
break;
}
case "Down": {
box.style.top = `${pos[1] + 50 > 300 ? 300 : pos[1] += 50}px`;
break;
}
case "Up": {
box.style.top = `${pos[1] - 50 < 0 ? 0 : pos[1] -= 50}px`;
break;
}
}
};
#container {
width: 350px;
height: 350px;
background-color: orange;
border-radius: 10px;
position: relative;
}
#box {
width: 50px;
height: 50px;
background-color: blue;
border-radius: 10px;
position: absolute;
top: 0;
left: 0;
}
#controls {
margin-top: 10px;
width: 350px;
display: flex;
flex-wrap: wrap;
border-radius: 50%;
overflow: hidden;
box-shadow: 1px 1px 2px #333, -7px -2px 1px #ccc;
}
#controls button {
width: 50%;
height: 40px;
cursor: pointer;
font: bold 24px monospace;
color: white;
text-shadow: 0 0 1px black, -0 -0 1px black;
}
#controls .solo {
width: 100%;
}
#controls button:hover {
outline: none;
background-color: lightgreen;
}
<div id="container">
<div id="box"></div>
</div>
<div id="controls">
<button class="solo">Up</button>
<button>Left</button><button>Right</button>
<button class="solo">Down</button>
</div>

Why is my text output from next() and prev() toggle incorrect?

When clicking the arrows to change the displayed option, the incorrect options is shown.
The user should be able click on the option menu to toggle it open/cosed and be able to click on a option to select it. Alternatively, the arrows could be used to toggle through the options instead.
This is the problematic code:
<script>
$("#arrow_left_physics").click(function() {
var $selected = $(".left_menu_option_selected").removeClass("left_menu_option_selected");
var divs = $("#left_menu__variant_physics").children();
divs.eq((divs.index($selected) - 1) % divs.length).addClass("left_menu_option_selected");
$("#left_menu_open .button-text").text($($selected).text());
});
$("#arrow_right_physics").click(function() {
var $selected = $(".left_menu_option_selected").removeClass("left_menu_option_selected");
var divs = $selected.parent().children();
divs.eq((divs.index($selected) + 1) % divs.length).addClass("left_menu_option_selected");
$("#left_menu_open .button-text").text($($selected).text());
});
</script>
$("#menu_open").click(function() {
$("#menu").toggle();
});
$(".menu_option").click(function() {
if ($(this).hasClass(".menu_option_selected")) {} else {
$(".menu_option").removeClass("menu_option_selected");
$(this).addClass("menu_option_selected");
$("#menu_open .button_text").text($(this).text());
}
});
$("#arrow_left").click(function() {
var $selected = $(".menu_option_selected").removeClass("menu_option_selected");
var options = $("#menu").children();
options.eq((options.index($selected) - 1) % options.length).addClass("menu_option_selected");
$("#menu_open .button_text").text($($selected).text());
});
$("#arrow_right").click(function() {
var $selected = $(".menu_option_selected").removeClass("menu_option_selected");
var options = $("#menu").children();
options.eq((options.index($selected) + 1) % options.length).addClass("menu_option_selected");
$("#menu_open .button_text").text($($selected).text());
});
.menu_open {
Cursor: pointer;
}
.menu {
display: none;
position: absolute;
border: 1px solid;
}
.menu_option {
Cursor: pointer;
Padding: 5px;
}
.menu_option:hover {
Background-Color: black;
Color: white;
}
.menu_option_selected {
color: green;
Background-color: #00ff0a4d;
}
.menu_option_selected:hover {
color: green;
}
.arrow {
Cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<input class="arrow" type="button" id="arrow_left" value="❮" />
<input class="arrow" type="button" id="arrow_right" value="❯" />
</div>
<div>
<button class="menu_open" id="menu_open">
<span class="button_text">option1</span>
</button>
</div>
<div class="menu" id=menu>
<div class="menu_option menu_option_selected">option1</div>
<div class="menu_option">option2</div>
<div class="menu_option">option3</div>
<div class="menu_option">option4</div>
<div class="menu_option">option5</div>
<div class="menu_option">option6</div>
</div>
-It seems that the first click of the arrows isn't working and that the index function is incorrect somewhere.
The problem is this line:
$("#menu_open .button_text").text($($selected).text());
$($selected) is the option that was previously selected, so you're showing the text of the previous option, not the current option. (BTW, there's no need to wrap $selected in $(), since it's already a jQuery object.)
You should use $(".menu_option_selected").text() instead of $($selected).text() to get the current option.
You should also make the initial text of the button option1, so it matches the selected option.
$("#menu_open").click(function() {
$("#menu").toggle();
});
$(".menu_option").click(function() {
if ($(this).hasClass(".menu_option_selected")) {} else {
$(".menu_option").removeClass("menu_option_selected");
$(this).addClass("menu_option_selected");
$("#menu_open .button_text").text($(this).text());
}
});
$("#arrow_left").click(function() {
var $selected = $(".menu_option_selected").removeClass("menu_option_selected");
var options = $("#menu").children();
options.eq((options.index($selected) - 1) % options.length).addClass("menu_option_selected");
$("#menu_open .button_text").text($(".menu_option_selected").text());
});
$("#arrow_right").click(function() {
var $selected = $(".menu_option_selected").removeClass("menu_option_selected");
var options = $("#menu").children();
options.eq((options.index($selected) + 1) % options.length).addClass("menu_option_selected");
$("#menu_open .button_text").text($(".menu_option_selected").text());
});
.menu_open {
Cursor: pointer;
}
.menu {
display: none;
position: absolute;
border: 1px solid;
}
.menu_option {
Cursor: pointer;
Padding: 5px;
}
.menu_option:hover {
Background-Color: black;
Color: white;
}
.menu_option_selected {
color: green;
Background-color: #00ff0a4d;
}
.menu_option_selected:hover {
color: green;
}
.arrow {
Cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<input class="arrow" type="button" id="arrow_left" value="❮" />
<input class="arrow" type="button" id="arrow_right" value="❯" />
</div>
<div>
<button class="menu_open" id="menu_open">
<span class="button_text">option1</span>
</button>
</div>
<div class="menu" id=menu>
<div class="menu_option menu_option_selected">option1</div>
<div class="menu_option">option2</div>
<div class="menu_option">option3</div>
<div class="menu_option">option4</div>
<div class="menu_option">option5</div>
<div class="menu_option">option6</div>
</div>
Just another version, refactoring your javascript code with some Arrow functions.
const setButtonText = () => {
$("#menu_open .button_text").text(
$(".menu_option_selected").text()
);
}
const moveSelection = direction => {
var selected = $(".menu_option_selected")
var options = $("#menu").children()
var newIndex;
if (direction == 'right') {
newIndex = (options.index(selected) + 1) % options.length
} else {
newIndex = (options.index(selected) - 1) % options.length
}
selected.removeClass("menu_option_selected")
options.eq(newIndex).addClass("menu_option_selected")
setButtonText()
}
// inizilize menu button_text
setButtonText()
$("#arrow_left").click(() => moveSelection('left'));
$("#arrow_right").click( () => moveSelection('right'));
$("#menu_open").click( () => $("#menu").toggle());
$(".menu_option").click( function() {
$(".menu_option_selected").removeClass("menu_option_selected")
$(this).addClass("menu_option_selected")
setButtonText()
});

jQuery show / hide notification if read

I'm trying to show/hide the .notification indicator when all of the .activity__item is marked as read. They can be marked read by clicking each individual item's .activity__button, or by clicking the button to mark all item's as read.
Using the function below I tried identifying whether each item has received the read state (getting the .activity__button--read class) and then hiding the notification if all of the items have been read. This doesn't seem to work here.
Is there an efficient way to show/ hide the notification indicator when all items have been read either by
Clicking them individually or
Marking all as read by clicking
the button?
$(function() {
if (!$(".activity__button").not(".activity__button--read").length) {
$(this).closest(".activity__header").find(".notification").hide();
} else {
$(this).closest(".activity__header").find(".notification").show();
} });
var open = 'fas fa-envelope-open';
var close = 'fas fa-envelope';
$(".activity__button[data-status]").off().on('click', function() {
var status = $(this).data('status');
if (status == 'unread') {
$(this).data('status', 'read').empty().html('<i class="' + open + '"></i>').addClass('activity__button--read');
$(this).closest(".activity__item").addClass('activity__item--read');
} else {
$(this).data('status', 'unread').empty().html('<i class="' + close + '"></i>').removeClass('activity__button--read');
$(this).closest(".activity__item").removeClass('activity__item--read');
}
});
$('.mark').off().on('click', function() {
var status = $(this).data('status');
if (!status || status == 'unread') {
$(this).closest(".activity__header").find(".notification").hide();
$(this).html('Mark all unread').data('status', 'read');
$(".activity__button[data-status]").each(function() {
$(this).data('status', 'read').empty().html('<i class="' + open + '"></i>').addClass('activity__button--read');
$(this).closest(".activity__item").addClass('activity__item--read');
});
} else {
$(this).html('Mark all read').data('status', 'unread');
$(this).closest(".activity__header").find(".notification").show();
$(".activity__button[data-status]").each(function() {
$(this).data('status', 'unread').empty().html('<i class="' + close + '"></i>').removeClass('activity__button--read');
$(this).closest(".activity__item").removeClass('activity__item--read');
$(this).closest(".activity__header").find(".notification").show();
});
}
});
$(function() {
if (!$(".activity__button").not(".activity__button--read").length) {
$(this).closest(".activity__header").find(".notification").hide();
} else {
$(this).closest(".activity__header").find(".notification").show();
}
});
.activity__header {
display: flex;
}
.activity__item {
position: relative;
height: 100px;
width: 300px;
border: 1px solid whitesmoke;
margin-top: -1px;
}
.activity__button {
cursor: pointer;
padding: 1rem;
font-size: 21px;
}
.activity__button svg {
color: #f8971d;
}
.activity__button.activity__button--read svg {
color: #47a877;
}
.activity__item--read {
background: #fafafa !important;
}
button {
padding: 12px;
margin: 1rem;
}
.notification {
width: 10px;
height: 10px;
border-radius: 50%;
background-color: #cb6f74;
color: #fff;
font-size: 10px;
font-weight: 600;
}
<script src="https://pro.fontawesome.com/releases/v5.8.1/js/all.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="activity__header">
<button class="mark" data-status="unread">Mark as Read</button>
<div class="notification"></div>
</div>
<div>
<div class="activity__item">
<div class="activity__button" data-status="unread"><i class="fas fa-envelope"></i>
</div>
</div>
<div class="activity__item">
<div class="activity__button" data-status="unread"><i class="fas fa-envelope"></i>
</div>
</div>
<div class="activity__item activity__item--read">
<div class="activity__button activity__button--read" data-status="read">
<i class="fas fa-envelope-open"></i>
</div>
</div>
<div class="activity__item">
<div class="activity__button" data-status="unread">
<i class="fas fa-envelope"></i>
</div>
</div>
</div>
</div>
data-status"read"`?
One way would be to check the state of all items each time they are updated
You could use a function like this
function updateNotificationIcon(){
var $activity_items = $('.activity__item'),
all_read = true;
// Loop through each .activity__item
$activity_items.each(function(){
// If item does NOT have the "read" class, set all_read to false
if(!$(this).hasClass('activity__item--read')){
all_read = false;
}
});
if(all_read){
$('.notification').hide();
}else{
$('.notification').show();
}
}
Then just run that function after each change to one of the item's "read" state
In your case I would update your javascript as so:
var open = 'fas fa-envelope-open';
var close = 'fas fa-envelope';
$(".activity__button[data-status]").off().on('click', function() {
var status = $(this).data('status');
if (status == 'unread') {
$(this).data('status', 'read').empty().html('<i class="' + open + '"></i>').addClass('activity__button--read');
$(this).closest(".activity__item").addClass('activity__item--read');
} else {
$(this).data('status', 'unread').empty().html('<i class="' + close + '"></i>').removeClass('activity__button--read');
$(this).closest(".activity__item").removeClass('activity__item--read');
}
// Add here
updateNotificationIcon();
});
$('.mark').off().on('click', function() {
var status = $(this).data('status');
if (!status || status == 'unread') {
$(this).closest(".activity__header").find(".notification").hide();
$(this).html('Mark all unread').data('status', 'read');
$(".activity__button[data-status]").each(function() {
$(this).data('status', 'read').empty().html('<i class="' + open + '"></i>').addClass('activity__button--read');
$(this).closest(".activity__item").addClass('activity__item--read');
});
} else {
$(this).html('Mark all read').data('status', 'unread');
$(this).closest(".activity__header").find(".notification").show();
$(".activity__button[data-status]").each(function() {
$(this).data('status', 'unread').empty().html('<i class="' + close + '"></i>').removeClass('activity__button--read');
$(this).closest(".activity__item").removeClass('activity__item--read');
$(this).closest(".activity__header").find(".notification").show();
});
}
// Add here
updateNotificationIcon();
});
$(function() {
if (!$(".activity__button").not(".activity__button--read").length) {
$(this).closest(".activity__header").find(".notification").hide();
} else {
$(this).closest(".activity__header").find(".notification").show();
}
});
function updateNotificationIcon() {
var $activity_items = $('.activity__item'),
all_read = true;
// Loop through each .activity__item
$activity_items.each(function() {
// If item does NOT have the "read" class, set all_read to false
if (!$(this).hasClass('activity__item--read')) {
all_read = false;
}
});
if (all_read) {
$('.notification').hide();
} else {
$('.notification').show();
}
}

5x5 checker board controlled by keyboard with different events at boxes

So i have this project am working on which is to traverse through 5x5 checker board with different events occurring at different boxes(positions) in the board (e.g if the person is at [2,0] an event to reduce the grid to only 2x2 size occurs or perhaps the box at [4,0] changes color)
much appreciate the help.
(function() {
// refined add event cross browser
function addEvent(elem, event, fn) {
if (typeof elem === "string") {
elem = document.getElementById(elem);
}
// avoid memory overhead of new anonymous functions for every event handler that's installed
// by using local functions
function listenHandler(e) {
var ret = fn.apply(this, arguments);
if (ret === false) {
e.stopPropagation();
e.preventDefault();
}
return(ret);
}
function attachHandler() {
// set the this pointer same as addEventListener when fn is called
// and make sure the event is passed to the fn also so that works the same too
var ret = fn.call(elem, window.event);
if (ret === false) {
window.event.returnValue = false;
window.event.cancelBubble = true;
}
return(ret);
}
if (elem.addEventListener) {
elem.addEventListener(event, listenHandler, false);
} else {
elem.attachEvent("on" + event, attachHandler);
}
}
function addClass(elem, cls) {
var oldCls = elem.className;
if (oldCls) {
oldCls += " ";
}
elem.className = oldCls + cls;
}
function removeClass(elem, cls) {
var str = " " + elem.className + " ";
elem.className = str.replace(" " + cls + " ", " ").replace(/^\s+|\s+$/g, "");
}
function findItem(items, target) {
for (var i = 0; i < items.length; i++) {
if (items[i] === target) {
return(i);
}
}
return(-1);
}
var keys = {up: 38, down: 40, left: 37, right: 39};
var cards = document.getElementById("game-board").getElementsByClassName("card");
addEvent(document, "keydown", function(e) {
// get key press in cross browser way
var code = e.which || e.keyCode;
// number of items across
var width = 4;
var increment, index, newIndex, active;
switch(code) {
case keys.up:
increment = -width;
break;
case keys.down:
increment = width;
break;
case keys.left:
increment = -1;
break;
case keys.right:
increment = 1;
break;
default:
increment = 0;
break;
}
if (increment !== 0) {
active = document.getElementById("game-board").getElementsByClassName("active")[0];
index = findItem(cards, active);
newIndex = index + increment;
if (newIndex >= 0 && newIndex < cards.length) {
removeClass(active, "active");
addClass(cards[newIndex], "active");
}
// prevent default handling of up, down, left, right keys
return false;
}
});
})();
.active {
background: #00ebe4;
border:2px solid #93ff85;
}
*{margin: 0; padding:0;}
body{
font-family:arial;
background: #5f5f5f;
}
#plan{
margin:90px auto;
width:400px;
height:400px;
background: rgba(95, 95, 95, 0.84);
border-radius: 10px;
}
#game-board{
width:380px;
height:380px;
}
.card{
box-shadow: 0 2px 2px 1px #000;
border-radius: 5px;
height:70px;
width:70px;
display:inline-block;
margin-left:20px;
margin-top:20px;
background: #3a89be 14px 7px no-repeat;
}
<body>
<div align="center";
style="color: #d8d8d8;
margin-top: 50px" >
<H1></H1>
<h2>use Arrows to Navigate.</h2></div>
<div id="plan">
<div id="game-board">
<div class="card active" id="0"></div>
<div class="card" id="1"></div>
<div class="card" id="2"></div>
<div class="card" id="3"></div>
<div class="card" id="4"></div>
<div class="card" id="5"></div>
<div class="card" id="6"></div>
<div class="card" id="7"></div>
<div class="card" id="8"></div>
<div class="card" id="9"></div>
<div class="card" id="10"></div>
<div class="card" id="11"></div>
<div class="card" id="12"></div>
<div class="card" id="13"></div>
<div class="card" id="14"></div>
<div class="card" id="15"></div>
</div>
</div>
<!-- <div id="restart"><button id="reset-button"></button>reset</div> -->
</body>
This is in response to your statement/clarification:
"but what i dont know is how to keep track of these actions on
specific boxes, thanks"
Take a look at event listeners in javascript. I know you're using some above, but it looks like you may have copied from somewhere -- which is fine -- but it's in a way that makes them less then useful for this purpose. Event listeners are normally setup on specific elements on the page, using getElementById. Example:
HTML
<button id='button1'>Click Me!</button>
JS
document.getElementById('button1').addEventListener("click", myFunction, true);
myFunction = function(){
//here's where you change the color, or size, or make a popup window, etc.
};
Clicking on that particular button (which can also be any other HTML element) will execute the function.

Categories