Fading through RGB space - javascript

for another project we are trying to fade through the RGB color space (from one color to another).
As a proof of concept we build the logic in JavaScript. As a final result, the background of a div should be changed to the given color, step by step.
But in our example the div just get set to the final color and doesn't show the steps between the start and end color.
Since we can't get it to work, our qustion: What is wrong here? is the logic flawed or our JS skills :) ?
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
</head>
<body>
<script>
$(function() {
var colors = [];
$('#go').click(function() {
console.log($('#red1').val()+" "+$('#green1').val()+" "+$('#blue1').val()+" "+$('#red2').val()+" "+$('#green2').val()+" "+$('#blue2').val());
slidecolor($('#red1').val(), $('#green1').val(), $('#blue1').val(), $('#red2').val(), $('#green2').val(), $('#blue2').val());
readArray();
});
function slidecolor(StartsR, StartsG, StartsB, aimR, aimG, aimB) {
StartsR = parseInt(StartsR);
StartsG = parseInt(StartsG);
StartsB = parseInt(StartsB);
aimR = parseInt(aimR);
aimG = parseInt(aimG);
aimB = parseInt(aimB);
if(aimR >= StartsR)
{
var directionR = 1;
console.log("größer");
var distanceR = aimR - StartsR;
}
else
{
var directionR = 0;
console.log("kleiner");
var distanceR = StartsR - aimR;
}
if(aimB >= StartsB)
{
var directionB = 1;
var distanceB = aimB - StartsB;
}
else
{
var directionB = 0;
var distanceB = StartsB - aimB;
}
if(aimG >= StartsG)
{
var directionG = 1;
var distanceG = aimG - StartsG;
}
else
{
var directionG = 0;
var distanceG = StartsG - aimG;
}
if((distanceR >= distanceB) && (distanceR >= distanceG)) { var distance = distanceR; }
if((distanceG >= distanceR) && (distanceG >= distanceB)) { var distance = distanceG; }
if((distanceB >= distanceR) && (distanceB >= distanceG)) { var distance = distanceB; }
var stepsR = Math.round(distance/distanceR);
var stepsG = Math.round(distance/distanceG);
var stepsB = Math.round(distance/distanceB);
console.log(distance+" "+distanceR);
console.log(stepsR+" "+stepsG+" "+stepsB);
var tmpstepsR = 0;
var tmpstepsG = 0;
var tmpstepsB = 0;
for(i=0; i<=distance; i++) {
console.log(i);
if(i==0)
{
console.log("FIRST RUN");
if(directionR == 1) {
var tmpR = StartsR + 1;
tmpstepsR = stepsR;
}
else
{
var tmpR = StartsR - 1;
tmpstepsR = stepsR + 1;
}
if(directionG == 1) {
var tmpG = StartsG + 1;
tmpstepsG = stepsG;
}
else
{
var tmpG = StartsG - 1;
tmpstepsG = stepsG;
}
if(directionB == 1) {
var tmpB = StartsB + 1;
tmpstepsB = stepsB;
}
else
{
tmpstepsB = stepsB;
var tmpB = StartsB - 1;
}
}
else
{
console.log("NEXT RUN");
if(((stepsR == i) || (tmpstepsR == i)) && tmpR != aimR)
{
tmpstepsR = tmpstepsR + stepsR;
if(directionR == 1) {
var tmpR = tmpR + stepsR;
}
else
{
var tmpR = tmpR - stepsR;
}
}
if(((stepsG == i) || (tmpstepsG == i)) && tmpG != aimG)
{
tmpstepsG = tmpstepsG + stepsG;
if(directionG == 1) {
var tmpG = tmpG + stepsG;
}
else
{
var tmpG = tmpG - stepsG;
}
}
if(((stepsB == i) || (tmpstepsB == i)) && tmpB != aimB)
{
tmpstepsB = tmpstepsB + stepsB;
if(directionB == 1) {
var tmpB = tmpB + stepsB;
}
else
{
var tmpB = tmpB - stepsB;
}
}
}
console.log('rgb('+ tmpR +','+ tmpG +','+ tmpB +')');
colors.push('rgb('+ tmpR +','+ tmpG +','+ tmpB +')');
}
}
function readArray(){
colors.forEach(function(entry){
timeOut(entry);
$('#color').css("background-color", entry);
});
}
function timeOut(entry){
setTimeout(function(){$('#color').css("background-color", entry);}, 3000);
}
});
</script>
<h1>Farbe 1</h1>
red: <input id="red1">
green: <input id="green1">
blue: <input id="blue1">
<h1>Farbe 2</h2>
red: <input id="red2">
green: <input id="green2">
blue: <input id="blue2">
<button id="go">LET'S GO</button>
<div id="color" style="width:500px;height:500px"></div>
</body>
</html>
Please note that some parts may be a bit buggy or ugly since it's just a first try. The last part were we added some time out were some last resort and may be not best practice...
EDIT: jsfiddle

In readArray, you're iterating over all entries in the colors array. This iteration takes very little time (As in, faster than you can notice). During that iteration, all 3-second timeouts are set. They aren't sequenced, they're all just set to be executed ~3 seconds after the forEach is done.
You'll need to properly sequence your callbacks:
function readArray(){
timeOut(colors, 0);
}
function timeOut(array, index){
var entry = colors[index];
$('#color').css("background-color", entry);
var nextIndex = index + 1;
if(nextIndex < array.length){
setTimeout(function(){
timeOut(array, nextIndex);
}, 30);
}
}
Basically, at the moment the current "step" is executed, you set the timeout for the next step.
Example Fiddle
Please note I set the timeout to 30 ms per step, so you can actually notice the fade.
(Instead of readArray();, you can just use timeOut(colors, 0);, of course, so you can remove readArray altogether)

