Why is my function not being called after the DOM is ready? - javascript

Can someone explain to me why the rescaleStuff function below is not being invoked on the line where I attempt to invoke it after defining it?
jQuery(function ($) { // $(document).ready equivalent
function scaleStuff()
{
// make elements with class 'same-height-as-width' have the self-explanatory property
$('.same-height-as-width').each(function () {
var thisElement = $(this);
thisElement.height(thisElement.width());
});
// make font size of carousel proportional to height
var factor = 15; // factor to scale the font size, e.g. factor=15 means font-size of the outer div
// if 1/15 of its height. The descendant text elements have font-size defined in em
$('#front-page-carousel-blue-strip').css('font-size', ($('#front-page-carousel-blue-strip').height() / factor).toString() + 'px');
}
scaleStuff(); // scale on page load
// ... bunch of other stuff
}
I shouldn't have to resize the window to get everything to scale immediately after I load the page.

I think you actually wanted:
$(document).ready(function() {
...
})
or
$(function() {
...
})
Note any combination interchanging $ and jQuery is valid.

What you have is fine. You're just missing the closing ) after your declaration:
jQuery(function ($) { // $(document).ready equivalent
function scaleStuff()
{
// make elements with class 'same-height-as-width' have the self-explanatory property
$('.same-height-as-width').each(function () {
var thisElement = $(this);
thisElement.height(thisElement.width());
});
// make font size of carousel proportional to height
var factor = 15; // factor to scale the font size, e.g. factor=15 means font-size of the outer div
// if 1/15 of its height. The descendant text elements have font-size defined in em
$('#front-page-carousel-blue-strip').css('font-size', ($('#front-page-carousel-blue-strip').height() / factor).toString() + 'px');
}
scaleStuff(); // scale on page load
// ... bunch of other stuff
} /* <-- Missing the closing ")". */
Remember the } closes the function being passed as a parameter. The ) closes the jQuery(...) function invocation. Once you add it, it should work fine. I've mocked up an example below using your syntax to show that this indeed works:
jQuery(function ($) {
alert($().jquery);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Try using
jQuery(document).ready(function( $ ) { ... });

Take a look here: https://learn.jquery.com/using-jquery-core/document-ready/
$( document ).ready(function() {
console.log( "ready!" );
});
$(function() {
console.log( "ready!" );
});
// Passing a named function instead of an anonymous function.
function readyFn( jQuery ) {
// Code to run when the document is ready.
}
$( document ).ready( readyFn );
// or:
$( window ).load( readyFn );

Related

Decrement value by javascript variable inside the css property

I wanna move content with animation.
There's an animation in the jquery function, like that:
.on('click', '.btn', function () {
var contentWidth = $(window).width() - $('.sidebar').width();
$( ".content" ).animate({
left: "+=1000",
}, 5000, function() {
// moving content function
}
);
});
So, because I have various positions of content, I need to use this value in the variable contentWidth. How I can set this value in a variable and decrement the left value every time when I call a function?
Something like left: "+=contentWidth" doesn't work. Is where I make mistake?
Not sure if i got it but...
maybe you could use string interpolation
.on('click', '.btn', function () {
var contentWidth = $(window).width() - $('.sidebar').width();
$( ".content" ).animate({
left: `+=${contentWith}`,
}, 5000, function() {
// moving content function
}
);
});
Not tested but should work theoretically

Simple jQuery Tooltip (position distorted on iPad)

I've used simple jQuery UI tooltip on form-fields of my webpage(viz responsive), its working perfectly on desktop on every browser, but on iPad its get distorted when I tap on form-fields as keypad swipe-up. Also header section of my webpage gets fixed on scroll.
I've used below code for the custom jQuery Tooltip.
$(function () {
$('.form-control').tooltip({
disabled: true,
position: {
my: "left top",
at: "left top-50",
using: function( position, feedback ) {
$( this ).css( position );
$( "<div>" )
.addClass( "arrow" )
.addClass( feedback.vertical )
.addClass( feedback.horizontal )
.appendTo( this );
}
}
}).on("focusin", function () {
$(this)
.tooltip("enable")
.tooltip("open");
}).on("focusout", function () {
$(this)
.tooltip("close")
.tooltip("disable");
});
});
I've written this code to re-initialize the tooltip for the focused field by calling its focusin trigger manually when document size changed. It is working as expected on Desktop browsers but on iPad tooltip is being re-initialized at same place again viz incorrect.
var toolTipEl;
$('#inputSuccess, #inputWarning').tooltip({
open: function (event, ui) {
toolTipEl = event.target;
}
});
function checkDocumentHeight(callback){
var lastHeight = document.body.clientHeight, newHeight, timer;
(function run(){
newHeight = document.body.clientHeight;
if( lastHeight != newHeight )
callback();
lastHeight = newHeight;
timer = setTimeout(run, 100);
})();
}
function doSomthing(){
console.log('document resized');
setTimeout(function() {
if ($(toolTipEl).is(':focus')) {
$(toolTipEl).trigger('focusout').trigger('focusin');
}
}, 500);
}
checkDocumentHeight(doSomthing);
Please help me to find out the solution for this.
You will need to reinitialize active Tooltip after completion of any event which cause change in the content (actually height) of your document affecting your Tooltip position.
First keep reference of the element for which the tooltip is active by listening to its events by adding following codes in your tooltip initialization (Keep your existing code as it is. Just add these additional statements).
var toolTipEl = undefined;
$(function () {
$('.form-control').tooltip({
open: function (event, ui) {
toolTipEl = event.target;
}
}).on("focusin", function () {
toolTipEl = undefined;
}).on("focusout", function () {
toolTipEl = undefined;
}).on("mouseleave", function () {
toolTipEl = undefined;
});
});
Please note, as you are displaying tooltip on focusin event as well. So, you will also need to release the variable if you do not want tooltip pop-upped if focus has changed/left.
And then create a function for resetting tooltip like below.
function resetTooltip() {
if (toolTipEl) {
$(toolTipEl).trigger('focusout').trigger('focusin');
};
}
Call this function in any events which is causing change in the document height. For example if content is coming from an ajax request. You can call restTooltip function by listing to the gloab ajax events. See example below.
$( document ).ajaxComplete(function() {
resetTooltip();
});
I hope it will help you. Ask me if you need any further clarification.

jQuery does not apply offset on document.ready

So I am trying to apply a JS function on two events: window.resize and document.ready. The second one just won't work.
When I load the website I want this function to execute and apply the CSS. This is the last JS code before the
I've tried many JS events, but no success.
window.addEventListener("resize", footerMargin);
$( document ).ready(function() { footerMargin(); });
function footerMargin() {
var offset = $( ".section-item--coming-soon").offset();
var novaVar = Math.round(offset.top);
var leftVar = Math.round($( ".footer--section").offset.left);
var heightComingSoon = $( ".section-item--coming-soon").height();
var overall = novaVar + heightComingSoon + 75;
$( ".footer--section").offset({ top: overall, left: leftVar });
}
Upon setting value to leftVar you are using $( ".footer--section").offset.left instead of $( ".footer--section").offset().left.
This Math.round($( ".footer--section").offset.left) will return NaN.
Change that to:
var leftVar = Math.round($( ".footer--section").offset().left);

Reloading a new set of images makes div height 0 in isotope

My javascript looks like the following:
<script type="text/javascript">
$(document).ready(function() {
// isotope
var $container = $('#content');
$container.imagesLoaded( function(){
$container.isotope({
filter: '*',
itemSelector : '.element',
getSortData : {
colors : function( $elem ) {
return $elem.find('.colors').text();
},
number : function( $elem ) {
return $elem.find('.number');
}
}
});
var $sortedItems = $container.data('isotope').$filteredAtoms;
// filter items when filter link is clicked
$('#filter a').click(function(){
alert("filter");
var selector = $(this).attr('data-filter');
$container.isotope({ filter: selector });
return false;
});
// sorting
$('#sort a').click(function(){
var sortType = $(this).attr('data-sort');
$container.isotope({ sortBy : sortType });
return false;
});
});
});
function updateContent(path, args) {
$.ajax({
url: (path+args),
type: "POST",
success: function( data ){
$(allCards).remove();
$("#content").html( data );
$('#content').isotope( 'reLayout', callback );
}
});
}
function callback() {
alert("success: "+$('#content').height());
}
</script>
Whenever I use the updateContent() function the height of the #content div becomes 0. I think there could be a race condition happening due to the content not having been fully loaded and isotope initializing before the next set of images have been loaded.
It works fine when I first load the document. However when I load a new set of images with updateContent() it sets the #content div height to 0. Ideally I'd like to be able to load a new set of images and isotope would initialize as it normally does and height should be an appropriate value for all of the images to fit inside the #content div.
The following part needs to be fixed and this is what I have so far...
$(allCards).remove(); // remove all previous images
$("#content").html( data ); // load new images
$('#content').isotope( 'reLayout', callback ); // <- reinit isotope to manage the new images
Basically I'd like it to remove all previous images and load all the new images in data and isotope would work with the new images.
I solved the issue by prepending. I'm putting this up so people don't have to suffer like I did.
$("#content").isotope( 'remove', $(".element"), function(){
$("#content").prepend($(data)).isotope( 'reloadItems' ).isotope({ sortBy: 'original-order' });
});
Have a look at http://isotope.metafizzy.co/docs/methods.html
Firstly make sure the markup your appending to $("#content") has the .element class.
If they don't have it, you'll need to append it to them before attempting to insert them into the isotope container.
Secondly try using the inbuilt method for removing appending objects
.isotope( 'addItems', $items, callback )
In your case it would be:
$("#content").isotope( 'remove', $(".element"), function(){
$("#content").isotope( 'addItems', $(data), function(){
$("#content").isotope( 'reLayout' callback );
});
});
You probably do not need to utilize the callbacks from 'remove' and 'addItems', but without a jsfiddle example it's hard to tell.

Return updating variable from function

I'm trying to use javascript/jQuery to find the width of the window and use the variable in a later function.
$(function resizer() {
function doneResizing() {
var windowWidth = $(window).width();
return windowWidth;
}
var getWidth = doneResizing();
var id;
$(window).resize(function() {
clearTimeout(id);
id = setTimeout(doneResizing, 0);
});
doneResizing();
return getWidth;
});
var finalWidth = resizer()
So the resize function updates whenever the window is resized and windowWidth is updated automatically. When the variable is returned outside of the function, getWidth doesn't update with a window resize unless I refresh the page. Any ideas? I just picked up js/jq 2 weeks ago, and I'm doing my best to wrap my head around returns and closures, so I may have overlooked something here. Thanks.
it would be much simpler to do the following:
var finalWidth;
$( document ).ready(function() {
//Set this the first time
finalWidth = $(window).width();
$(window).resize(function() {
//resize just happened, pixels changed
finalWidth = $(window).width();
alert(finalWidth); //and whatever else you want to do
anotherFunction(finalWidth);
});
});
and use finalwidth outside as it is a global variable.
You get the same functionality without the complexity.
Update
As commented, global variables are bad practice ( e.g. also http://dev.opera.com/articles/view/javascript-best-practices/ ).
To avoid a global variable finalWidth can be moved inside document.ready and any necessary functions can be called from inside resize(function() { event handler.
Update 2
Due to the problem with dragging causing multiple resize events, code has been updated.
Reference: JQuery: How to call RESIZE event only once it's FINISHED resizing?
JSFiddle: http://jsfiddle.net/8ATyz/1/
$( document ).ready(function() {
var resizeTimeout;
$(window).resize(function() {
clearTimeout(resizeTimeout);
resizeTimeout= setTimeout(doneResizing, 500);
});
doneResizing(); //trigger resize handling code for initialization
});
function doneResizing()
{
//resize just happened, pixels changed
finalWidth = $(window).width();
alert(finalWidth); //and whatever else you want to do
anotherFunction(finalWidth);
}
function anotherFunction(finalWidth)
{
alert("This is anotherFunction:"+finalWidth);
}
You have mixed up your resizer function with the jQuery ready function.
To keep track on the window width you can do
(function ($) {
var windowWidth;
// when the document is fully loaded
$(function(){
// add an resize-event listener to the window
$(window).resize(function(){
// that updates the variable windowWidth
windowWidth = $(window).width();
})
// trigger a resize to initialize windowWidth
.trigger('resize');
// use windowWidth here.
// will be updated on window resize.
});
}(jQuery));

Categories