Putting simple functions that contain jquery in a jquery execution queue - javascript

I have a number of functions containing jquery that should be executed sequentially. They aren't used to create effects but rather to position certain elements at a calculated location inside a div. All online resources on jquery queue are focused on the creation of transitions or animations so it's hard to find a simple example on how to execute a number of simple functions sequentially.
I have these functions:
function bigItemRecalc(recalc, idBase, innerHeight, i) {
if (recalc < 0) {
$('#' + idBase + i).css('max-height', (innerHeight + (2 * recalc)));
recalc = 0;
}
return recalc;
}
function firstCheck(recalc, idBase, i) {
if (i == 1) {
$('#' + idBase + i).css('margin-top', recalc * -1);
}
}
function lastCheck(recalc, idBase, itemAmount, i) {
if (i == itemAmount) {
$('#' + idBase + i).css('margin-top', recalc);
}
}
function truncateItems(totalHeight, widgetHeight, idBase, i) {
if (totalHeight > (widgetHeight - 20)) {
$('#' + idBase + i).remove();
$('#' + idBase + "b" + i).remove();
}
}
In another function I want to execute these sequentially by using a jquery queue preferably , but I haven't got a clue how.
The code is called here:
function styleWidget(itemAmount, widgetHeight, widgetWidth, idBase) {
var innerHeight;
var outerHeight;
var recalc;
var totalHeight = 0;
var totalWidth = 0;
for (var i = 1; i <= itemAmount; i++)
{
if (widgetHeight >= widgetWidth)
{
totalHeight += $('#'+idBase+i).height();
innerHeight = $('#' + idBase + i).height();
outerHeight = (widgetHeight/itemAmount);
recalc = ((outerHeight / 2) - (innerHeight / 2));
recalc = bigItemRecalc(recalc, idBase, innerHeight, i);
$('#' + idBase + i).css('padding-top', recalc);
firstCheck(recalc, idBase, i);
lastCheck(recalc, idBase, itemAmount, i);
truncateItems(totalHeight, widgetHeight, idBase, i);
}
else
{
innerHeight = $('#'+idBase+i).height();
outerHeight = widgetHeight;
recalc = ((outerHeight/2)-(innerHeight/2));
$('#'+idBase+i).css('padding-top',recalc);
totalWidth += $('#'+idBase+i).width();
if (totalWidth > (widgetWidth-20))
{
$('#' + idBase + i).remove();
$('#' + idBase + "b" + i).remove();
}
}
}
}
The bottom part hasn't been updated just yet, but it can be ignored as it's being tested with portrait mode widgets.
I think I've found a clue. When no delay is introduced the values of totalHeight and innerHeight seem very low. So I assume that the page isn't fully loaded by the time the script is executed. Every time a new widget is generated the above script is called like this:
$(document).ready(styleWidget(3, 225, 169, 'id-871206010'));
This fixed it:Why does Firefox 5 ignore document.ready?
It seems like reloading the page did not trigger the .ready() function.

Related

My script needs page refresh for it to run