Related

How to solve this multiple nested for loop

EDIT: Big edit from ealier
I have achieved: the ultimate for-loop HELL.
What it does: scans an image and finds a 40 by 40 pixel square that has every pixel within it approximately the same color.
The problem: The code doesn't work as intended. Unsure why, but all my attempts to debug are in vain.
jimp.read('jeffrey.png')
.then(image => {
console.log(jimp.intToRGBA(image.getPixelColor(0,0)))
console.log(image.bitmap.width)
console.log(image.bitmap.height)
var breakAll = false;
var FINALX;
var FINALY;
var doneCounter = 0;
//40 by 40 pixels needed for qr code. Thisis barcode, so make it 40 by 80 or smthn, figure out that x thing.
for(var x = 0; x < image.bitmap.width; x++) {
var breakThis = false;
console.log(x + " is x")
if(breakAll == true) {
break;
}
var verticalStart = 0;
for(var y1 = verticalStart; y1 < image.bitmap.height; y1++) {
if(breakAll == true) {
break;
}
var tempStandardR = jimp.intToRGBA(image.getPixelColor(x,y1)).r;
var tempStandardG = jimp.intToRGBA(image.getPixelColor(x,y1)).g;
var tempStandardB = jimp.intToRGBA(image.getPixelColor(x,y1)).b;
var verticalCounter = 0;
for(var y2 = y1; y2 < image.bitmap.height; y2++) {
if(breakAll == true) {
break;
}
if(verticalCounter >= 40) {
//Then do X stuff
//horizcountertim
for(var y3 = y1; y3 < y1 + 40; y3++) {
if(breakAll == true) {
break;
}
breakThis = false;
var horizontalCounter = 0;
var tempStandardR3 = jimp.intToRGBA(image.getPixelColor(x,y3)).r;
var tempStandardG3 = jimp.intToRGBA(image.getPixelColor(x,y3)).g;
var tempStandardB3 = jimp.intToRGBA(image.getPixelColor(x,y3)).b;
for(var x2 = x; x2 < x + 41; x2++) {
if(breakAll == true) {
break;
}
console.log(doneCounter)
if(doneCounter >= 40) {
//SUCESS!!!!!!
//THE SPOT HAS BEEN FOUND AT (x minus 40, y minus 40).
//insert other image in this image at above coordinates. Wow I highly doubt this works.
console.log('SUCESS!!!!!!!!!')
FINALX = x2-40;
FINALY = y3-40;
breakAll = true;
break;
}
if(breakAll == true) {
break;
}
var tempStandardR4 = jimp.intToRGBA(image.getPixelColor(x2,y3)).r;
var tempStandardG4 = jimp.intToRGBA(image.getPixelColor(x2,y3)).g;
var tempStandardB4 = jimp.intToRGBA(image.getPixelColor(x2,y3)).b;
if((((tempStandardR3 - tempStandardR4) <= 20) && ((tempStandardR3 - tempStandardR4) >= -20)) && (((tempStandardG3 - tempStandardG4) <= 20) && ((tempStandardG3 - tempStandardG4) >= -20)) && (((tempStandardB3 - tempStandardB4) <= 20) && ((tempStandardB3 - tempStandardB4) >= -20))) {
horizontalCounter++;
if(horizontalCounter == 40) {
horizontalCounter = 0;
doneCounter++;
break;
}
// if((x2 - x >= 39) && (y3 - y1) >= 39) {
if(breakAll == true) {
break;
}
}
else {
horizontalCounter = 0;
verticalCounter = 0;
doneCounter = 0;
console.log('donecounter reset')
verticalStart = y3;
//y2 = y3;
breakThis = true;
break;
}
}
if(breakAll == true) {
break;
}
if(breakThis = true) {
break;
}
}
if(breakThis = true) {
breakThis = false;
break;
}
}
if(breakAll == true) {
break;
}
var tempStandardR2 = jimp.intToRGBA(image.getPixelColor(x,y2)).r;
var tempStandardG2 = jimp.intToRGBA(image.getPixelColor(x,y2)).g;
var tempStandardB2 = jimp.intToRGBA(image.getPixelColor(x,y2)).b;
if((((tempStandardR - tempStandardR2) <= 20) && ((tempStandardR - tempStandardR2) >= -20)) && (((tempStandardG - tempStandardG2) <= 20) && ((tempStandardG - tempStandardG2) >= -20)) && (((tempStandardB - tempStandardB2) <= 20) && ((tempStandardB - tempStandardB2) >= -20))) {
verticalCounter++;
}
else {
verticalCounter = 0;
verticalStart = y2;
console.log('lvl1 reset')
doneCounter = 0;
break;
}
}
}
}
console.log(' done');
console.log(FINALX + " = x")
console.log(FINALY + " = y")
})
.catch(err => {
console.log(err);
})
Each of the tempStandards are the RGB value for that individual pixel.
All of the for loops are to get a 40 by 40 open grid.
The issue I do see is a problem, but am baffled as to why, is doneCounter, that is supposed to ++ every time a horizontal counter has reached 40 and thus finished its horizontal check of one row of the 40 by 40 grid.
The issue when console logging doneCounter is, it console logs the same value twice, which makes no sense since its within the same for loop that has an if else statement that either adds to donecounter or resets it to 0.
EDIT: I scrapped the above code to try and remake it entirely to see if that would let it work, still failed though and not a clue as to why: Below is the updated attempt:
jimp.read('jeffrey.png')
.then(image => {
console.log(jimp.intToRGBA(image.getPixelColor(0,0)))
console.log(image.bitmap.width)
console.log(image.bitmap.height)
var breakAll = false;
var FINALX;
var FINALY;
var doneCounter = 0;
var veritcalCounter = 0;
var verticalStart = 0;
var horizontalCounter = 0;
var breakAll = false;
var breakThis = false;
//40 by 40 pixels needed for qr code. Thisis barcode, so make it 40 by 80 or smthn, figure out that x thing.
for(var x = 0; x < image.bitmap.width; x++) {
console.log(x)
verticalCounter = 0;
for(var y = 0; y < image.bitmap.height; y++) {
var tempStandardR = jimp.intToRGBA(image.getPixelColor(x,verticalStart)).r;
var tempStandardG = jimp.intToRGBA(image.getPixelColor(x,verticalStart)).g;
var tempStandardB = jimp.intToRGBA(image.getPixelColor(x,verticalStart)).b;
var tempStandardR2 = jimp.intToRGBA(image.getPixelColor(x,y)).r;
var tempStandardG2 = jimp.intToRGBA(image.getPixelColor(x,y)).g;
var tempStandardB2 = jimp.intToRGBA(image.getPixelColor(x,y)).b;
if((((tempStandardR - tempStandardR2) <= 20) && ((tempStandardR - tempStandardR2) >= -20)) && (((tempStandardG - tempStandardG2) <= 20) && ((tempStandardG - tempStandardG2) >= -20)) && (((tempStandardB - tempStandardB2) <= 20) && ((tempStandardB - tempStandardB2) >= -20))) {
verticalCounter++;
if(verticalCounter == 40) {
verticalCounter = 0;
for(var y1 = y-40; y1 < y; y1++) {
horizontalCounter = 0;
for(var x1 = x; x1 < x+41; x1++) {
var tempStandardR3 = jimp.intToRGBA(image.getPixelColor(x,y1)).r;
var tempStandardG3 = jimp.intToRGBA(image.getPixelColor(x,y1)).g;
var tempStandardB3 = jimp.intToRGBA(image.getPixelColor(x1,y1)).b;
var tempStandardR4 = jimp.intToRGBA(image.getPixelColor(x1,y1)).r;
var tempStandardG4 = jimp.intToRGBA(image.getPixelColor(x1,y1)).g;
var tempStandardB4 = jimp.intToRGBA(image.getPixelColor(x1,y1)).b;
if((((tempStandardR3 - tempStandardR4) <= 20) && ((tempStandardR3 - tempStandardR4) >= -20)) && (((tempStandardG3 - tempStandardG4) <= 20) && ((tempStandardG3 - tempStandardG4) >= -20)) && (((tempStandardB3 - tempStandardB4) <= 20) && ((tempStandardB3 - tempStandardB4) >= -20))) {
if(x1 == x+40) {
doneCounter++;
if(doneCounter == 39) {
//SUCESS!!!!!!
//THE SPOT HAS BEEN FOUND AT (x minus 40, y minus 40).
//insert other image in this image at above coordinates. Wow I highly doubt this works.
console.log('SUCESS!!!!!!!!!')
FINALX = x;
FINALY = y1-40;
breakAll = true;
break;
}
break;
}
}
else {
verticalCounter = 0;
horizontalCounter = 0;
doneCounter = 0;
y = y1;
breakThis = true;
break;
}
if(breakAll == true) {
break;
}
}
if(breakThis == true) {
breakThis = false;
break;
}
if(breakAll == true) {
break;
}
}
if(breakAll == true) {
break;
}
}
if(breakAll == true) {
break;
}
}
else {
verticalCounter = 0;
verticalStart = 0;
}
if(breakAll == true) {
break;
}
}
if(breakAll == true) {
break;
}
}
console.log(' done');
console.log(FINALX + " = x")
console.log(FINALY + " = y")
})
.catch(err => {
console.log(err);
})

