I am new to JavaScript. I would like to add to add two buttons for my visitors to control font size. I would like to include two tags - 'p' and 'blockquote". Can you please help me edit this code in order to include both?
var min = 8;
var max = 18;
function increaseFontSize() {
var p = document.getElementsByTagName('p');
for (i = 0; i < p.length; i++) {
if (p[i].style.fontSize) {
var s = parseInt(p[i].style.fontSize.replace("px", ""));
} else {
var s = 12;
} if (s != max) {
s += 1;
}
p[i].style.fontSize = s + "px"
}
}
function decreaseFontSize() {
var p = document.getElementsByTagName('p');
for (i = 0; i < p.length; i++) {
if (p[i].style.fontSize) {
var s = parseInt(p[i].style.fontSize.replace("px", ""));
} else {
var s = 12;
} if (s != min) {
s -= 1;
}
p[i].style.fontSize = s + "px"
}
}
Thank you.
Here's a working version:
http://jsfiddle.net/ny4p7pg9/
I took the liberty of refactoring a bit the functions to make the code more parameterized.
function changeFontSize(delta) {
var tags = document.querySelectorAll('p,blockquote');
for (i = 0; i < tags.length; i++) {
if (tags[i].style.fontSize) {
var s = parseInt(tags[i].style.fontSize.replace("px", ""));
} else {
var s = 12;
} if (s != max) {
s += delta;
}
tags[i].style.fontSize = s + "px"
}
}
function increaseFontSize() {
changeFontSize(1);
}
function decreaseFontSize() {
changeFontSize(-1);
}
Instead of using:
p = document.getElementsByTagName('p');
you could, instead use:
elems = document.querySelectorAll('p, blockquote');
(the variable name is irrelevant, and was changed only because the elements are no longer exclusively <p> elements):
function increaseFontSize() {
var elems = document.querySelectorAll('p, blockquote');
for (i = 0; i < elems.length; i++) {
if (elems[i].style.fontSize) {
var s = parseInt(elems[i].style.fontSize.replace("px", ""));
} else {
var s = 12;
} if (s != max) {
s += 1;
}
elems[i].style.fontSize = s + "px"
}
}
var min = 8;
var max = 18;
function increaseFontSize() {
var elems = document.querySelectorAll('p, blockquote');
for (i = 0; i < elems.length; i++) {
if (elems[i].style.fontSize) {
var s = parseInt(elems[i].style.fontSize.replace("px", ""));
} else {
var s = 12;
} if (s != max) {
s += 1;
}
elems[i].style.fontSize = s + "px"
}
}
function decreaseFontSize() {
var elems = document.querySelectorAll('p, blockquote');
for (i = 0; i < elems.length; i++) {
if (elems[i].style.fontSize) {
var s = parseInt(elems[i].style.fontSize.replace("px", ""));
} else {
var s = 12;
} if (s != min) {
s -= 1;
}
elems[i].style.fontSize = s + "px"
}
}
document.querySelector('#increase').addEventListener('click', increaseFontSize);
document.querySelector('#decrease').addEventListener('click', decreaseFontSize);
<button id="increase">↑A</button>
<button id="decrease">A↓</button>
<p>Some text to have its text adjusted by the buttons just up there.</p>
<blockquote>Some text in a blockquote</blockquote>
The querySelectorAll() method accepts CSS-style selectors, and returns a (non-live) NodeList, and is supported in all modern browsers, including IE from version 8 onwards.
That said, it's probably better to increase the font-size of the <body> element, otherwise font-adjustment is redundant (since other elements will still be unclear), so, instead, I'd suggest:
function increaseFontSize() {
// retrieving, and caching, the <body> element:
var body = document.body,
// finding the current computed fontSize of the <body> element, parsing it
// as a float (though parseInt() would be just as safe, really):
currentFontSize = parseFloat(window.getComputedStyle(body, null).fontSize);
// if the currentFontSize is less than the specified max:
if (currentFontSize < max) {
// we set the fontSize of the <body> to the incremented fontSize,
// increasing the current value by 1, and concatenating with the 'px' unit:
body.style.fontSize = ++currentFontSize + 'px';
}
}
function decreaseFontSize() {
var body = document.body,
currentFontSize = parseFloat(window.getComputedStyle(body, null).fontSize);
if (currentFontSize > min) {
body.style.fontSize = --currentFontSize + 'px';
}
}
var min = 8;
var max = 18;
function increaseFontSize() {
var body = document.body,
currentFontSize = parseFloat(window.getComputedStyle(body, null).fontSize);
if (currentFontSize < max) {
body.style.fontSize = ++currentFontSize + 'px';
}
}
function decreaseFontSize() {
var body = document.body,
currentFontSize = parseFloat(window.getComputedStyle(body, null).fontSize);
if (currentFontSize > min) {
body.style.fontSize = --currentFontSize + 'px';
}
}
document.querySelector('#increase').addEventListener('click', increaseFontSize);
document.querySelector('#decrease').addEventListener('click', decreaseFontSize);
<button id="increase">↑A</button>
<button id="decrease">A↓</button>
<p>Some text to have its text adjusted by the buttons just up there.</p>
<blockquote>Some text in a blockquote</blockquote>
References:
document.body.
document.querySelectorAll().
Window.getComputedStyle().
Related
I am trying to replicate a mosaic that can be found on many webpages. While looking for solutions to my problem I came accross a very good implementation on squarespace seen at https://native-demo.squarespace.com/images-native/. I have hosted my website containing the mosaic at http://alexstiles.000webhostapp.com.
My issue is that when you resize the window the horizontal spacing between the images flucuates like it has an animation instead of staying consistient. Although it sorts itself out if you resize slowly, rapid movements can cause the margin to be to large or small. This behavior is not present in the squarespace template. How can I remove this and make the margin consistient when resizing? I have already tried using css margins instead of javascript. I have added the javascript below to help.
let mosaic = document.getElementsByClassName("mosaic")[0]; // For a single mosaic for now
let numImages = 12;
let imageTopic = "design";
let originalImageTopic = "design";
let rowWidth = 3;
let scale = 1;
let mosaicLoader = document.getElementsByClassName("loader-container")[0]
let search = document.getElementById("search");
let searchBtn = document.getElementById("search-button");
let form = document.getElementsByTagName("form")[0];
function rem(rems) {
return rems * (16 * scale);
}
searchBtn.addEventListener("click", function(event) {
event.preventDefault();
searchResult(search.value);
});
search.addEventListener("click", function() {
form.classList.add("focused");
});
search.addEventListener("blur", function() {
form.classList.remove("focused");
});
document.onkeydown = checkKey;
function checkKey(e) {
e = e || window.event;
if (e.keyCode == '13' || e.which == '13' || e.key === "Enter") {
e.preventDefault();
searchResult(search.value);
}
}
if (window.location.hash) {
let hash = window.location.hash.substring(1); //Puts hash in variable, and removes the # character
search.value = hash;
searchResult(hash);
}
function searchResult(query) {
// Get and set query
query = ((query != "" && query != originalImageTopic) ? search.value : imageTopic);
imageTopic = query;
if (imageTopic != originalImageTopic) {
parent.location.hash = imageTopic;
document.getElementById("search-term").textContent = imageTopic + " pictures";
}
// Put up loader while fetching images
mosaicLoader.style.display = "flex";
// Remove old images
let length = mosaic.children.length;
while (mosaic.lastChild && length > 1) {
mosaic.removeChild(mosaic.lastChild);
length--;
}
// Create new images
let loadedImageNum = 0
for (let i = 0; i < numImages; i++) {
let image = document.createElement("img");
image.src = `https://source.unsplash.com/random?${imageTopic}/sig${i}/`;
mosaic.appendChild(image);
}
// Wait for all images to load
let loadedImages = 0;
let image = mosaic.querySelectorAll("img");
imageCheck = setInterval(function() {
for (let i = 0; i < numImages; i++) {
if (image[i].naturalHeight !== 0 && image[i].complete) {
loadedImages++;
}
if (loadedImages == numImages) {
clearInterval(imageCheck);
// alert("Loaded!")
// Lay them out
setTimeout(imagesLoaded, 2000); // Needs some time before laying out
// Break loop
break;
}
}
}, 200)
}
searchResult(imageTopic); // Inital images with no search query
window.onload = function() {
windowResizeEvents();
}
window.onresize = function() {
windowResizeEvents();
}
function windowResizeEvents() {
imagesLoaded();
}
function mosaicCalibration() {
let images = document.querySelectorAll(".mosaic img");
if (window.innerWidth < 750) {
mosaic.classList.add("column");
} else if (window.innerWidth < 1100) {
rowWidth = 2;
} else {
rowWidth = 3 // Math.round(window.innerWidth/(426 + (2/3)));
}
if (window.innerWidth > 750) {
mosaic.classList.remove("column");
for (let i = 0; i < images.length; i++) {
images[i].style.width = `calc((100% - ${((rowWidth - 1) * 1)}rem) / ${rowWidth})`;
}
}
}
function imagesLoaded() {
// Find out row width, image width, etc
mosaicCalibration();
// Remove loader and set height to 0 so new height can be calculated
mosaicLoader.style.display = "none";
mosaic.style.height = 0;
// Define variables
let images = document.querySelectorAll(".mosaic img");
let row = 0;
let rowNum = 0;
let margin = rem(1.25);
let imageWidth = ((mosaic.scrollWidth - (2 * margin)) / rowWidth);
let column = [];
for (let i = 0; i < images.length; i++) {
images[i].style.top = i > rowWidth - 1 ? column[i-rowWidth] + margin : 0;
if (row < rowWidth) {
if (window.innerWidth > 1100) {
images[i].style.left = row * imageWidth + (row >= 1 ? row * margin : 0);
} else {
images[i].style.left = row * imageWidth + (row >= 1 ? (row + 0.5) * margin : 0);
}
row++
} else {
images[i].style.left = 0;
row = 1;
rowNum++;
}
if (rowNum > 0) {
column.push(column[i-rowWidth] + images[i].scrollHeight + margin);
} else {
column.push(images[i].scrollHeight);
}
}
mosaic.style.height = mosaic.scrollHeight;
}
I am having a problem defining a class method:
this.method = function(){...}
I get an error thrown at the "." after "this".
If I declare the method directly using method(){...}, I am unable to reference it in other methods as it shows that the method is undefined.
The method I want to deifne is shuffleBoard(). How do I do it?
class Board {
constructor(size,boardId){
this.boardId = boardId;
switch(size){
case "medium":
var boardSize = 560;
var tiles = 7*7;
break;
case "large":
boardSize = 720;
tiles = 9*9;
break;
default:
boardSize = 320;
tiles = 4*4;
break;
}
var container = $(this.boardId+" .tiles-container");
var row = 0;
var loopArray = [];
for(var i = 0;i < tiles; i++){
var tile = document.createElement("div");
loopArray.push(i);
var text = i+1;
tile.setAttribute("index",i+1);
tile.id = i+1;
if(i == tiles - 1){
var empty = "empty"
}
tile.setAttribute("class","tile "+empty);
tile.innerText = text;
container.append(tile);
(function(){
tile.onclick = function(){
var tileObject = new Tile(this.getAttribute("index"));
console.log(tileObject.move());
}
})()
var prevRow = row;
if(i%4 == 0 && i != 0){
row++
}
if(row > prevRow){
var positionX = 0;
}
else{
var positionX = (i%4)*80;
}
var positionY = row*80;
tile.style.top=positionY+"px";
tile.style.left=positionX+"px";
console.log(i+"---"+row+"////"+prevRow);
}
setTimeout(function(){this.shuffleBoard(loopArray);},4000);
return container;
}
this.shuffleBoard = function(arr){
var i = 0;
console.log(this.boardId);
$(this.boardId+" .tiles-container tile").forEach(function(el){
var shuffled = shuffle(arr);
el.innerText = shuffled[i];
arr.pop(arr[i]);
i++
});
}
}
It seems like you are using ES6 syntax. In ES6 write functions like
shuffleBoard() {
// rest of the code
}
and to access it use this keyword. like this.shuffleBoard().
To call it in setTimeout, use arrow functions
setTimeout(() => { this.shuffleBoard(loopArray); }, 4000);
1.You have to use an arrow function to keep the scope, because otherwise this would be pointing to the new function created in the timeout.
setTimeout(() => {
this.shuffleBoard(loopArray);
}, 4000);
2.The constructor mustn't return anything because it prevents it from returning the object it constructs
3.jQuery uses .each() to iterate over jQuery objects instead of .forEach().
I put the notes directly in the code as comments as well:
class Board {
constructor(size, boardId) {
this.boardId = boardId;
switch (size) {
case "medium":
var boardSize = 560;
var tiles = 7 * 7;
break;
case "large":
boardSize = 720;
tiles = 9 * 9;
break;
default:
boardSize = 320;
tiles = 4 * 4;
break;
}
var container = $(this.boardId + " .tiles-container");
var row = 0;
var loopArray = [];
for (var i = 0; i < tiles; i++) {
var tile = document.createElement("div");
loopArray.push(i);
var text = i + 1;
tile.setAttribute("index", i + 1);
tile.id = i + 1;
if (i == tiles - 1) {
var empty = "empty"
}
tile.setAttribute("class", "tile " + empty);
tile.innerText = text;
container.append(tile);
(function() {
tile.onclick = function() {
var tileObject = new Tile(this.getAttribute("index"));
console.log(tileObject.move());
}
})()
var prevRow = row;
if (i % 4 == 0 && i != 0) {
row++
}
if (row > prevRow) {
var positionX = 0;
} else {
var positionX = (i % 4) * 80;
}
var positionY = row * 80;
tile.style.top = positionY + "px";
tile.style.left = positionX + "px";
console.log(i + "---" + row + "////" + prevRow);
}
setTimeout(() => { //use arrow function to keep the scope
this.shuffleBoard(loopArray);
}, 4000);
//return container; returning the container here prevents the constructor from returning the constructed object
}
shuffleBoard(arr) {
var i = 0;
console.log(this.boardId);
$(this.boardId + " .tiles-container tile").each(function(el) { //jQuery uses .each instead of forEach
var shuffled = shuffle(arr);
el.innerText = shuffled[i];
arr.pop(arr[i]);
i++
});
}
}
let board = new Board("medium", "myboard");
console.log(board.shuffleBoard);
board.shuffleBoard([]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
shuffleBoard = function(arr){
// rest of code
})
Then you can use method as:
let board = new Board()
board.shuffleBoard()
way1:move this.propertyName to constructor
class Board{
constructor(size,boardId){
this.boardId = boardId;
switch(size){
case "medium":
var boardSize = 560;
var tiles = 7*7;
break;
case "large":
boardSize = 720;
tiles = 9*9;
break;
default:
boardSize = 320;
tiles = 4*4;
break;
}
var container = $(this.boardId+" .tiles-container");
var row = 0;
var loopArray = [];
for(var i = 0;i < tiles; i++){
var tile = document.createElement("div");
loopArray.push(i);
var text = i+1;
tile.setAttribute("index",i+1);
tile.id = i+1;
if(i == tiles - 1){
var empty = "empty"
}
tile.setAttribute("class","tile "+empty);
tile.innerText = text;
container.append(tile);
(function(){
tile.onclick = function(){
var tileObject = new Tile(this.getAttribute("index"));
console.log(tileObject.move());
}
})()
var prevRow = row;
if(i%4 == 0 && i != 0){
row++
}
if(row > prevRow){
var positionX = 0;
}
else{
var positionX = (i%4)*80;
}
var positionY = row*80;
tile.style.top=positionY+"px";
tile.style.left=positionX+"px";
console.log(i+"---"+row+"////"+prevRow);
}
setTimeout(function(){this.shuffleBoard(loopArray);},4000);
this.shuffleBoard = function(arr) {
var i = 0;
console.log(this.boardId);
$(this.boardId + " .tiles-container tile").forEach(function(
el
) {
var shuffled = shuffle(arr);
el.innerText = shuffled[i];
arr.pop(arr[i]);
i++;
});
}
return container;
}
}
way2:change this.propertyName to a method in className.prototype
class Board {
constructor(size, boardId) {
this.boardId = boardId;
switch (size) {
case "medium":
var boardSize = 560;
var tiles = 7 * 7;
break;
case "large":
boardSize = 720;
tiles = 9 * 9;
break;
default:
boardSize = 320;
tiles = 4 * 4;
break;
}
var container = $(this.boardId + " .tiles-container");
var row = 0;
var loopArray = [];
for (var i = 0; i < tiles; i++) {
var tile = document.createElement("div");
loopArray.push(i);
var text = i + 1;
tile.setAttribute("index", i + 1);
tile.id = i + 1;
if (i == tiles - 1) {
var empty = "empty";
}
tile.setAttribute("class", "tile " + empty);
tile.innerText = text;
container.append(tile);
(function() {
tile.onclick = function() {
var tileObject = new Tile(this.getAttribute("index"));
console.log(tileObject.move());
};
})();
var prevRow = row;
if (i % 4 == 0 && i != 0) {
row++;
}
if (row > prevRow) {
var positionX = 0;
} else {
var positionX = (i % 4) * 80;
}
var positionY = row * 80;
tile.style.top = positionY + "px";
tile.style.left = positionX + "px";
console.log(i + "---" + row + "////" + prevRow);
}
setTimeout(function() {
this.shuffleBoard(loopArray);
}, 4000);
return container;
}
shuffleBoard(arr) {
var i = 0;
console.log(this.boardId);
$(this.boardId + " .tiles-container tile").forEach(function(el) {
var shuffled = shuffle(arr);
el.innerText = shuffled[i];
arr.pop(arr[i]);
i++;
});
}
}
I am trying to render child elements of an element if the element is in view or removing the content if not in view like below on scroll event like below
list.addEventListener('scroll', function () {
var elements = document.querySelectorAll('.aBox');
var toBe = counter - 1 - elements.length;
for (var i = 0; i < elements.length; i++) {
var inView = visibleY(elements[i]),
ele = elements[i].querySelector('.item');
if (inView === false && ele) {
console.log("Not in visible, keeping it none");
var height = elements[i].clientHeight;
elements[i].style.height = height + "px";
elements[i].innerHTML = "";
} else if(!ele){
console.log('Placing the content');
var minArray = arr[toBe + 1 + i],
str = "";
for (var j = 0; j < minArray.length; j++) {
str += "<div class='item'>" + minArray[j] + "</div>";
}
elements[i].innerHTML = str;
}
}
});
It seems working but if I have a look at the DOM this is not working as expected. Someone please help me to find the problem, fiddle.
Update
function updateData(callback) {
var elements = document.querySelectorAll('.aBox');
elements = Array.prototype.slice.call(elements);
var toBe = counter - 1 - elements.length;
async.each(elements, function (element, cb) {
var inView = $(element).is_on_screen(),
ele = element.querySelector('.item');
if (inView == false && ele) {
console.log("Not in visible, keeping it none");
var height = element.clientHeight;
element.style.height = height + "px";
element.innerHTML = "";
} else if (!ele && inView) {
console.log('Placing the content');
var minArray = arr[toBe + 1 + i],
str = "";
if (typeof minArray === "object") {
for (var j = 0; j < minArray.length; j++) {
str += "<div class='item'>" + minArray[j] + "</div>";
}
element.innerHTML = str;
}
}
cb();
}, function () {
callback()
});
}
Fiddle
Hi I have solved this problem. Posting here, so that it will be more helpful for people who want to work on mobiles to display very large lists with virtual scrolling
var arr = new Array(10000);
for (var i = 0; i < arr.length; i++) {
arr[i] = "Hello Dudes..." + i;
}
Array.prototype.chunk = function (chunkSize) {
var array = this;
return [].concat.apply([],
array.map(function (elem, i) {
return i % chunkSize ? [] : [array.slice(i, i + chunkSize)];
}));
}
arr = arr.chunk(50);
var list = document.getElementById('longList');
var button = document.getElementById('loadMore');
var counter = arr.length,
aBoxLen = 1;
function appendBox() {
var div = document.createElement('div'),
str = "";
div.className = "aBox";
var minArray = arr[counter - aBoxLen];
for (var i = 0; i < minArray.length; i++) {
str += "<div class='item'>" + minArray[i] + "</div>";
}
div.innerHTML = str;
div.setAttribute('index', counter - aBoxLen);
var box = document.querySelector('.aBox');
if (box) {
list.insertBefore(div, box);
} else {
list.appendChild(div);
}
aBoxLen += 1;
}
appendBox();
button.addEventListener('click', function () {
appendBox();
});
$.fn.is_on_screen = function () {
var win = $(window);
var viewport = {
top: win.scrollTop(),
left: win.scrollLeft()
};
viewport.right = viewport.left + win.width();
viewport.bottom = viewport.top + win.height();
var bounds = this.offset();
bounds.right = bounds.left + this.outerWidth();
bounds.bottom = bounds.top + this.outerHeight();
return (!(viewport.right < bounds.left || viewport.left > bounds.right || viewport.bottom < bounds.top || viewport.top > bounds.bottom));
};
function updateData(callback) {
var elements = document.querySelectorAll('.aBox');
elements = Array.prototype.slice.call(elements);
var toBe = counter - 1 - elements.length;
async.each(elements, function (element, cb) {
var inView = $(element).is_on_screen(),
ele = element.querySelector('.item');
if (inView == false && ele) {
console.log("Not in visible, keeping it none");
var height = element.clientHeight;
element.style.height = height + "px";
element.innerHTML = "";
} else if (!ele && inView) {
console.log('Placing the content');
console.log(element.getAttribute('index'));
var minArray = arr[element.getAttribute('index')],
str = "";
for (var j = 0; j < minArray.length; j++) {
str += "<div class='item'>" + minArray[j] + "</div>";
}
element.innerHTML = str;
}
cb();
}, function () {
// callback()
});
}
var delay = false;
var timeout = null;
list.addEventListener('touchmove', function () {
clearTimeout(timeout);
timeout = setTimeout(function () {
updateData();
}
}, delay);
});
None of the solutions were specifically designed for mobiles, so I have implemented this.
I think there is lots of space for improvement in this. If anybody want to improve it, please feel free to make it
Demo
i am new to html and js. I have created a form with the following script. i have an event handler for calculateTime. I cant seem to get the form to calculate. If you guys could point me in the right direction that would be great. Thanks
<script>
function getWaterSystem() {
var waterSystem;
var selectedSystem = 0;
for (var i = 1; i <= 4; i++) {
waterSystem = document.getElementById("system + i");
if (waterSystem.checked == true) {
waterSystem = waterSystem(i).value;
}
}
return waterSystem;
}
function largePlant() {
var checkbox;
checkbox = document.getElementById("large");
if (checkbox(i).checked) {
checkbox = 1.5;
}
else {
checkbox = "";
}
return checkbox;
}
function getSoilType() {
var soilType;
var selectedSoil = 0;
for (var i = 1; i <= 3; i++) {
soilType = document.getElementById("soil + i");
if (soilType[i].checked) {
soilType = soilType[i].value;
}
}
return soilType;
}
function calculateTime() {
var waterTime = getWaterSystem() * getSoilType() * largePlant();
alert("The recommended watering time is " + waterTime);
}
</script>
I made some adjustment, just check it out, it's quite simple:
document.getElementById("check1").checked
<script>
function getWaterSystem() {
var waterSystem=0;
var selectedSystem = 0;
for (var i = 1; i <= 4; i++) {
if (document.getElementById("system" + i).checked) {
reutrn waterSystem = document.getElementById("system" + i).value;
}
}
return waterSystem;
}
function largePlant() {
var checkbox=0;
if (document.getElementById("large").checked) {
checkbox = 1.5;
}
else {
checkbox = 0;
}
return checkbox;
}
function getSoilType() {
var soilType=0;
var selectedSoil = 0;
for (var i = 1; i <= 3; i++) {
soilType = document.getElementById("soil" + i);
if (document.getElementById("soil" + i). checked) {
soilType = document.getElementById("soil" + i).value;
return soilType;
}
}
return soilType;
}
function calculateTime() {
var waterTime = getWaterSystem() * getSoilType() * largePlant();
alert("The recommended watering time is " + waterTime);
}
</script>
Could it have something to do with these two lines:
waterSystem = document.getElementById("system + i");
soilType = document.getElementById("soil + i");
If you want to target the id of #systemX or #soilX where X is being a number from you i var. You should write it like this:
waterSystem = document.getElementById("system" + i);
soilType = document.getElementById("soil" + i);
<html>
<body>
<script type="text/javascript">
start();
function start() {
var val = "0,1";
var n = 5;
var chars = ['a', 'b', 'c', 'd', 'e'];
gVars = chars.slice(0, n);
for (var i = 0; i < gVars.length; i++)
document.write(gVars[i] + "<br />");
var termsStr = val.split(',');
for (var i = 0; i < termsStr.length; i++)
document.write(termsStr[i] + "<br />");
var gOrigTerms = [];
var maxterm = Math.pow(2, termsStr.length) - 1;
document.write("maxterm: " + maxterm + "<br />");
for (var i = 0; i < termsStr.length; i++) {
gOrigTerms[i] = parseInt(termsStr[i]);
document.write(gOrigTerms[i] + "<br />");
if (gOrigTerms[i] > maxterm) document.write("Invalid term in term list." + "<br />");
}
gFormula = new Formula(gVars, gOrigTerms);
document.write(gFormula);
gFormula.toString();
gFormula.reduceToPrimeImplicants(); //here the breakpoint is inserted
}
function Formula(vars, terms)
{
this.vars = vars;
this.termList = [];
for (var i = 0; i < terms.length; i++) {
this.termList[i] = new Term(Dec2Bin(terms[i], vars.length));
document.write("this.termList" + this.termList[i] + "<br />");
}
this.orginalTermList = [];
document.write("this.orginalTermList" + this.orginalTermList + "<br />");
}
function Dec2Bin(dec, size) {
var bits = [];
for (var bit = 0; bit < size; bit++)
{
bits[bit] = 0;
}
var i = 0;
while (dec > 0)
{
if (dec % 2 == 0)
{
bits[i] = 0;
} else
{
bits[i] = 1;
}
i++;
dec = (dec / 2) | 0;
// Or with zero casts result to int (who knows why...)
}
bits.reverse();
return bits;
}
function Term(varVals)
{
this.varVals = varVals;
document.write("this.varVals: " + this.varVals);
}
function reduceToPrimeImplicants() //there is some problem with this function
{
this.originalTermList = this.termList.slice(0);
var numVars = this.termList[0].getNumVars();
var table = [];
for (var dontKnows = 0; dontKnows <= numVars; dontKnows++) {
table[dontKnows] = [];
for (var ones = 0; ones <= numVars; ones++) {
table[dontKnows][ones] = [];
}
table[dontKnows][numVars + 1] = [];
}
table[numVars + 1] = [];
table[numVars + 1][numVars + 1] = [];
for (var i = 0; i < this.termList.length; i++) {
var dontCares = this.termList[i].countValues(DontCare);
var ones = this.termList[i].countValues(1);
var len = table[dontCares][ones].length;
table[dontCares][ones][len] = this.termList[i];
}
for (var dontKnows = 0; dontKnows <= numVars - 1; dontKnows++) {
for (var ones = 0; ones <= numVars - 1; ones++) {
var left = table[dontKnows][ones];
var right = table[dontKnows][ones + 1];
var out = table[dontKnows + 1][ones];
for (var leftIdx = 0; leftIdx < left.length; leftIdx++) {
for (var rightIdx = 0; rightIdx < right.length; rightIdx++) {
var combined = left[leftIdx].combine(right[rightIdx]);
if (combined != null) {
if (out.indexOf(combined) < 0) {
var len = out.length;
out[len] = combined;
}
if (this.termList.indexOf(left[leftIdx]) >= 0) {
this.termList.splice(this.termList.indexOf(left[leftIdx]), 1);
}
if (this.termList.indexOf(right[rightIdx]) >= 0) {
this.termList.splice(this.termList.indexOf(right[rightIdx]), 1);
}
if (this.termList.indexOf(combined) < 0) {
var len = this.termList.length;
this.termList[len] = combined;
}
}
}
}
}
}
}
function getNumVars()
{
return this.varVals.length;
}
function countValues(value)
{
result = 0;
for (var i = 0; i < this.varVals.length; i++) {
if (this.varVals[i] == value) {
result++;
}
}
return result;
}
function combine(term)
{
var diffVarNum = -1; // The position where they differ
for (var i = 0; i < this.varVals.length; i++) {
{
if (this.varVals[i] != term.varVals[i])
if (diffVarNum == -1) {
diffVarNum = i;
} else { // They're different in at least two places return null; }
}
}
if (diffVarNum == -1)
{
// They're identical return null;
}
resultVars = this.varVals.slice(0);
resultVars[diffVarNum] = DontCare;
return new Term(resultVars);
}
</script>
</body>
</html>
In the above code, that is not complete, but which implements quine Mccluskey algorithm. There is a problem while it is debugged.
If a breakpoint is inserted at gFormula.reducetoPrimeImplicants(); the debugger does not go into that function. This is the last function called in the code until now. But, it does go to start(), which is the first function.
There is some problem in reducetoPrimeImplicants(); function because it also gives ERROR in internet explorer.
I am not able to figure out the error. If I remove reducetoPrimeImplicants(); function from the code the works fine.
Please, can somebody tell me why the debugger does not enter reducetoPrimeImplicants();.
I am using the Firebug debugger.
Thanks in advance.
The last function in your page combine() is missing a closing brace.
If you don't mind, a suggestion: Please use http://jsbeautifier.org/ or some similar tool to indent your code better.
Your For loop has two starting braces.
for (var i = 0; i < this.varVals.length; i++) {
{
So remove one. This should solve your problem.