Every time I load my page for the first time my script does not load, I need to refresh the page at least 3 times for it to run. How can I make my script run without a page refresh? This particular script is in BABEL.
'use strict';
var deg = 0;
var index = 0;
$('#' + index).css('opacity', '1');
$('.navbar').contextmenu(function () {
return false;
});
$('.navbar').on('mousewheel', function (e) {
var move = -60;
var nextIndex = nextIndex = (index + 1) % 6;
if (e.originalEvent.wheelDelta / 120 <= 0) {
// wheel up
move = 60;
nextIndex = index -1 < 0 ? 5 : index - 1;
}
$('.scroll-list').css('transform', 'rotateX(' + (deg + move) + 'deg)');
$('#' + index).css('opacity', '0.01');
$('#' + nextIndex).css('opacity', '1');
index = nextIndex;
deg = deg + move;
event.stopPropagation();
console.timeEnd('cache');
});
And what if you wrapped your code inside a window.onload function?
window.onload = function() {
// your code
}
Your code will only run when the html document is "ready" and fully loaded.
You are running Javascript that depends on page elements and the javascript is executed before the elements are on the page;
Wrapp all your code inside document.ready function
$(document).ready(function () {
var deg = 0;
var index = 0;
$('#' + index).css('opacity', '1');
$('.navbar').contextmenu(function () {
return false;
});
$('.navbar').on('mousewheel', function (e) {
var move = -60;
var nextIndex = nextIndex = (index + 1) % 6;
if (e.originalEvent.wheelDelta / 120 <= 0) {
// wheel up
move = 60;
nextIndex = index - 1 < 0 ? 5 : index - 1;
}
$('.scroll-list').css('transform', 'rotateX(' + (deg + move) + 'deg)');
$('#' + index).css('opacity', '0.01');
$('#' + nextIndex).css('opacity', '1');
index = nextIndex;
deg = deg + move;
event.stopPropagation();
console.timeEnd('cache');
});
});
Wrap your code in ready function, so that your JavaScript executes after DOM is loaded.

Setting up an array to handle size conditions

I've got the following code. I am working on an array. I found a javascript array instructions..if this is wrong, I'd love help to find out if there is a jQuery version of this.
My issue comes into play when I am trying to implement an if() and else if() conditions to the array. I am using i (variable) to count items in array.
It is saying that there is an issue on the line that reads else if(width <= Sizes[i]) { $(element).attr('src', 'images/' + Sizes[i] + '/' + name[name.length - 1]) }
Also, it appears that the array isn't working at all. Its pulling the default image.
I am probably doing this wrong. I am doing this trying to figure out how arrays work and implementing them into a code I already have. Can someone please help solve this? It isn't working. The code works perfectly without the array, so it is something in the array.
$(document).ready(function() {
window.onresize = resize;
function resize() {
var img = $('img.resizable');
var width = $(window).innerWidth();
var Sizes, sLength, i;
img.each(function(index, element) {
var name = element.src.split('/') // Split is a native javascript function, which 'splits' the string into an array with the components
Sizes = [2880, 1920, 1000, 600];
sLength = Sizes.length;
for (i = 0; i < sLength; i++) {
if (i == 0) {
if (width <= Sizes[i]) {
$(element).attr('src', 'images/' + Sizes[i] + '/' + name[name.length - 1])
}
}
if (i > 0) {
else if (width <= Sizes[i]) {
$(element).attr('src', 'images/' + Sizes[i] + '/' + name[name.length - 1])
}
}
} else {
$(element).attr('src', 'images/2880/' + name[name.length - 1])
}
})
}
resize();
});
The actual script I am trying to convert
$(document).ready(function() {
window.onresize = resize;
function resize() {
var img = $('img.resizable');
var width = $(window).innerWidth();
img.each(function(index, element) {
var name = element.src.split('/') // Split is a native javascript function, which 'splits' the string into an array with the components
if(width <= 600) {
$(element).attr('src', 'images/600/' + name[name.length - 1]) // This name[name.length -1] trick is being used to select the 'last value in the string' based on the length of the string.
}
else if(width <= 1000) {
$(element).attr('src', 'images/1000/' + name[name.length - 1])
}
else if(width <= 1920) {
$(element).attr('src', 'images/1920/' + name[name.length - 1])
}
else {
$(element).attr('src', 'images/2880/' + name[name.length - 1])
}
})
}
resize();
});
Here's a solution that simplifies matters by using Array#filter to select the appropriate width; the appropriate size will sit in the first position of the sizes array:
$(document).ready(function() {
window.onresize = resize;
resize();
});
function resize() {
// use $.each to iterate over each element
$('img.resizable').each(function(index, element) {
// get the image name directly
var name = element.src.substring(element.src.lastIndexOf('/'));
// let's whittle down sizes to *only* those that fit our screen width
var sizes = [600, 1000, 1920, 2880].filter(function(s){
return window.innerWidth < s || s == 2880;
});
// update the image with whatever size is in the first position
$(element).attr('src', 'images/' + sizes[0] + name);
});
}
We can move the resize function definition outside of your on ready handler, to make it globally accessible. We can dispense with use of split to just find whatever is after the last / (the image name). And we can avoid using loops and if statements with breaks, which tend to be difficult to read and maintain.
This is a bit verbose and follows your array starting with the largest value which I used instead of hard coding that for the "largest" (last) conditional. Remove the console logs prior to deployment.
$(document).ready(function() {
window.onresize = resize;
var sizes = [2880, 1920, 1000, 600];
function resize() {
console.log('si');
var img = $('img.resizable');
var width = $(window).innerWidth();
img.each(function(index, element) {
var name = element.src.split('/');
name = name[name.length - 1];
var setto = 0;
for (var i = sizes.length; i >= 0; i--) {
console.log(i,width,setto, sizes[i]);
if (width <= sizes[i]) {
setto = sizes[i];
break;
}
}
setto = width >= sizes[0] ? sizes[0] : setto;
$(element).attr('src', 'images/' + setto + '/' + name);
});
}
resize();
});
You are referencing Sizes array using lowercase s at sizes[i], where sizes is not defined
I hope this could solve your problem:
$(window).on('resize', function (e) {
var img = $('img.resizable');
var width = $(window).innerWidth();
var Sizes, sLength, i;
img.each(function (index, element) {
var name = element.getAttribute('src').split('/') // Split is a native javascript function, which 'splits' the string into an array with the components
Sizes = [2880, 1920, 1000, 600].sort((a, b) => {return a - b;});
sLength = Sizes.length;
for (i = 0; i < sLength; i++) {
if (width <= Sizes[i]) {
$(element).attr('src', 'images/' + Sizes[i] + '/' + name.pop())
console.log('New src for image N. ' + index + ' is: ' + $(element).attr('src'));
break;
}
}
});
});
$(function () {
// simulate a resize on dom ready: for testing
$(window).trigger('resize');
});
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<img class="resizable" src="images/100/nameofimage1.png">
<img class="resizable" src="images/100/nameofimage2.png">
You want something like this probably:
sort_array_small_to_large(Sizes)
for (i = 0; i < Sizes.length; i++)
{
if (width <= Sizes[i])
{
size = Sizes[i]
break
}
}
$(element).attr('src', 'images/' + size + '/' + name[name.length - 1])

