I'm working on swapping out some content in a simple div using the code below.
var slides = [
[],
[],
[],
[]
];
slides[0]['title'] = "Content One";
slides[0]['body'] = "Here is a little bit of useful information for you to read.";
slides[0]['link-text'] = "READ MORE...";
slides[0]['URL'] = "/go/somewhere";
slides[1]['title'] = "Content Two";
slides[1]['body'] = "This is different information for you to read.";
slides[1]['link-text'] = "READ THIS INSTEAD...";
slides[1]['URL'] = "/go/elsewhere";
var overlayTitle;
var overlayBody;
var overlayLink;
var i = 0;
var overlayInterval = setInterval(overlaySlider(), 600);
function overlaySlider() {
if (i == 1) {
i = 0;
} else {
i++;
}
overlayTitle = slides[i]['title'];
overlayBody = slides[i]['body'];
overlayLink = '' + slides[i]['link-text'] + '';
$("#hvoTitle").fadeOut()(400, function() {
$(this).html(overlayTitle).fadeIn();
});
$("#hvoBody").fadeOut()(400, function() {
$(this).html(overlayBody).fadeIn();
});
$("#hvoLink").fadeOut()(400, function() {
$(this).html(overlayLink).fadeIn();
});
}
Everything works until I get to the first .fadeOut, then I get an error that .fadeOut is not a function. I believe it should be in the version of the library I am using. (full, not slim).
Here is a fiddle I am trying to get working:
https://jsfiddle.net/529to1w5/41/
Problem
fadeOut()(
Solution
fadeout(
Simple syntax error, glad to help.
Related
I'm fairly certain this is a simple mistake, but I'm confused as to why this won't work. I've been unable to find any documentation on using multiple brackets in a row when accessing properties. This is part of my code that creates a link that when clicked runs the "dropItem" function:
var dropDest = "screwdriver";
var dropCat = "supplies.tools";
dropButton.onclick= function() {dropItem(dropCat, dropDest)};
The "dropItem" function:
var dropItem = function(category, droppedItem) {
player.inventory[category][droppedItem].amount = player.inventory[category][droppedItem].amount - 1; };
I get a "Cannot read property 'screwdriver' of undefined" error. How would one properly pass this? Both properties need to be variables for it to work. Is this an error due to multiple brackets?
EDIT:
I realized I forgot to include how the player object is structured, and this is critical for understanding why I needed to pass a dot-notated category:
var player = {
"health": 100,
"hydration": 100,
"hunger": 100,
"energy": 100,
"inventory": {
"supplies": {
"tools": {
"screwdriver": {
"amount": 0,
"condition": 0
}
},
"buldingMaterials": {
"wood": {
"amount": 0,
"condition": 0
}
}
},
"aidPacks": {
"healthPacks": 0
}
}
}
This is why I need to be able to access both player.inventory.supplies.tools and player.inventory.aidPacks.healthpacks with the same function.
You can make your code more generic and easier. This is useful when you have more than two categories - then you dont need to work with [0] and 1 - here is the code:
var player = { "inventory": { "supplies": { "tools" : { "screwdriver" : { "amount" : 1}}}}};
var dropDest = "screwdriver";
var dropCat = "supplies.tools";
function getProperty(obj, str) {
return str.split(".").reduce(function(o, x) { return o[x] }, obj);
}
function dropItem(category, droppedItem) {
var accessString = dropCat + "." + droppedItem;
getProperty(player.inventory, accessString).amount -= 1;
alert(getProperty(player.inventory, accessString).amount);
}
dropItem(dropCat, dropDest);
Here is the fiddle: https://jsfiddle.net/j7g0d8kz/3/
After looking at lightstalker89's code I realized that my issue was not the brackets, but rather the category that was being passed was not parsing the dot notation in the middle, thus staying as "supplies.tools" instead of separating fully. However, due to the way the player object is structured I needed to be able to pass dot notated categories, so I split the string:
var player = { "inventory": { "supplies": { "tools" : { "screwdriver" : { "amount" : 1}}}}};
var dropDest = "screwdriver";
var dropCat = "supplies.tools";
function dropItem(category, droppedItem) {
if(category.indexOf(".") > 0) {
var newCat = category.split(".");
var cat1 = newCat[0];
var cat2 = newCat[1];
player.inventory[cat1][cat2][droppedItem].amount = player.inventory[cat1][cat2][droppedItem].amount - 1;
alert(player.inventory[cat1][cat2][droppedItem].amount);
}else {
player.inventory[category][droppedItem].amount = player.inventory[category][droppedItem].amount - 1;
alert(player.inventory[category][droppedItem].amount);
}
}
dropItem(dropCat, dropDest);
Here's the JSFiddle: https://jsfiddle.net/j7g0d8kz/
Again, huge thanks to #lightstalker89 for making me realise my mistake.
How does your player object look like? Is it an empty object when you want to change the properties.
Basically you can use multiple brackets as you did.
If the player object does not have the needed properties, then your code should look like this:
var player = {};
var dropDest = "screwdriver";
var dropCat = "supplies.tools";
function dropItem(category, droppedItem) {
if(!player.inventory){
player.inventory = {};
}
if(!player.inventory[category]){
player.inventory[category] = {};
}
if(!player.inventory[category][droppedItem]){
player.inventory[category][droppedItem] = { amount: 0};
}
player.inventory[category][droppedItem].amount = player.inventory[category][droppedItem].amount - 1;
}
dropItem(dropCat, dropDest);
alert(JSON.stringify(player));
alert(player.inventory[dropCat][dropDest].amount);
Here is the fiddle: https://jsfiddle.net/csqbjnd7/1/
If the player object exists you can use multiple brackets. The code should then look like this:
var player = { "inventory": { "supplies.tools" : { "screwdriver" : { "amount" : 1}}}};
var dropDest = "screwdriver";
var dropCat = "supplies.tools";
function dropItem(category, droppedItem) {
player.inventory[category][droppedItem].amount = player.inventory[category][droppedItem].amount - 1;
}
dropItem(dropCat, dropDest);
alert(player.inventory[dropCat][dropDest].amount);
alert(JSON.stringify(player));
Here is the fiddle: https://jsfiddle.net/9o1949oz/2/
Was doing a nice-dropping navigation using css3 transforms.
Also written some javascript for this purpose.
But unfortunately it looks a bit untidy.
Would you guys please give me some tips to optimize javascript code.
The pen --> http://codepen.io/rokki_balboa/pen/doOqqv?editors=001
var bar = document.querySelector('.fa-bars');
var lis = document.getElementsByTagName('li');
bar.onclick = function() {
var delayIn = 0;
var delayOut = 1500;
if (!(lis[0].classList.contains('accordion'))) {
console.log(lis[5]);
[].forEach.call(lis, function(el) {
setTimeout(function() {
el.classList.add('accordion');
}, delayOut);
delayOut -= 300;
});
} else {
[].forEach.call(lis, function(el) {
setTimeout(function() {
el.classList.remove('accordion');
}, delayIn);
delayIn += 300;
});
}
};
If you're simply looking to reduce duplication, this might help:
var bar = document.querySelector('.fa-bars');
var lis = document.getElementsByTagName('li');
bar.onclick = function() {
var delay = {in: 0, out: 1500};
var adding = !(lis[0].classList.contains('accordion'));
[].forEach.call(lis, function(el) {
setTimeout(function() {
el.classList[adding ? 'add' : 'remove']('accordion');
}, delay[adding ? 'out' : 'in']);
delay[adding ? 'out' : 'in'] += (adding ? -300 : 300);
});
};
But it does so at some expense in readability. You'd have to make the call for your codebase as to which seems more maintainable.
In the future, https://codereview.stackexchange.com/ is a good place for code review help.
I've made a javascript slideshow for text but it gets bugged after a couple of loops.
This is what it should be like(don't mind the cursor in gif):
This is what happens after a couple of loops:
The Javascript code:
var quote_array = [
"Aš supratau, kad kuo daugiau dirbu,<br/>tuo labiau man sekasi.",
"Dirbdamas sau malonų darbą<br/>pasieki tobuliausių rezultatų.",
"Tikras darbas yra darbas<br/>kurio tu nemėgsti."
];
var quoteName_array = [
"-Tomas Džefersonas",
"-Aristotelis",
"-Bilas Watersonas"
];
var quote_i = Math.floor(Math.random()*quote_array.length);
var quote_elem;
var quoteName_elem;
var patikrinti
function quoteNext()
{
quote_i = Math.floor(Math.random()*quote_array.length);
if(patikrinti==quote_i)
{
quoteNext();
}
quote_elem.style.opacity = 0;
quoteName_elem.style.opacity = 0;
setTimeout("quoteSlide()",1100);
}
function quoteSlide()
{
patikrinti = quote_i;
quote_elem.innerHTML = quote_array[quote_i];
quoteName_elem.innerHTML = quoteName_array[quote_i];
quote_elem.style.opacity = 1;
quoteName_elem.style.opacity = 1;
setTimeout("quoteNext()",13900);
}
I didn't see the recurion at first, but in quoteNext() you're (randomly) calling quoteNext() a second time - which will add another setTimeout("quoteSlide()",1100) so over time more and more "loops" are running in parallel, leading to total flickering in the end. Change your function to
function quoteNext() {
quote_i = Math.floor(Math.random()*quote_array.length);
if (patikrinti==quote_i) {
quoteNext(); // try again
} else { // but do not continue
quote_elem.style.opacity = 0;
quoteName_elem.style.opacity = 0;
setTimeout(quoteSlide, 1100); // pass functions, not code strings
}
}
I'm using this JS code to make a banner:
var images = ["../../images/g11.jpg","../../images/g9.jpg","../../images/g10.jpg"];
var titulos = ["title1","title2","title3"];
var resumos = ["ddd","aaa","bbb"];
var noticias = ["190","204","200"];
var total = 3;
var indice = 0;
function rotate() {
document.getElementById('imageb').src = images[indice];
document.getElementById('titulob').innerHTML = titulos[indice];
document.getElementById('resumob').innerHTML = resumos[indice];
document.getElementById('noticiab').value = noticias[indice];
indice++;
if (indice > total - 1) indice = 0;
}
function banner() {
rotate();
setTimeout(banner, 5000);
}
It works how expected, but after some loops it freezes the browser. Pretty sure I'm not using setTimeout properly. Any ideas?
Edit:
Working so far:
function rotate(indice) {
document.getElementById('imageb').src = images[indice];
document.getElementById('titulob').innerHTML = titulos[indice];
document.getElementById('resumob').innerHTML = resumos[indice];
document.getElementById('noticiab').value = noticias[indice];
}
function banner(indice) {
var f1 = function() { banner(indice); };
var total = 3;
rotate(indice);
indice++;
if (indice > total - 1) indice = 0;
setTimeout(f1, 5000);
}
I'm posting this as a CW because it's a total guess.
Completely FWIW, here's how I'd minimally change that code: Live Copy | Live Source
(function() {
var entries = [
{
img: "../../images/g11.jpg",
titulo: "title1",
resumo: "ddd",
noticia: "190"
},
{
img: "../../images/g9.jpg",
titulo: "title2",
resumo: "aaa",
noticia: "204"
},
{
img: "../../images/g10.jpg",
titulo: "title3",
resumo: "bbb",
noticia: "200"
}
];
var indice = 0;
function rotate() {
var entry = entries[indice];
document.getElementById('imageb').src = entry.img;
document.getElementById('titulob').innerHTML = entry.titulo;
document.getElementById('resumob').innerHTML = entry.resumo;
document.getElementById('noticiab').value = entry.noticia;
indice = (indice + 1) % data.length;
}
function banner() {
rotate();
setTimeout(banner, 5000);
}
banner();
})();
Changes:
Put everything in a scoping function to avoid creating global variables.
Use an array of objects rather than parallel arrays.
Use the array's length rather than a separate total variable.
Use the remainder trick for getting the wrap-around on the indice variable.
I added a call to banner(); at the end to get things started, but I assume you have that and just didn't show it.
But again, I don't see any reason your code shouldn't be working as is, other than the possibility of some weird global variable conflict.
I am trying to use JQuery's each() method to animate typing on multiple blocks of code, but I keep getting this error:
Uncaught TypeError: Cannot call method 'createDocumentFragment' of undefined
Check out some example code in this Fiddle...
And for your convenience, the JS is listed below:
$('.typeanimator').each(function(index) {
console.log(index);
var codeBlock = $(this).text();
var done;
var blockLength = codeBlock.length;
var charCounter = 0;
$(this).text('|');
(function typeAnimator() {
var typingSimulator = Math.round(Math.random() * (200));
done = setTimeout(function() {
console.log("Le print.");
charCounter++;
var typeSection = codeBlock.substring(0, charCounter);
$(this).text(typeSection + '|');
typeAnimator();
if (charCounter == blockLength) {
$(this).text($(this).text().slice(0, -1));
clearTimeout(done);
}
}, typingSimulator);
}());
});
The problem is in the use of $(this) inside the typeAnimator function. You are actually want to refer the this from the parent function but instead you are getting a totally different this. So, use a temporary variable to store the $(this)
$('.typeanimator').each(function(index) {
...
var self = $(this);
self.text('|');
(function typeAnimator() {
var typingSimulator = Math.round(Math.random() * (200));
done = setTimeout(function() {
...
self.text(typeSection + '|');
typeAnimator();
if (charCounter == blockLength) {
self.text(self.text().slice(0, -1));
clearTimeout(done);
}
}, typingSimulator);
}());
});
Updated fiddle
$('.typeanimator').each(function(index, current) {
console.log(index);
var codeBlock = $(current).text();
var done;
var blockLength = codeBlock.length;
var charCounter = 0;
$(current).text('|');
(function typeAnimator(context) {
var typingSimulator = Math.round(Math.random() * (200));
done = setTimeout(function() {
console.log("Le print.");
charCounter++;
var typeSection = codeBlock.substring(0, charCounter);
$(context).text(typeSection + '|');
typeAnimator(context);
if (charCounter == blockLength) {
$(context).text($(context).text().slice(0, -1));
clearTimeout(done);
}
}, typingSimulator);
}(current));
});
This should work, always remember that javascript is really picky about the context when using 'this'. As well .each() has nifty parameter of current item :) Gl, and good code.