jQuery & Javascript to Highlight and Crossout HTML Content

Highlight and Crossout values i am storing to database so, we can remain next time in questions I just want to be worked highlight and crossout in html using jquery same way or another way.
I am trying this code and sometimes it generates problem while calling jQuery functions it generates double output while when we do highlight questions and crossout on html content sometimes highlight and crossout also not working with selecting using Ctrl+A or select all with my code.
Click Here For Output
HTML:
<style>
.highlight{background:yellow;}
.crossout{text-decoration: line-through;}
</style>
<input type="button" onClick="return false;" id="btn_highlight" unselectable="on" value="highlight" class="unselectable" alt="highlight" width="36" height="38">
<input type="button" onClick="return false;" id="btn_crossout" unselectable="on" value="crossout" class="unselectable" alt="crossout" width="36" height="38" />
<input name="highlight" id="highlight" type="text" value=""/>
<input name="crossout" id="crossout" type="text" value=""/>
<div class="highlight_area">
<div id="high" class="question_area">
<div class="question_stem">
<p>A 47-year-old male with chronic kidney disease and peptic ulcer disease presents to the emergency room with chest pain. The patient states the pain increases with breathing and radiates to his back but improves with leaning forward. He states that he recently had a viral upper respiratory infection that left him with a cough for the past 3 weeks. An echocardiogram is ordered which appears normal. EKG shows diffuse ST segment elevations with PR depression. What is the most appropriate treatment at this time?</p>
</div>
<br>
</div>
<div class="input radio"><input type="radio" name="data[Answer][answer]" id="answer11" value="1"><label for="answer11">A. NSAID only</label></div>
<div class="input radio"><input type="radio" name="data[Answer][answer]" id="answer22" value="2"><label for="answer22">B. Colchicine only</label></div>
<div class="input radio"><input type="radio" name="data[Answer][answer]" id="answer33" value="3"><label for="answer33">C. NSAIDS and colchicine</label></div>
<div class="input radio"><input type="radio" name="data[Answer][answer]" id="answer44" value="4"><label for="answer44">D. Corticosteroids</label></div>
<div class="input radio"><input type="radio" name="data[Answer][answer]" id="answer55" value="5"><label for="answer55">E. Dialysis</label></div>
<input type="hidden" name="data[Answer][correct]" value="2" id="AnswerCorrect">
</div>
JQUERY:
$(document).on('click', '#btn_highlight', function() {
select('#highlight');
apply('highlight');
});
$(document).on('click', '#btn_crossout', function() {
select('#crossout');
apply('crossout');
});
function select(id) {
function append(id, begin, end) {
// console.log('Add: ' + begin + ' to ' + end);
var highlights = $(id).val().trim().split(',');
var start = -1;
var done = -1;
var duplicate = -1;
var inside = -1;
var out = [];
var previous = 99999999;
var on = false;
for (x in highlights) {
var mark = highlights[x];
if (!mark) continue;
// console.log('Check: ' + mark + ' Start: ' + start + ' End: ' + done);
if (duplicate == mark) {
// console.log('Repeated mark');
out.push(mark);
}
if (done >= 0) {
out.push(mark);
continue;
} else if (start < 0) {
if (end < mark) {
// console.log('Prepend new');
out.push(begin);
out.push(end);
out.push(mark);
start = mark;
done = end;
} else if (end == mark || begin < mark) {
if (!on && end <= mark) {
// console.log('Prepend consecutive');
out.push(begin);
out.push(end);
out.push(mark);
done = mark;
} else if (on) {
// console.log('Start inside');
inside = begin
} else {
// console.log('Start new');
out.push(begin);
}
start = begin;
} else if (begin == mark) {
// console.log('Start overlapped');
duplicate = mark;
start = mark;
} else {
// console.log('Skip one');
out.push(mark);
}
}
if (done < 0 && start >= 0) {
if (end == mark) {
if (inside >= 0) {
// console.log('End overlapped from inside');
out.push(inside);
on = !on;
} else if (duplicate < 0) {
// console.log('End overlapped from outside');
out.push(end);
}
done = mark;
} else if (end > previous && end < mark) {
if (!on || duplicate >= 0) {
// console.log('End new');
out.push(end);
}
out.push(mark);
done = mark;
}
}
on = !on;
// console.log(out);
previous = mark;
}
if (done < 0) {
if (duplicate >= 0 && begin == mark) {
out.push(begin);
out.push(begin);
out.push(end);
} else {
if (start < 0) {
out.push(begin);
} else if (duplicate >= 0) {
// console.log('End from duplicate');
out.push(duplicate);
}
out.push(end);
}
}
$(id).val(out.toString().trim(','));
// console.log(id + ': ' + $(id).val());
if (out.length % 2 != 0) {
console.log('Error!');
}
}
var temp = '#temp';
function getIndex(elem, offset) {
var parent = $(elem).parents('.highlight_area');
elem.nodeValue = temp + elem.nodeValue;
var text = parent.text();
var add = text.indexOf(temp);
offset = offset + add;
elem.nodeValue = elem.nodeValue.substr(temp.length);
return offset;
}
function getIndex2(elem, offset) {
var parent = elem.parents('.highlight_area');
elem.text(temp + elem.text());
var text = parent.text();
var add = text.indexOf(temp);
offset = offset + add;
elem.text(elem.text().substr(temp.length));
return offset;
}
function getElem(node) {
if (node.is('.highlight,.crossout')) {
node = node.parent();
}
return node;
}
var highlight = window.getSelection();
// console.log(highlight);
var base = highlight.focusNode;
var anchor = highlight.anchorNode;
var baseOffset = highlight.focusOffset;
var anchorOffset = highlight.anchorOffset;
if (!highlight.rangeCount || !$(base).parents('.highlight_area').length || !$(anchor).parents('.highlight_area').length) {
// console.log(highlight.rangeCount + ' ; ' + $(base).parents('.highlight_area').length + ' ; ' + $(anchor).parents('.highlight_area').length);
return;
}
baseOffset = getIndex(base, baseOffset);
anchorOffset = getIndex(anchor, anchorOffset);
var stem = $('.highlight_area');
var baseIndex = getElem($(base.parentElement)).index();
var anchorIndex = getElem($(anchor.parentElement)).index();
var start = Math.min(baseOffset, anchorOffset);
var end = Math.max(baseOffset, anchorOffset);
// console.log('Offset: ' + start + ' to ' + end);
// console.log('Indexes: ' + baseIndex + ' v ' + anchorIndex);
if (baseIndex == anchorIndex) {
append(id, start, end);
} else {
var children = stem.find(':not(.highlight,.crossout)');
var startIndex = Math.min(baseIndex, anchorIndex);
var endIndex = Math.max(baseIndex, anchorIndex);
var child = $(children[startIndex]);
var text = child.text();
var textStart = getIndex2(child, text.length);
append(id, start, textStart);
for (var i = startIndex + 1; i < endIndex; i++) {
child = $(children[i]);
text = child.text();
if (!text.trim().length) continue;
append(id, textStart, textStart + text.length);
textStart = textStart + text.length;
}
var child = $(children[endIndex]);
var textStart = getIndex2(child, 0);
append(id, textStart, end);
}
}
function apply() {
var highlights = $('#highlight').val().split(',');
var crossouts = $('#crossout').val().split(',');
var marks = {};
for (x in highlights) {
if (typeof marks[highlights[x]] != 'undefined') {
// 2 consecutive highlights
marks[highlights[x]] = 4;
} else {
marks[highlights[x]] = 1;
}
}
for (x in crossouts) {
if (typeof marks[crossouts[x]] == 'undefined') {
marks[crossouts[x]] = 2;
} else {
if (marks[crossouts[x]] == 4) {
// 2 highlights and a crossout
marks[crossouts[x]] = 6;
} else if (marks[crossouts[x]] == 2) {
// 2 consecutive crossouts
marks[crossouts[x]] = 5;
} else if (marks[crossouts[x]] == 6) {
// 2 consecutive highlights and crossouts
marks[crossouts[x]] = 7;
} else if (marks[crossouts[x]] == 3) {
// 2 consecutive crossouts and highlight
marks[crossouts[x]] = 8;
} else {
// highlight and crossout
marks[crossouts[x]] = 3;
}
}
}
var stem = $('.highlight_area');
var children = stem.find(':not(.highlight,.crossout)');
var childIndex = 0;
var child = $(children[childIndex]);
var text = child.text().replace(/(<([^>]+)>)/ig, "");
var high = false;
var cross = false;
var previousMark = 0;
var passedChars = 0;
var mode = 0;
var string = '';
var nextEdge = 0;
stem.empty();
child.empty();
var first = true;
var maxLoop = 10;
for (x in marks) {
if (x == '') continue;
// console.log('Mark: ' + x);
nextEdge = 1 * passedChars + 1 * text.length;
// console.log('Next edge: ' + nextEdge);
var loopCount = 0;
while (x > nextEdge && loopCount++ < maxLoop) {
string = text.substr(previousMark - passedChars);
stem.append(child.append(string));
passedChars = 1 * passedChars + 1 * text.length;
previousMark = passedChars;
// move on to next
childIndex = childIndex + 1;
child = $(children[childIndex]);
text = child.text();
child.empty();
nextEdge = 1 * text.length + 1 * passedChars;
// console.log('Next edge : ' + nextEdge);
}
// console.log('Select: ' + previousMark + ' to ' + x);
string = text.substr(previousMark - passedChars, x - previousMark);
// console.log(string);
var type = '';
if (high) {
type = type + ' highlight';
}
if (cross) {
type = type + ' crossout';
}
if (type) {
var span = $('<span></span>').addClass(type);
span.text(string);
child.append(span);
} else {
child.append(string);
}
previousMark = x;
if (marks[x] == 1) {
high = !high;
} else if (marks[x] == 2) {
cross = !cross;
} else if (marks[x] == 3) {
high = !high;
cross = !cross;
} else if (marks[x] == 4) {
high = true;
} else if (marks[x] == 5) {
cross = true;
} else if (marks[x] == 6) {
high = true;
cross = !cross;
} else if (marks[x] == 7) {
high = true;
cross = true;
} else if (marks[x] == 8) {
high = !high;
cross = true;
}
}
string = text.substr(previousMark - passedChars);
stem.append(child.append(string));
childIndex = childIndex + 1;
while (childIndex < children.length) {
child = $(children[childIndex]);
child.find('.highlight,.crossout').each(function(i, e) {
child.html(child.html().replace($(e).outerHtml(), $(e).text()));
});
stem.append(child);
childIndex = childIndex + 1;
}
}
apply();
Click Here For Output