jQuery touchmove stops working when removing child

I have two divs:
<div class="main">
<div class="child" />
</div>
I've created an event listener for the main element which enables the user to drag the child element around
map.bind('touchmove', function(f) {
if (map.pinch) {
return;
}
f.preventDefault();
f.originalEvent.preventDefault();
f = f.originalEvent.touches[0];
map.handleMoveEvent(f);
});
map.handleMoveEvent = function(f) {
mover.css('left', map.getX() + (f.clientX - map.lastmouse.clientX) / scaler.scale);
mover.css('top', map.getY() + (f.clientY - map.lastmouse.clientY) / scaler.scale);
map.lastmouse = f;
map.moverMoved();
}
map.moverMoved = function() {
if (map.getX() > 0) {
map.tileX--;
mover.moveX(-TILE_WIDTH);
map.find(".child").moveX(TILE_WIDTH);
map.updateVisibleTiles();
}
if (map.getX() < -TILE_WIDTH) {
map.tileX++;
mover.moveX(TILE_WIDTH);
map.find(".child").moveX(-TILE_WIDTH);
map.updateVisibleTiles();
}
if (map.getY() > 0) {
map.tileY--;
mover.moveY(-TILE_HEIGHT);
map.find(".child").moveY(TILE_HEIGHT);
map.updateVisibleTiles();
}
if (map.getY() < -TILE_HEIGHT) {
map.tileY++;
mover.moveY(TILE_HEIGHT);
map.find(".child").moveY(-TILE_HEIGHT);
map.updateVisibleTiles();
}
$('#console').html(map.tileX + " " + map.tileY);
//$('#console').html(map.getX() + " " + map.getY());
};
map.updateVisibleTiles = function() {
mover.find(".child").remove();
for (x = Math.max(map.tileX - tiledistance, 0); x <= Math.min(map.tileX + tiledistance, map.getTileCount() - 1); x++) {
for (y = Math.max(map.tileY - tiledistance, 0); y <= Math.min(map.tileY + tiledistance, map.getTileCount() - 1); y++) {
var child = $(document.createElement('div'));
child.width(TILE_WIDTH);
child.height(TILE_HEIGHT);
var farbe = 'rgb(' + (Math.floor(Math.random() * 256)) + ',' + (Math.floor(Math.random() * 256)) + ',' + (Math.floor(Math.random() * 256)) + ')';
child.css("background-color", farbe);
child.css('position', 'absolute');
child.addClass('child');
child.css('left', (x - map.tileX) * TILE_WIDTH);
child.css('top', (y - map.tileY) * TILE_HEIGHT);
mover.append(child);
}
}
}
In some situations i have to exchange the child while dragging
$('.main').find(".child").remove();
but after removing the touchmove does not fire anymore. It only happens when i start the touchmove by tapping on the child element... The problem is obvios to me, but what's the solution?
$().remove() removes the dom element and it's event listeners. Use $().detach() to preserve event listeners.
http://api.jquery.com/detach/
The .detach() method is the same as .remove(), except that .detach() keeps all jQuery data associated with the removed elements. This method is useful when removed elements are to be reinserted into the DOM at a later time.
i just created an invisible overlay which handles the event, this seems to work:
var toch = $(document.createElement('div'));
toch.css('position', 'absolute');
toch.css('width', '100%');
toch.css('height', '100%');
map.append(toch);
toch.bind('touchmove', function(f) {})

