I am attempting to incorporate a script (written by "dystroy" I believe) that centers an image vertically within a div with the overflow hidden. It works quite well but many of my images are dynamically loaded upon mouseover.
I need to find a way to call the script upon image load. It's been two days now and as JS/JQuery aren't my native language, I find my self here.
Can anyone suggest how I might get the following to fire on image load?
Many thanks!
<script type='text/javascript'>//<![CDATA[
$(window).load(function(){
$('.container').each(function () {
var $img = $(this).find('img');
$(this).scrollTop(($img.height() - $(this).height()) / 2);
$(this).scrollLeft(($img.width() - $(this).width()) / 2);
});
});
//]]></script>
$(document).ready(... Will wait until everything on the page is loaded (including the images) before executing the function.
<script type='text/javascript'>//<![CDATA[
$(document).ready(function(){
$('.container').each(function () {
var $img = $(this).find('img');
$(this).scrollTop(($img.height() - $(this).height()) / 2);
$(this).scrollLeft(($img.width() - $(this).width()) / 2);
});
});
//]]></script>
Perhaps you could combine the load api (https://api.jquery.com/load/):
$("#book").load(function() {
// Handler for .load() called.
});
with the event delegation to make it so that any new images loading inside one of your specified divs get an onload function applied to them (https://learn.jquery.com/events/event-delegation/):
// attach a delegated event
$("#list").on("click", "a", function(event) {
event.preventDefault();
console.log($(this).text());
});
Related
I am trying to load a web web page inside a div with an ajax call but not working. it's showing this error
jquery.min.js:2 [Deprecation] Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience
how to solve this issue.
<div class="warper">
<div class="menu">
Home
Page One
Page Two
Page Three
</div>
<div id="content"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$(document).ready(function () {
$("#content").load('home.html');
// Set trigger and container variables
var trigger = $('.menu a'),
container = $('#content');
// Fire on click
trigger.on('click', function () {
// Set $this for re-use. Set target from data attribute
var $this = $(this),
target = $this.data('target');
// Load target page into container
container.load(target + '.html');
// Stop normal link behavior
return false;
});
});
</script>
Just to be specific, you're trying to load content into a div, not a webpage. A webpage would have it's own document and DOM and such and would require an <iframe>
Your issue could be with your use of .data() instead of .attr(). Although in my answer I use the vanilla javascript .getAttribute(), which does the same thing and saves a jquery call. Essentially you're code is trying to :
container.load(undefined + '.html');
I've never used the load method like this, (I don't know why they decided to overload it for event handeling and ajax) but it would look something like this:
<script>
$('#content').load('home.html');
$('.menu').on('click', 'a', function (e) {
e.preventDefault(); //stop normal link behavior
$('#content').load(this.getAttribute('data-target') + '.html');
});
</script>
Also, if your script is at the bottom of the <body>, you don't need $(document).ready(), as the code won't run until the document is ready anyway.
With jQuery 3.3.1 load() I am adding content with a few HTML img tags inside and then I want to check the viewport for visible elements AFTER
all the pictures have finished loading.
My problem is that I am unable to know when the dynamically added pictures have been fully loaded in my <div id="#content">.
This is my JS code for loading the new content:
// Replace the #content with content from a file containing a few `img` tags
$("#content").load("image-list.html", function() {
console.log("Now my images have fully loaded???");
});
I have tried this:
// Show me which event is triggered after load()
$(window).on("load resize scroll", function(event) {
console.log(event);
});
// Check if I can get when the images have fully loaded
$("img").on("load", function() {
console.log("Load image event???");
});
I also have tried some black-magic with waiting X milliseconds and looping through all image tags but this is for sure NOT the way to go as it is obscure!
The result of the above is:
I get the Now my images have fully loaded message immediately after I have loaded the file but it does not wait to show the message to after everything has been rendered
I do not get the console.log(event) message at all
I do not get any Load image event messages at all
I am debugging this by slowing down the speed with Chromes network option:
The reason your Load image event??? log is not firing, because you are not late binding the event handler on the images, thus, the on function will not fire for images that were added dynamically to your html.
To late bind, you can modify that function the following way:
$(document).on('load', 'img', function() {
console.log("Load image event???");
});
But if an image takes a long time to load, and you are trying to do something after all the new images were loaded which came from your image-list.html, I suggest something like the below approach:
Try putting the load listener, inside the callback function of the load method, like this:
$("#content").load("image-list.html", function() {
var numberOfImages = jQuery("#content img").length;
$("#content img").one('load', function() {
numberOfImages--;
if (numberOfImages == 0) {
console.log("All the images have loaded");
}
});
$("#content img").each(function() {
if (jQuery(this)[0].complete) jQuery(this).trigger("load");
});
});
You just have to be careful, as apparently, the load event will not fire, if the image you are loading was already cached, and loaded from the cache. There are workarounds for that too.
EDIT: The above code will take care for the situation where the images are loaded from cache also.
in this small project I tried to play with window.load and $(document).ready()
https://jsfiddle.net/23rupa07/
What I read was that $(document).ready() is triggered immediately when DOM is loaded and window.load is waiting until for example images are loaded.
For jQuery version 2.2.4 it's working as is mentioned above, but when I change jQuery to version 3.1.0 the order is reverted.
Check screenshot. Does anyone know why?
document ready change between jQuery2 and jQuery3
One of the changes of jQuery 3 is that as of now - the document-ready handlers are asynchronous, even if the document is currently ready at the point where the handler is added. This provides a consistent code execution order that is independent of whether the document is ready or not[1].
This change required implementing a queue functionality for the document-ready callbacks, and this also affect other calls for events that are not called from the jQuery object.
If we take this code for example:
window.addEventListener('DOMContentLoaded', function() {
console.log('vanilla - DOMContentLoaded');
});
$(function(){
console.log('jquery - DOM loaded');
});
jQuery2 will give us:
jquery - DOM loaded
vanilla - DOMContentLoaded
jQuery3 will give us:
vanilla - DOMContentLoaded
jquery - DOM loaded
The behavior we see in the OP is related to a race-condition between the "fire" event of the document-ready's callbacks and the window.onload function.
This code will can show that the two functions run "at the same time", and it's only a matter of code-execution inside the VM of the browser:
$(function(){
console.log('jquery - DOM loaded')
});
window.onload = function(){
setTimeout(function() {
console.log('window - loaded');
}, 0);
}
<script type="text/javascript" src="//code.jquery.com/jquery-3.1.0.js"></script>
Regarding the question about the images - since the images are already in your cache when you load the document, it only seems like the window.onload function is called before the document.ready (it's a race condition), however if you will make sure the images will never cache - you will see that you get exactly the same results for both jquery2 and jquery3.
jQuery 2
$(document).ready(function(){
console.log('jquery - DOM loaded');
});
window.onload = function(){
console.log('window - loaded');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script>
for (i = 0; i < 6; i++) {
document.writeln('<img src="https://o.aolcdn.com/commerce/autodata/images/USC60LGC051A021001.jpg?'+ parseInt(Math.random()*10000) +'" alt="">');
}
</script>
jQuery 3
$(document).ready(function(){
console.log('jquery - DOM loaded');
});
window.onload = function(){
console.log('window - loaded');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script>
for (i = 0; i < 6; i++) {
document.writeln('<img src="https://o.aolcdn.com/commerce/autodata/images/USC60LGC051A021001.jpg?'+ parseInt(Math.random()*10000) +'" alt="">');
}
</script>
I am working on my wordpress site, and i use a static page for my front/home page. I wanted to use parallax scrolling but i cant get my script to load and work.
I linked it in header like this:
<script type="text/javascript" src="<?php bloginfo('template_url'); ?>/js/scroll.js"></script>
and this is my scroll script:
(function($) {
$.fn.parallax = function(options) {
var windowHeight = $(window).height();
// Establish default settings
var settings = $.extend({
speed: 0.15
}, options);
// Iterate over each object in collection
return this.each( function() {
// Save a reference to the element
var $this = $(this);
// Set up Scroll Handler
$(document).scroll(function(){
var scrollTop = $(window).scrollTop();
var offset = $this.offset().top;
var height = $this.outerHeight();
// Check if above or below viewport
if (offset + height <= scrollTop || offset >= scrollTop + windowHeight) {
return;
}
var yBgPosition = Math.round((offset - scrollTop) * settings.speed);
// Apply the Y Background Position to Set the Parallax Effect
$this.css('background-position', 'center ' + yBgPosition + 'px');
});
});
}
}(jQuery));
$('.parallax-section-1').parallax({
speed : 0.15
});
I found some articles that i would have to use the functions.php and enque the script but i never did that before so im a bit lost, so any help would be highly appreciated.
First things first, lets load the script the "WordPress Way". This will actually help simplify troubleshooting.
To do that, edit your theme's functions.php file.
In that file, add this PHP code. Be sure it is between <?php opening / closing tags.
Typically, I'd recommend adding it to the end of the file, but if your file includes this ?> - that the code you add is before the ?>:
add_action('enqueue_scripts', 'my_custom_script');
function my_custom_script() {
// Be sure jQuery is loading
wp_enqueue_script('jquery');
// Load your script
wp_enqueue_script('my-parallax-script', get_template_directory_uri() . '/js/scroll.js', array('jquery'), FALSE, TRUE);
}
Now - once you do this, you will want to be sure that your script is in fact loading. To do that, visit the page, then do a VIEW SOURCE in your browser. When you view source, do a search of the code for "scroll.js" - if you find it, great. Click on the url (or copy / paste it into your browser window) and be sure that the script is referencing the right location. If not, you'll need to be sure to move the script to the right location, so the page will load it.
Next Step
You have a problem with your script that will not work in WordPress. You are referencing jQuery with the $ symbol, AND it appears that you are referencing an element directly, which means there's a good chance the element doesn't exist when the script will run, which means that it won't have the desired effect.
Instead, we need to do two things. Because WordPress loads jQuery in what's called no conflict mode, you need to reference it using jQuery, not $. AND you need to put your code into a document ready function.
Thankfully, jQuery offers a slick way of doing the document ready that exposes the $ inside of the document ready, for convenience:
// Shorthand version of "No-conflict-safe" document ready
jQuery(function($) {
// Inside here, we can use $ instead of jQuery
$('.parallax-section-1').parallax({
speed : 0.15
});
});
If it still does not work after all of this, then you need to open your console in your browser, and look for any javascript errors. They will help you identify what is going on, which is the first step to solving the problem.
I want to set div#top height equals image height. I wrote:
$(document).ready(function() {
setTopHeight();
});
/*
* window resizing
*/
$(window).resize(function() {
setTopHeight();
});
/*
* setting #top height by banner height
*/
var setTopHeight = function() {
var bannerHeight = $('#banner-image').height();
$('#top').height(bannerHeight + 'px');
};
It works on resize, but doesn't at reload. I've tried sth like this:
$(document).ready(function() {
setTimeout(function() {
setTopHeight();
}, 50);
});
and it works, but of course it's not solution. Can somebody tell me why console.log returns 0?
$(document).ready(function() {
console.log($('#banner-image').height());
});
.ready won't work because your image has not been loaded yet. use .load
$(document).ready fires when the DOM is ready, but the image might still be downloading - so no height yet. You might use jQuery load on the image.
$('#banner-image').on('load', function () {
setTopHeight();
})
The jQuery .load() acts as an event handler. .load() is a shortcut for .on('load, function(){}). It will be triggered once the image/element if fully loaded.
Example 1:
$('#banner-image').load(setTopHeight);
Example 2
$('#banner-image').load(function(){
setTopHeight();
});
Example 3
$('#banner-image').on('load', setTopHeight);
Try .load() instead .ready()
$(window).load(function() {
setTopHeight();
});
The image load is in a second HTTP round after your document. so you need listen to image load
$('#banner-image').load(setTopHeight);