Highlight & Crossout issues in HTML Content using jQuery & Javascript

I have problem while calling jquery functions it generates double output while when we do highlight questions and crossout on html content sometimes highlight and crossout also not working with selecting using Ctrl+A or select all.
highlight and crossout values i am storing to database so, we can remain next time in questions.
I am trying and just needs to works it well.
Click Here For Output
HTML Code
<style>
.highlight{background:yellow;}
.crossout{text-decoration: line-through;}
</style>
<input type="button" onClick="return false;" id="btn_highlight" unselectable="on" value="highlight" class="unselectable" alt="highlight" width="36" height="38">
<input type="button" onClick="return false;" id="btn_crossout" unselectable="on" value="crossout" class="unselectable" alt="crossout" width="36" height="38" />
<input name="highlight" id="highlight" type="text" value=""/>
<input name="crossout" id="crossout" type="text" value=""/>
<div class="highlight_area">
<div id="high" class="question_area">
<div class="question_stem">
<p>A 47-year-old male with chronic kidney disease and peptic ulcer disease presents to the emergency room with chest pain. The patient states the pain increases with breathing and radiates to his back but improves with leaning forward. He states that he recently had a viral upper respiratory infection that left him with a cough for the past 3 weeks. An echocardiogram is ordered which appears normal. EKG shows diffuse ST segment elevations with PR depression. What is the most appropriate treatment at this time?</p>
</div>
<br>
</div>
<div class="input radio"><input type="radio" name="data[Answer][answer]" id="answer11" value="1"><label for="answer11">A. NSAID only</label></div>
<div class="input radio"><input type="radio" name="data[Answer][answer]" id="answer22" value="2"><label for="answer22">B. Colchicine only</label></div>
<div class="input radio"><input type="radio" name="data[Answer][answer]" id="answer33" value="3"><label for="answer33">C. NSAIDS and colchicine</label></div>
<div class="input radio"><input type="radio" name="data[Answer][answer]" id="answer44" value="4"><label for="answer44">D. Corticosteroids</label></div>
<div class="input radio"><input type="radio" name="data[Answer][answer]" id="answer55" value="5"><label for="answer55">E. Dialysis</label></div>
<input type="hidden" name="data[Answer][correct]" value="2" id="AnswerCorrect">
</div>
jQuery Code
$(document).on('click', '#btn_highlight', function() {
select('#highlight');
apply('highlight');
});
$(document).on('click', '#btn_crossout', function() {
select('#crossout');
apply('crossout');
});
function select(id) {
function append(id, begin, end) {
// console.log('Add: ' + begin + ' to ' + end);
var highlights = $(id).val().trim().split(',');
var start = -1;
var done = -1;
var duplicate = -1;
var inside = -1;
var out = [];
var previous = 99999999;
var on = false;
for (x in highlights) {
var mark = highlights[x];
if (!mark) continue;
// console.log('Check: ' + mark + ' Start: ' + start + ' End: ' + done);
if (duplicate == mark) {
// console.log('Repeated mark');
out.push(mark);
}
if (done >= 0) {
out.push(mark);
continue;
} else if (start < 0) {
if (end < mark) {
// console.log('Prepend new');
out.push(begin);
out.push(end);
out.push(mark);
start = mark;
done = end;
} else if (end == mark || begin < mark) {
if (!on && end <= mark) {
// console.log('Prepend consecutive');
out.push(begin);
out.push(end);
out.push(mark);
done = mark;
} else if (on) {
// console.log('Start inside');
inside = begin
} else {
// console.log('Start new');
out.push(begin);
}
start = begin;
} else if (begin == mark) {
// console.log('Start overlapped');
duplicate = mark;
start = mark;
} else {
// console.log('Skip one');
out.push(mark);
}
}
if (done < 0 && start >= 0) {
if (end == mark) {
if (inside >= 0) {
// console.log('End overlapped from inside');
out.push(inside);
on = !on;
} else if (duplicate < 0) {
// console.log('End overlapped from outside');
out.push(end);
}
done = mark;
} else if (end > previous && end < mark) {
if (!on || duplicate >= 0) {
// console.log('End new');
out.push(end);
}
out.push(mark);
done = mark;
}
}
on = !on;
// console.log(out);
previous = mark;
}
if (done < 0) {
if (duplicate >= 0 && begin == mark) {
out.push(begin);
out.push(begin);
out.push(end);
} else {
if (start < 0) {
out.push(begin);
} else if (duplicate >= 0) {
// console.log('End from duplicate');
out.push(duplicate);
}
out.push(end);
}
}
$(id).val(out.toString().trim(','));
// console.log(id + ': ' + $(id).val());
if (out.length % 2 != 0) {
console.log('Error!');
}
}
var temp = '#temp';
function getIndex(elem, offset) {
var parent = $(elem).parents('.highlight_area');
elem.nodeValue = temp + elem.nodeValue;
var text = parent.text();
var add = text.indexOf(temp);
offset = offset + add;
elem.nodeValue = elem.nodeValue.substr(temp.length);
return offset;
}
function getIndex2(elem, offset) {
var parent = elem.parents('.highlight_area');
elem.text(temp + elem.text());
var text = parent.text();
var add = text.indexOf(temp);
offset = offset + add;
elem.text(elem.text().substr(temp.length));
return offset;
}
function getElem(node) {
if (node.is('.highlight,.crossout')) {
node = node.parent();
}
return node;
}
var highlight = window.getSelection();
// console.log(highlight);
var base = highlight.focusNode;
var anchor = highlight.anchorNode;
var baseOffset = highlight.focusOffset;
var anchorOffset = highlight.anchorOffset;
if (!highlight.rangeCount || !$(base).parents('.highlight_area').length || !$(anchor).parents('.highlight_area').length) {
// console.log(highlight.rangeCount + ' ; ' + $(base).parents('.highlight_area').length + ' ; ' + $(anchor).parents('.highlight_area').length);
return;
}
baseOffset = getIndex(base, baseOffset);
anchorOffset = getIndex(anchor, anchorOffset);
var stem = $('.highlight_area');
var baseIndex = getElem($(base.parentElement)).index();
var anchorIndex = getElem($(anchor.parentElement)).index();
var start = Math.min(baseOffset, anchorOffset);
var end = Math.max(baseOffset, anchorOffset);
// console.log('Offset: ' + start + ' to ' + end);
// console.log('Indexes: ' + baseIndex + ' v ' + anchorIndex);
if (baseIndex == anchorIndex) {
append(id, start, end);
} else {
var children = stem.find(':not(.highlight,.crossout)');
var startIndex = Math.min(baseIndex, anchorIndex);
var endIndex = Math.max(baseIndex, anchorIndex);
var child = $(children[startIndex]);
var text = child.text();
var textStart = getIndex2(child, text.length);
append(id, start, textStart);
for (var i = startIndex + 1; i < endIndex; i++) {
child = $(children[i]);
text = child.text();
if (!text.trim().length) continue;
append(id, textStart, textStart + text.length);
textStart = textStart + text.length;
}
var child = $(children[endIndex]);
var textStart = getIndex2(child, 0);
append(id, textStart, end);
}
}
function apply() {
var highlights = $('#highlight').val().split(',');
var crossouts = $('#crossout').val().split(',');
var marks = {};
for (x in highlights) {
if (typeof marks[highlights[x]] != 'undefined') {
// 2 consecutive highlights
marks[highlights[x]] = 4;
} else {
marks[highlights[x]] = 1;
}
}
for (x in crossouts) {
if (typeof marks[crossouts[x]] == 'undefined') {
marks[crossouts[x]] = 2;
} else {
if (marks[crossouts[x]] == 4) {
// 2 highlights and a crossout
marks[crossouts[x]] = 6;
} else if (marks[crossouts[x]] == 2) {
// 2 consecutive crossouts
marks[crossouts[x]] = 5;
} else if (marks[crossouts[x]] == 6) {
// 2 consecutive highlights and crossouts
marks[crossouts[x]] = 7;
} else if (marks[crossouts[x]] == 3) {
// 2 consecutive crossouts and highlight
marks[crossouts[x]] = 8;
} else {
// highlight and crossout
marks[crossouts[x]] = 3;
}
}
}
var stem = $('.highlight_area');
var children = stem.find(':not(.highlight,.crossout)');
var childIndex = 0;
var child = $(children[childIndex]);
var text = child.text().replace(/(<([^>]+)>)/ig, "");
var high = false;
var cross = false;
var previousMark = 0;
var passedChars = 0;
var mode = 0;
var string = '';
var nextEdge = 0;
stem.empty();
child.empty();
var first = true;
var maxLoop = 10;
for (x in marks) {
if (x == '') continue;
// console.log('Mark: ' + x);
nextEdge = 1 * passedChars + 1 * text.length;
// console.log('Next edge: ' + nextEdge);
var loopCount = 0;
while (x > nextEdge && loopCount++ < maxLoop) {
string = text.substr(previousMark - passedChars);
stem.append(child.append(string));
passedChars = 1 * passedChars + 1 * text.length;
previousMark = passedChars;
// move on to next
childIndex = childIndex + 1;
child = $(children[childIndex]);
text = child.text();
child.empty();
nextEdge = 1 * text.length + 1 * passedChars;
// console.log('Next edge : ' + nextEdge);
}
// console.log('Select: ' + previousMark + ' to ' + x);
string = text.substr(previousMark - passedChars, x - previousMark);
// console.log(string);
var type = '';
if (high) {
type = type + ' highlight';
}
if (cross) {
type = type + ' crossout';
}
if (type) {
var span = $('<span></span>').addClass(type);
span.text(string);
child.append(span);
} else {
child.append(string);
}
previousMark = x;
if (marks[x] == 1) {
high = !high;
} else if (marks[x] == 2) {
cross = !cross;
} else if (marks[x] == 3) {
high = !high;
cross = !cross;
} else if (marks[x] == 4) {
high = true;
} else if (marks[x] == 5) {
cross = true;
} else if (marks[x] == 6) {
high = true;
cross = !cross;
} else if (marks[x] == 7) {
high = true;
cross = true;
} else if (marks[x] == 8) {
high = !high;
cross = true;
}
}
string = text.substr(previousMark - passedChars);
stem.append(child.append(string));
childIndex = childIndex + 1;
while (childIndex < children.length) {
child = $(children[childIndex]);
child.find('.highlight,.crossout').each(function(i, e) {
child.html(child.html().replace($(e).outerHtml(), $(e).text()));
});
stem.append(child);
childIndex = childIndex + 1;
}
}
apply();