my script only working from console

I have a script that I put inside my html doc.
when I load the html page the script is not working,but when I put the script inside the console then the script is working an making the effect I want on the html doc.
here is the script,what i'm doing wrong?
var maxRows = 10;
$('.table').each(function() {
var cTable = $(this);
var cRows = cTable.find('tr:gt(0)');
var cRowCount = cRows.size();
if (cRowCount < maxRows) {
return;
}
cRows.each(function(i) {
$(this).find('td:first').text(function(j, val) {
return (i + 1) + " - " + val;
});
});
cRows.filter(':gt(' + (maxRows - 1) + ')').hide();
var cPrev = cTable.siblings('.prev');
var cNext = cTable.siblings('.next');
cPrev.addClass('disabled');
cPrev.click(function() {
var cFirstVisible = cRows.index(cRows.filter(':visible'));
if (cPrev.hasClass('disabled')) {
return false;
}
cRows.hide();
if (cFirstVisible - maxRows - 1 > 0) {
cRows.filter(':lt(' + cFirstVisible + '):gt(' + (cFirstVisible - maxRows - 1) + ')').show();
} else {
cRows.filter(':lt(' + cFirstVisible + ')').show();
}
if (cFirstVisible - maxRows <= 0) {
cPrev.addClass('disabled');
}
cNext.removeClass('disabled');
return false;
});
cNext.click(function() {
var cFirstVisible = cRows.index(cRows.filter(':visible'));
if (cNext.hasClass('disabled')) {
return false;
}
cRows.hide();
cRows.filter(':lt(' + (cFirstVisible +2 * maxRows) + '):gt(' + (cFirstVisible + maxRows - 1) + ')').show();
if (cFirstVisible + 2 * maxRows >= cRows.size()) {
cNext.addClass('disabled');
}
cPrev.removeClass('disabled');
return false;
});
});
You're most likely running that script before the elements that it references exist.
Make sure that the <script> tag comes later in the page than the element with the class table or wrap your entire script in:
$(function(){
... Your entire script
});
in order to ensure that it does not execute until the DOM is ready.
Try wrapping the whole thing with this:
$(document).ready(function () { /* existing code */ });
The browser may be executing your code before the page has loaded and therefore before the elements exist.
A page can't be manipulated safely until the document is "ready."
jQuery detects this state of readiness for you. Code included inside
$( document ).ready() will only run once the page Document Object
Model (DOM) is ready for JavaScript code to execute. Code included
inside $( window ).load(function() { ... }) will run once the entire
page (images or iframes), not just the DOM, is ready.
Try wrapping your code in this
$(document).ready(function() {
// Your code here
});
The Source

