javascript randomly fails to sort items, no error - javascript

For some reason Javascript stops working randomly.
Code that is dealing with height problem:
$(document).ready(function()
{
/*setEqualHeight($("ul#product_list li"));*/
//alert("some text");
/*setEqual($("ul#product_list"));*/
//var i = 2;
//alert($('ul#product_list li:nth-child('+ (i + 2) +')').height()); //this is correct way to get value*/
var elements = $('ul#product_list li').length; //this is correct way to get value
/*var liekana = elements % 3;
elements = elements - liekana;
alert(elements);*/
for(var i = 1; i <= elements; i = i + 3)
{
var first = $('ul#product_list li:nth-child('+ (i) +')').height();
var second = $('ul#product_list li:nth-child('+ (i + 1) +')').height();
var third = $('ul#product_list li:nth-child('+ (i + 2) +')').height();
var tallest = 0;
if (first > second)
if (first > third)
{
tallest = first;
}
else
{
tallest = third;
}
else
if (second > third)
{
tallest = second;
}
else
{
tallest = third;
}
$('ul#product_list li:nth-child('+ (i) +')').height(tallest);
$('ul#product_list li:nth-child('+ (i + 1) +')').height(tallest);
$('ul#product_list li:nth-child('+ (i + 2) +')').height(tallest);
/*if (!third)
alert("yra");*/
}
});
Failing URL: http://piguskompiuteris.lt/6_asus
Normal render URL: http://piguskompiuteris.lt/16-lenovo
Any suggestions how to solve this problem would be greatly appreciated. Thanks
UPDATE 2. I have rewriten javascript code... I still get the same random errors, sometimes grid collapses. I am not sure what is the cause.
Possible causes:
1) Height attribute is too small and doesn't include height + padding + margin + border
2) There is something wrong with function placement (currently not in header) or calling it $(document).ready(function()

I have checked your site. And found this solution use it:
columns.height(tallestcolumn);
Replace above code with the following code:
columns.css("min-height", tallestcolumn+" !imporatant");
This will work for you.

Sorting script works.
To fix script use:
$(window).load(function() {});
Out instead of:
$(document).ready(function() {});

Related

jQuery - Each counting resetting issue

I'm trying to get the currentpage number using jQuery each function. This is how I am doing it
var CurrentPageView = 1;
var check = true;
var Bookmark = [];
var CurPage = 1;
$(function() {
$(window).scroll(function() {
if (check) {
var PagesPosition = [];
var CurrentWindowPosition = $(window).scrollTop();
var CurrentCenterWindowPos = CurrentWindowPosition + $(window).height() / 2;
$(".Page").each(function() {
var PagePos = $(this).offset().top;
if (PagePos / CurrentCenterWindowPos <= 1) {
CurPage = $(this).index() + 1;
}
});
$(".CurrPageNumber").val(CurPage);
CurrentPageView = CurPage;
}
});
});
And it is working pretty well. If i am scrolling up and down he changes and gives me the currentpage number. The problem happens if between those with the class page there is something like a span. When this happens the counter resets to 1..
I would like to know if there is a way to keep the counting working for every div with the class "A4 Portrait" even if inside a span.
So instead of the actual count
1
2
1
2
It would be
1
2
3
4
Try using the index in the list of .Page instead of the index in its parent:
$(".Page").each(function(i) {
var PagePos = $(this).offset().top;
if (PagePos / CurrentCenterWindowPos <= 1) {
CurPage = i + 1; // Use the index in the array.
}
});
$(".CurrPageNumber").val(CurPage);
CurrentPageView = CurPage;

Issues with rotating jqueryUI modal

I am trying to build a modal that rotates to a particular element, $(.linkmoddet), based on a clicked element in the navbar $('.selectcircle') using the .switchClass function in jQueryUI.
However, I am having issues with the actual math involved, often causing:
only one or two elements to rotate at a time.
multiple elements gaining classes but not losing them.
occasionally losing all the classes involved, defaulting the element in question to a standard size and position in CSS.
Code
Edit: This has now been fixed.
http://codepen.io/yeasayer/pen/ZWxYZG
var selectcircle = $('.selectcircle');
var linkmoddet = $('.linkmoddet');
selectcircle.click(function(){
var circleindex = $(this).index()-1;
var centerindex;
console.log(circleindex);
selectcircle.each(function (index){
if (circleindex == index)
{
console.log($(this));
}
});
linkmoddet.each(function (index){
if ($(this).hasClass('moddetcenter'))
{
centerindex = $(this).index();
console.log("the center is index #"+centerindex);
}
var rotation = centerindex - circleindex;
//This is where I start having issues.
var i = $(this).index() + rotation;
var j;
if (i <= -1)
{
j = i + moddetids.length-1;
$(this).switchClass(classes[i+$(this).index()],classes[j]);
}
if (i >= moddetids.length)
{
j = i - moddetids.length;
$(this).switchClass(classes[i-$(this).index()],classes[j]);
}
else
{
if (rotation < 0)
{
j = i-1;
}
else
{
j = i+1;
}
$(this).switchClass(classes[i], classes[j]);
}
});
});
Does anyone have an idea on how to achieve the desired results, possibly in a simpler manner than described above?
Alright, it turns out that I figured it out by doing the following:
linkmoddet.each(function (index){
var classnum;
var newrot;
if ($(this).hasClass('moddetcenter'))
{
classnum = 2;
if (rotation < 0)
{
rotation += classes.length;
}
if (classnum + rotation >= classes.length)
{
newrot = classnum + rotation - classes.length;
$(this).switchClass(classes[classnum],classes[newrot]);
}
else if (rotation != 0)
{
$(this).switchClass(classes[classnum],classes[classnum+rotation]);
}
}
/* This is repeated for all the classes available in the classes array.
* ie: 0 being the first class, 1 being the second, etc. It's not an
* elegant solution, but it works for my current needs at the moment
* while I put it in a function in the future. */
Thanks!

Resetting jquery varible to lowest possible value that doesn't exist

This script generate divs with cloud images that fly from left to right with random height and intervals. It generally works but it keeps incrementing divs "id" infinitely. I can't figure out how to reset the counter being safe that never two identical "id"s will exist in the same time.
function cloudgenerator(){
var nr=1;
var t1 = 20000;
var t2 = 50000;
function cloud(type,time,nr){
$("#sky").append("<div id=\"cloudFL"+nr+"\" class=\"cloud"+type+"\" ></div>");
setTimeout(function() {
$("#cloudFL"+nr).css({top:Math.floor(Math.random() * 400)+'px'}).animate({
left:'100%',
},time,'linear',function(){$(this).remove();
});
}, Math.floor(Math.random() * t1));
};
function wave(){
var tx = 0;
setInterval(function(){
cloud(1,t1,nr);
nr++;
var n = $( "div.cloud1" ).length;
$( "span" ).text( "There are " + n +" n and "+ tx +" tx")
if(tx < n){tx = n}
else(tx = 1)
},500);
};
wave()};
cloudgenerator()
In the bottom, there is an instruction that checks if number of divs is starting to drop and presents those values in span for debugging.
Quick and easy solutionYou could loop through the id's in JQuery, starting from the lowest number, until you find a JQuery selector that yields 0 results...
var newid = 0;
var i = 1;
while(newid == 0) {
if( $('#cloudFL' + i).length == 0 ) { newid = i; }
else { i++; }
}
JSFIDDLE DEMO
Alternative solution (scalable)
Given that you may have many clouds onscreen at one time, you could try this alternative approach.
This approach creates an array of 'used ids' and the wave function then checks if any 'used ids' are available before creating a new id for the cloud function. This will run quite a bit more efficiently that then above 'quick fix solution' in situations where many clouds appear on screen.
function cloudgenerator(){
var nr=1;
var t1 = 20000;
var t2 = 50000;
var spentids = [];
function cloud(type,time,id){
$("body").append('<div id="' + id + '" class="cloud' + type + '" >' + id + '</div>');
setTimeout(function() {
$('#'+id).css({top:Math.floor(Math.random() * 400)+'px'}).animate({
left:'100%',
},time,'linear',function(){
spentids.push( $(this).attr('id') );
$(this).remove();
});
}, Math.floor(Math.random() * t1));
};
function wave(){
setInterval(function(){
if(spentids.length == 0) {
cloud(1,t1,"cloudFL" + nr);
nr++;
} else {
spentids = spentids.sort();
cloud(1,t1,spentids.shift());
}
},500);
};
wave()};
cloudgenerator()
JSFIDDLE DEMO - ALTERNATIVE
Why not get the timestamp and add this to your id?
If you donĀ“t need the ids i would stick to #hon2a and just add the styling to the class and remove the ids.
And another solution:
You could make a check if ID xyz is used. Like this e.g.
var cloudCount = jQuery('.cloud20000').length + jQuery('.cloud50000').length + 10;
for(var i = 0; i <= cloudCount; i++) {
if(jQuery('#cloudFL' + i).length <= 0) {
nr = i;
return false;
}
}
cloud(1,t1,nr);

Getting Javascript/jQuery scrolling function to work on successive divs

I'm currently trying to implement functionality similar to infinite/continuous/bottomless scrolling, but am coming up with my own approach (as an intern, my boss wants to see what I can come up with on my own). So far, I have divs of a fixed size that populate the page, and as the user scrolls, each div will be populated with an image. As of now, the function I've written works on the first div, but no longer works on successive divs.
$(window).scroll(function () {
var windowOffset = $(this).scrollTop();
var windowHeight = $(this).height();
var totalHeight = $(document).height();
var bottomOffset = $(window).scrollTop() + $(window).height();
var contentLoadTriggered = new Boolean();
var nextImageCount = parseInt($("#nextImageCount").attr("value"));
var totalCount = #ViewBag.totalCount;
var loadedPageIndex = parseInt($("#loadedPageIndex").attr("value"));
var calcScroll = totalHeight - windowOffset - windowHeight;
$("#message").html(calcScroll);
contentLoadTriggered = false;
if (bottomOffset >= ($(".patentPageNew[id='" + loadedPageIndex + "']").offset().top - 1000)
&& bottomOffset <= $(".patentPageNew[id='" + loadedPageIndex + "']").offset().top && contentLoadTriggered == false
&& loadedPageIndex == $(".patentPageNew").attr("id"))
{
contentLoadTriggered = true;
$("#message").html("Loading new images");
loadImages(loadedPageIndex, nextImageCount);
}
});
This is the image-loading function:
function loadImages(loadedPageIndex, nextImageCount) {
var index = loadedPageIndex;
for(var i = 0; i < nextImageCount; i++)
{
window.setTimeout(function () {
$(".patentPageNew[id='" + index + "']").html("<img src='/Patent/GetPatentImage/#Model.Id?pageIndex=" + index + "' />");
index++;
var setValue = index;
$("#loadedPageIndex").attr("value", setValue);
}, 2000);
}
}
I was wondering what may be causing the function to stop working after the first div, or if there might be a better approach to what I'm attempting?
EDIT: It seems that loadedPageIndex == $(".patentPageNew").attr("id") within the if statement was the culprit.
#ViewBag.totalCount; is not a JavaScript, it's .NET, so your script probably stops after encountering an error.
Also: ".patentPageNew[id='" + loadedPageIndex + "']" is inefficient. Since IDs must be unique, just query by ID instead of by class name then by ID.

replacing images inplace

I have a array of static images that I am using for an animation.
I have one frame image that I want to update the image of and I have seen a lot of tutorials on animating images with javascript just simply update the source of an image.
frame.src = animation[2].src; etc
When I look at the resource tracking in chrome, it doesnt look like they are getting cached even thought the web browser does download the image more than once but not once for each time it is displayed, so there is still some browser caching going on.
What is the best way to replace the frame image object with another image?
Well, you can either position all images absolute and give them a z-index, then use jQuery/JS to shuffle their z-indexes, bringing a new one to the top in a cross fader style,
or you can take all the id's and fadeone in slightly faster than the last one fades out.
Like so:
function fader(func) {
var currID = $('#mainimg ul').data('currLI');
var currLiStr = '#mainimg ul li#' + currID;
img = $(currLiStr).find('img').attr('src');
nextID = (currID == 'six') ? 'one' : $(currLiStr).next().attr('id');
nextLiStr = $('#mainimg ul li#' + nextID);
$(currLiStr).fadeOut(3000);
$(nextLiStr).fadeIn(2000).find('div.inner').delay(3000).fadeIn('slow').delay(6000).fadeOut('slow');
$('#mainimg ul').data('currLI',nextID);
}
Note 'six' is the id of the last li, reseting it back to one, but if you do $('#mainimg ul li:last').attr('id'); and $('#mainimg ul li:first').attr('id') to get the last and first id's, you can allow it to cope with any amount of images (obviously this is with li's given id's one, two and so on, but if you are finding out the last and first id you could use any structure.
Or you can set a ul width a width of all the li's multiplied, and give the li's the width of the images, and set overflow to hidden, then use JS to pull the li's left by the width of 1 li on each iteration in a slider like I have done here: http://www.reclaimedfloorboards.com/
There are loads of options
I ended up using jquery's replaceWith command and gave all the frames a class "frame" that i could select with $('.frame') which happened to only select visible frames.
<script type="text/javascript">
var animation = [];
var firstFrame = 1;
var lastFrame = 96;
var animationFrames = 16;
var loadedImageCount = 0;
$(function() {
$("button, input:submit",'#forecastForm').button();
$("#progressbar").progressbar({
value: 0
});
$('#id_Species').attr('onChange', 'loadAnimation($(\'#id_Species\').val(),$(\'#id_Layer\').val(),$(\'#id_StartTime\').val(),$(\'#id_EndTime\').val())' )
$('#id_Layer').attr('onChange', 'loadAnimation($(\'#id_Species\').val(),$(\'#id_Layer\').val(),$(\'#id_StartTime\').val(),$(\'#id_EndTime\').val())' )
$('#id_StartTime').attr('onChange', 'loadAnimation($(\'#id_Species\').val(),$(\'#id_Layer\').val(),$(\'#id_StartTime\').val(),$(\'#id_EndTime\').val())' )
$('#id_EndTime').attr('onChange', 'loadAnimation($(\'#id_Species\').val(),$(\'#id_Layer\').val(),$(\'#id_StartTime\').val(),$(\'#id_EndTime\').val())' )
});
if (document.images) { // Preloaded images
loadAnimation('Dry_GEM',1,1,96);
}
function rotate(animation, frame)
{
if (frame >= animation.length)
frame = 0;
$('.frame').replaceWith(animation[frame]);
window.setTimeout('rotate(animation,'+eval(frame+1)+')',150);
}
function loadAnimation(species, layer, startTime, endTime)
{
layer = Number(layer);
startTime = Number(startTime);
endTime = Number(endTime);
if (startTime > endTime)
{
swap = startTime;
startTime = endTime;
endTime = swap;
delete swap;
}
for (i=0;i<animation.length;i++)
delete animation[i];
delete animation;
animation = []
$('#progressbar').progressbar({value: 0});
loadedImgCount = 0;
animationFrames = endTime - startTime + 1;
for(i=0;i < animationFrames;i++)
{
animation[i] = new Image();
animation[i].height = 585;
animation[i].width = 780;
$(animation[i]).attr('class','frame');
animation[i].onload = function()
{
loadedImgCount += 1;
$('#progressbar').progressbar({value: eval(loadedImgCount / animationFrames * 100)});
};
animation[i].src = 'http://[[url]]/hemi_2d/' + species + '_' + layer + '_' + eval(i+startTime) + '.png';
}
}
</script>
The easiest way to do it is create a separate hidden image for each frame. Something like this:
var nextImage = (function(){
var imagePaths='basn0g01.png,basn0g02.png,basn0g04.png,basn0g08.png'.split(','),
imageHolder=document.getElementById('custom-header'),
i=imagePaths.length, imageIndex=i-1, img;
for (;i--;) {
img=document.createElement('img');
img.src='http://www.schaik.com/pngsuite/' + imagePaths[i];
if (i) img.style.display='none';
imageHolder.appendChild(img);
}
return function(){
imageHolder.childNodes[imageIndex].style.display='none';
if (++imageIndex >= imageHolder.childNodes.length) imageIndex=0;
imageHolder.childNodes[imageIndex].style.display='inline-block';
}
}());
Try this example on this page; paste it in the console and then call nextImage() a few times. Watch the top of the page.
edit
If you already have all the images in your HTML document, you can skip most of the above and just do something like this:
var nextImage = (function(){
var imageHolder=document.getElementById('custom-header'),
images=imageHolder.getElementsByTagName('img'),
i=images.length, imageIndex=0, img;
for (;i--;) if (i) images[0].style.display='none';
return function(){
imageHolder.childNodes[imageIndex].style.display='none';
if (++imageIndex >= imageHolder.childNodes.length) imageIndex=0;
imageHolder.childNodes[imageIndex].style.display='inline-block';
}
}());

Categories

Resources