How to use AJAX or JSON in this code?

I am creating a website application that allows users to select a seat, if it is not already reserved, and reserve it.
I have created a very round about way of getting the seats that are previously reserved using iFrames, however that was temporarily, now I need to make it secure and "proper javascript code" using proper practices. I have no clue what AJAX (or JSON) is, nor how to add it to this code, but it needs to get the file "seatsReserved"+this.id(that is the date)+"Que.html" and compare the string of previously reserved seats to see which class to make the element. If this is horrible, or if any of the other things could work better, I am open to criticism to everything. Thank you all!
Here is the javascript code:
A little side note, all of the if statements are due to different amount of seats in each row
<script>
var i = " 0 ";
var counter = 0;
var leng=0;
document.getElementById("Show1").addEventListener("click", changeDay);
document.getElementById("Show2").addEventListener("click", changeDay);
document.getElementById("Show3").addEventListener("click", changeDay);
function changeDay() {
var iFrame = document.getElementById("seatList");
iFrame.src = "seatsReserved" + this.id + "Que.html";
document.getElementById('date').innerHTML = this.id;
var seatsTaken = iFrame.contentWindow.document.body.innerHTML;
var k = 0;
let = 'a';
var lc = 0;
for (lc = 1; lc <= 14; lc++) {
if (lc == 1) {
leng = 28;
}
else if (lc == 2) {
leng = 29;
}
else if (lc == 3) {
leng = 32;
}
else if (lc == 4 || lc == 6 || lc == 12 || lc == 14) {
leng = 33;
}
else if (lc == 5 || lc == 13) {
leng = 34;
}
else if (lc == 8 || lc == 10) {
leng = 35;
}
else {
leng = 36;
}
for (k = 1; k <= leng; k++) {
if (seatsTaken.indexOf((" " +
let +k + " ")) <= -1) {
seat = document.getElementById(let +k);
seat.removeEventListener("click", selectedSeat);
}
else {
document.getElementById(let +k).className = "openseat";
document.getElementById(let +k).removeEventListener("click", doNothing);
}
}
let = String.fromCharCode(let.charCodeAt(0) + 1);
}
}
function loadChanges() {
var iFrame = document.getElementById("seatList");
var seatsTaken = iFrame.contentWindow.document.body.innerHTML;
var k = 0;
let = 'a';
var lc = 0;
var leng = 0;
for (lc = 1; lc <= 14; lc++) {
if (lc == 1) {
leng = 28;
}
else if (lc == 2) {
leng = 29;
}
else if (lc == 3) {
leng = 32;
}
else if (lc == 4 || lc == 6 || lc == 12 || lc == 14) {
leng = 33;
}
else if (lc == 5 || lc == 13) {
leng = 34;
}
else if (lc == 8 || lc == 10) {
leng = 35;
}
else {
leng = 36;
}
for (k = 1; k <= leng; k++) {
if (seatsTaken.indexOf((" " +
let +k + " ")) <= -1) {
seat = document.getElementById(let +k);
seat.addEventListener("click", selectedSeat);
seat.className = "openseat";
}
else {
document.getElementById(let +k).className = "notAvailible";
document.getElementById(let +k).addEventListener("click", doNothing);
}
}
let = String.fromCharCode(let.charCodeAt(0) + 1);
}
i = " 0 ";
counter = 0;
document.getElementById("seatString").innerHTML = i;
document.getElementById("getSeats").value = i;
document.getElementById("seatnums").innerHTML = counter;
}
i = document.getElementById("seatString").innerHTML;
counter = document.getElementById("seatnums").innerHTML;
function selectedSeat() {
var w = this.id;
var l = (" " + w);
var b = (" " + w + " ");
if (counter < 5) {
if (i.indexOf(b) <= 0) {
this.className = "closedseat";
i = i + b;
i = i.replace(" 0 ", " ");
document.getElementById("seatString").innerHTML = i;
document.getElementById("getSeats").value = i;
counter = counter + 1;
document.getElementById("seatnums").innerHTML = counter;
}
else if (i.indexOf(b) > 0) {
this.className = "openseat";
i = i.replace(b, "");
document.getElementById("seatString").innerHTML = i;
document.getElementById("getSeats").value = i;
counter = counter - 1;
document.getElementById("seatnums").innerHTML = counter;
}
}
else if (i.indexOf(b) > 0) {
this.className = "openseat";
i = i.replace(b, "");
document.getElementById("seatString").innerHTML = i;
document.getElementById("getSeats").value = i;
counter = counter - 1;
document.getElementById("seatnums").innerHTML = counter;
}
}
function doNothing() {
}
var rannum = Math.random() * 1000;
document.getElementById('getConfirmation').value = rannum;
</script>