function doesn't execute on jquery document ready

I have a javascript function that resize and centers images based on the surrounding container size (that in turn depend on the window size). I use jquery as js framework. The function need to be executed after document load (on document ready) but also when and if the user changes size of the browser, ie I have the following running in the html-document:
$(document).ready(function(){
fixImageSizes();
});
$(window).resize(function() {
fixImageSizes();
});
But for some unknown reason the function is only executed when a user resizes the browser and not after loading. Can anyone please help with this?
(my function is below for knowledge...)
function fixImageSizes()
{
var cw = $('#imagecontainer').width();
var ch = $('#imagecontainer').height();
$('#imagecontainer img').each(function()
{
var iw = $(this).css('width');
var ih = $(this).css('height');
if (parseInt(iw) < parseInt(cw)) // image width < viewport
{
var newih = Math.ceil(parseInt(ih) * parseInt(cw) / parseInt(iw)) + 'px';
var newimargint = '-' + Math.ceil(parseInt(newih)/2) + 'px';
var newimarginl = '-' + Math.ceil(parseInt(cw)/2) + 'px';
$(this).css({'width':cw,'height':newih,'margin-left':newimarginl,'margin-top':newimargint});
}
if (parseInt(ih) < parseInt(ch)) // image height < viewport
{
var newiw = Math.ceil(parseInt(iw) * parseInt(ch) / parseInt(ih)) + 'px';
var newimargint = '-' + Math.ceil(parseInt(ch)/2) + 'px';
var newimarginl = '-' + Math.ceil(parseInt(newiw)/2) + 'px';
$(this).css({'width':newiw,'height':ch,'margin-left':newimarginl,'margin-top':newimargint});
}
if (parseInt(ih) > parseInt(ch) && parseInt(iw) > parseInt(cw)) // viewport smaller than image, shrink image
{
if (parseInt(ch) - parseInt(ih) > parseInt(cw) - parseInt(iw)) // difference is less on height
{
var newiw = Math.ceil(parseInt(iw) * parseInt(ch) / parseInt(ih)) + 'px';
var newimargint = '-' + Math.ceil(parseInt(ch)/2) + 'px';
var newimarginl = '-' + Math.ceil(parseInt(newiw)/2) + 'px';
$(this).css({'width':newiw,'height':ch,'margin-left':newimarginl,'margin-top':newimargint});
}
else // difference less on width
{
var newih = Math.ceil(parseInt(ih) * parseInt(cw) / parseInt(iw)) + 'px';
var newimargint = '-' + Math.ceil(parseInt(newih)/2) + 'px';
var newimarginl = '-' + Math.ceil(parseInt(cw)/2) + 'px';
$(this).css({'width':cw,'height':newih,'margin-left':newimarginl,'margin-top':newimargint});
}
}
});
You should use the load event instead of the ready event.
The ready event runs after the document has loaded, but before the images has loaded, so you won't have the correct size of all elements.
The function is probably executing (you can double-check with a simple alert), but the images you are "fixing" is probably not loaded yet. You can use the window.onload event or listen to the image load event like this:
var scale = function() {
// rescale
};
$('#imagecontainer img').each(function() {
this.complete ? scale.call(this) : $(this).load(scale);
});
Try this:
$(window).load(function (){
fixImageSizes();
});

Categories

Resources