Javascript Check variable.Then gain ++ per second

I have a problem i want to check a variable.If its 0 then gain ++ after 1.5s.If its 10 then gain ++ after .4s.Its complicated.It doesnt really work.My code so far:
if(road == 1){setInterval(function(){stamina = stamina+1;document.getElementById("stamina").innerHTML = stamina;},1400);}
else if(road == 2){setInterval(function(){stamina = stamina+1;document.getElementById("stamina").innerHTML = stamina;},1300);}
else if(road == 3){setInterval(function(){stamina = stamina+1;document.getElementById("stamina").innerHTML = stamina;},1200);}
else if(road == 4){setInterval(function(){stamina = stamina+1;document.getElementById("stamina").innerHTML = stamina;},1100);}
else if(road == 5){setInterval(function(){stamina = stamina+1;document.getElementById("stamina").innerHTML = stamina;},1000);}
else if(road == 6){setInterval(function(){stamina = stamina+1;document.getElementById("stamina").innerHTML = stamina;},900);}
else if(road == 7){setInterval(function(){stamina = stamina+1;document.getElementById("stamina").innerHTML = stamina;},800);}
else if(road == 8){setInterval(function(){stamina = stamina+1;document.getElementById("stamina").innerHTML = stamina;},600);}
else if(road == 9){setInterval(function(){stamina = stamina+1;document.getElementById("stamina").innerHTML = stamina;},400);}
else if(road == 10){setInterval(function(){stamina = stamina+1;document.getElementById("stamina").innerHTML = stamina;},200);}
else{setInterval(function(){stamina++;document.getElementById("stamina").innerHTML = stamina;},1500);}
And the code to build a road is this:
function build_road() {
if ((wood + tavern) >= 29 && stone > 4 && road < 10) {
road++;
document.getElementById("road_count").innerHTML = road;
wood = (wood + tavern) - 20;
stone = stone - 5;
document.getElementById("wood").innerHTML = wood;
document.getElementById("stone").innerHTML = stone;
exp = exp + 20;
var x = document.getElementById("PROGRESS");
x.setAttribute("value", exp);
x.setAttribute("max", max);
if (exp == 100) {
exp = 0;
level++;
document.getElementById("level").innerHTML = level;
}
alert("Congratulations,You've create a Road,Now you gain stamina slightly faster.");
}
else {
alert("You need: 30Wood,5Stone .Maximum 10 Roads.")
}
}
Make reusable functions (it's often a good practice, when you a difficulties with a piece of code, to break it into small functions):
var staminaIncreaseTimer = null;
function configureStaminaIncrease(delay) {
if (staminaIncreaseTimer !== null)
clearInterval(staminaIncreaseTimer);
staminaIncreaseTimer = setInterval(function () {
increaseStamina();
}, delay);
}
function increaseStamina() {
stamina += 1;
document.getElementById("stamina").innerHTML = stamina;
}
Solution with an array (suggested by Jay Harris)
var roadIndex = road-1;
var ROAD_DELAYS = [1400, 1300, 1200, /*...*/];
var DEFAULT_DELAY = 1500;
if (roadIndex < ROAD_DELAYS.length) {
configureStaminaIncrease(ROAD_DELAYS[roadIndex]);
} else {
configureStaminaIncrease(DEFAULT_DELAY);
}
Solution with a switch instead of you if-elseif mess:
switch (road) {
case 1:
configureStaminaIncrease(1400);
break;
case 2:
configureStaminaIncrease(1300);
break;
case 3:
configureStaminaIncrease(1200);
break;
//and so on...
default:
configureStaminaIncrease(1500);
}

Categories

Resources