How can I select an img placed within a span with appendChild? - javascript

I'm using picturefill.js (Scott Jehl): https://github.com/scottjehl/picturefill/blob/master/picturefill.js
Here's how I have it setup, (some code omitted b/c it was just more media query stuff) using span tags and data attributes as in his documentation:
<figure>
<a href='http://www.casaromeromexican.com'>
<span id="picture" data-picture data-alt="Casa Romero Mexican website">
<span data-src="img/casa-romero-mexican.jpg"></span>
<span data-src="img/casa-romero-mexican#2x.jpg" data-media="(min-device-pixel-ratio: 2.0)"></span>
<span data-src="img/casa-romero-mexican-md.jpg" data-media="(min-width: 768px") </span>
// and so on...
The correct img is being loaded and placed on the page, as expected. Here's is a snippet of the generated HTML:
<span data-src="img/casa-romero-mexican-md.jpg" data-media="(min-width: 768px)"><img alt="Casa Romero Mexican website" src="img/casa-romero-mexican-md.jpg"></span>
What I'd like to do is add a class to whichever img tag ends up getting generated.
However, I'm not even able to select the img that is appended! Here's what I'm working with:
alert(($('#picture').children().find('img').size()));
This returns 0, even though the image is on the page. I am expecting it to return a size of 1, b/c based on the media queries, 1 of the images is appended to the page with picturefill.
Just to be sure that there wasn't issues with the DOM loading, I placed picturefill.js in the header (even though JS should go in footer most of the time), and even did this:
$(document).ready(function() {
alert('ready!');
alert(($('#picture').children().find('img').size()));
});
Still doesn't seem to find the img.

http://learn.jquery.com/using-jquery-core/document-ready/
After reading this, I understood why jQuery was not finding the img. In this case, it was necessary to use $( window ).load(function() { ... }). This will not run the script until the entire page is loaded, as opposed to $( document ).ready(), which only waits for the DOM.
In other words, $( document ).ready() is fine most of the time, but not when waiting on media elements that may take longer to load and/or need to be fetched with a request!

Related

Does an <img> tag load along side with the rest of the page or after?

I'm new to HTML programming and I'm trying to understand the <img> tag in html
but I cannot understand when the image is being loaded
for example in this code:
#pic
{
display:inline-block;
background-image:url('https://cdn.pixabay.com/photo/2015/04/19/08/32/marguerite-729510__340.jpg');
height:20rem;
width:35rem;
}
<div>Hello how are you?</div>
<img src="https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__480.jpg">
<br>
<span id="pic"></span>
<div>I'm good wbu?</div>
Is the <img> being loaded first or after or simultaneously while the other tags are being loaded?
What exactly is the order of the DOM elements loading when a browser loads a new webpage?
Do the same rules apply to the background-image ?
Html code is rendered line by line , in your code img tag is rendered after your first div tag, you give https src to the image,
Browser rendering machine doesn't wait whenever image is available and then rendered the next line. That's why you have seen that sometimes at the beginning we can see all the part of website except image.
Img tag is rendered with like all the tag. But to render image it takes time

WP: Enqueue JS at very end of the loading site

I've got a script, which changes div's placement a little. To work fine, it must be loaded at very end of the page loading - it's because my WP page have few different plugins, some of them uses the js to display content on page, and moving that content is what I want to achieve.
I've tried to put 999999 priority to add_action parameter, also tried to cheat with js function settimeout, but that's not the point - it must work every time, and my "solutions" didn't provide me that. There was always some linked scripts which were loaded later than mine, timeout works sometimes, but only sometimes...
Plugins which i think could collide: Woocommerce, Easy FancyBox, Instagram Feed.
Thx for help!
[EDIT]
So, i need to change this:
<div class="foo">
<div class="bar">
<div class="destination">
</div>
</div>
<div class="origin">
</div>
</div>
To this:
<div class="foo">
<div class="bar">
<div class="destination">
<div class="origin">
</div>
</div>
</div>
</div>
My js code is:
var from = document.getElementsByClassName("origin");
jQuery("window").on("load",function(){
jQuery.each(from, function(i, el) {
jQuery(el.parentNode.parentNode).find(jQuery(".destination"))[0].appendChild(el);
});
});
And only what i need is to load it up last after all js files.
Also, the function which works sometimes looks that:
var from = document.getElementsByClassName("origin");
setTimeout(function() {
jQuery.each(from, function(i, el) {
jQuery(el.parentNode.parentNode).find(jQuery(".destination"))[0].appendChild(el);
});
},1);
instead of using $( document ).ready(function() { try to use $( window ).on( "load", function() {
You're over-complicating things ... especially by mixing vanilla JS DOM methods and jQuery so much.
$('.destination').each(function() {
$(this).parent().next().appendTo($(this));
})
For each .destination element, go up to its parent (.bar - could explicitly pass that selector into parent(), but there seems no need here), grab the next sibling of that - and append it to the current destination element we started with, done.
https://jsfiddle.net/a04fp226/
That wrapped into document ready should do the trick - provided the elements exist at that point already. If not, you need to figure out the correct time when to run this - that would depend on how those elements are created in the first place. If another script adds them on document ready, it becomes about execution order.

How to get parentNode ID and use it as a variable

I'm trying to run a script on images within specific blog posts. Each post div is given a unique ID by Blogger that I'm trying to get. Because I only want to run the script on posts containing the function call and not the entire page, I want the function to basically find the ID of the div that's calling it, store that ID as a variable, and then pass that variable in to my function.
<script>
var scriptTag = document.scripts[document.scripts.length - 1];
var parentTag = scriptTag.parentNode;
</script>
This returns the correct element but the second I wrap it in a function(){} it doesn't work anymore. How can I assign these variables from within a function so I don'thave to clutter up every post's html with a bunch of variable declarations?
Secondly, once I have these variables assigned is there a way to use the value stored with the getElementByID method to actually select the element?
var parentDivID = parentTag.id;
var postID = document.getElementByID(parentDivID); //can't figure out how to select using this as the variable
For ease of use I'd like it if I could simply wrap the function call in script tags and stick it at the end of my post's html whenever I need to use it.
Details
The script I want to run finds images within divs with a specified class and resizes them to fit side-by-side so that the outer edges of the images completely fill the width of the div.
Here is the question covering that script:
Force dissimilar images to equal heights so combined widths fill fixed div
I would like to call this script at the end of any post body where I plan to use side-by-side formatting. The reason I want to call it at the end of a post instead of on the entire page is because the page uses "infinite scrolling" and I'm worried that as posts load after the fact the resizing script will have already been run and newly loaded posts will not be resized.
So I want the function to be able to find the unique ID of the div that contains the call, use that as a variable and ask the script to look inside that post for divs of a certain class, then look within those divs for image tags and resize those images. I hope that makes sense.
Here's an example of what I'd like the post's html to look like:
<div style="width:500px; margin:auto;">
<div class="widthVal x2">
<img class="caption" alt="Caption 01" src="sample01.jpg" />
<img class="caption" alt="Caption 02" src="sample02.jpg" />
<img class="caption"alt="Caption 03" src="sample03.jpg" />
</div>
<script> resizeMagic(); </script>
</div>
Thanks for any help!

Is there a way to make images inside display:none not get downloaded by the browser?

I want the browser (mobile webkit especially) to NOT download images that are inside display:none divs. Right now, they get downloaded and not rendered.
Is there a jquery plugin to do this?
you can use data-* attributes. that way, you can have jQuery load them on demand:
<img data-source="image_path">
//this one gets all images and loads them
$('img').each(function(){
//loads the source from data-source
this.src = this.getAttribute('data-source');
});
<img data-source="image_path" class="foo">
<img data-source="image_path" class="foo">
//this one gets all images that have class foo and loads them
$('img.foo').each(function(){
//loads the source from data-source
this.src = this.getAttribute('data-source');
});
ofcourse you need to wrap this in a function so that you can call which images on demand. like:
function loadImg(selector){
$(selector).each(function(){
this.src = this.getAttribute('data-source');
});
}
//load images with class foo:
loadImg('.foo');
I don't think so. To be sure, you would need your original HTML DOM to exclude the hidden images, which you could do with server-side programming based on user agent sniffing (although that is not recommended). Modifying the DOM after document.ready or document.load will mean that the browser has already had a chance to request assets from the server even if they might not be displayed.
It would be unusual but if you still want to use jQuery you could follow #Pointy's advice and make all images placeholders in your markup. Then replace the :visible placeholders with the images you want using an attribute as the data source. No plugin is needed, just use something like replaceWith() or attr() to swap out the placeholder node for the image you want downloaded or change the src attribute.
I would use a 1x1 transparent gif as the placeholder with the correct height and width attributes rather than no source <img> for a placeholder. That way the page flow will be determined correctly when the page renders so it won't jump around as your images lazily load.

How to load picture images via click on a picture?

At the moment i load default images for every picture in my app. I want to load the real picture of all images in div 5 if i click on any picture of div 5. At the moment i use the onclick event of the img tag with:
switchImg(this, "LINK_FOR_PICTURE")
my js snippet:
function switchImg(img, url){
$(img).attr("src", url);
}
At the moment it only loads the picture that i clicked on.
here the HTML snippet:
<div id="1">
</div>
<div id="2">
</div>
..
<div id="5">
<img src="DEFAULT_IMG" onclick="switchImg(this, "LINK_FOR_PICTURE_1")" alt="No_picture">
</div>
<img src="DEFAULT_IMG" onclick="switchImg(this, "LINK_FOR_PICTURE_2")" alt="No_picture">
</div>
<img src="DEFAULT_IMG" onclick="switchImg(this, "LINK_FOR_PICTURE_3")" alt="No_picture">
</div>
.....
</div>
How do i need to change my code that following condition is true:
i click on any picture in div id=5 and all this pictures gets the correct picture link (LINK_FOR_PICTURE_1, LINK_FOR_PICTURE_2, etc) as src. The other pictures in the other divs don`t change and still display the default img. (Div id 5 is an example the same procedure should be possible for other divs with pictures).
Please keep in mind that the img link changes for every picture.
using only numbers for id is bad practice
your div id="5" is closed right after first image
you are using double quotes in double quotes in your example - bad idea
by calling switchImg(this, "LINK_FOR_PICTURE_3") using this, "this"
represents only clicked image. You would need something like
function switchImg(img){
$(img).closest('div').find('img').each(function(){
$(this).attr("src", $(this).attr('imglink'));
});
}
using html
<img src="DEFAULT_IMG" onclick="switchImg(this);" imglink="LINK_FOR_PICTURE_3" alt="No_picture">
Take advantage of jQuery and event delegation and observe when the div is clicked to then find all the images within that div and trigger the src change. To explain this better i've quickly thrown together an example on JSFiddle
http://jsfiddle.net/Phunky/EnhUE/
In my example you can either click images individually or the div for them all.
This will do it:
HTML
<div id="5">
<img src="DEFAULT_IMG" data-fullImg="link_for_picture1" alt="No_picture">
<img src="DEFAULT_IMG" data-fullImg="link_for_picture1" alt="No_picture">
<img src="DEFAULT_IMG" data-fullImg="link_for_picture1" alt="No_picture">
</div>
JS
function switchImg(img){
img.attr("src", img.data('fullImg'));
}
$(function(){
var allImages = $('#5 img');
allImages.click(function(){
allImages.each(function(){
switchImg($(this));
});
});
});
HTML changes
I assume you want all the img tags wrapped in #5, no? Because your current HTML markup is invalid.
Additionally, ids can't technically start with a number. It probably won't cause a problem in most browsers, but it is invalid.
I'm using an HTML5 data-attribute to store the link for the picture. This will work even in non-HTML5 browsers. I'll get to this in a moment.
Finally, inline-JS is generally a bad idea because it is difficult to maintain. Using jQuery, it's very easy to bind code to the onclick event.
JS Changes
allImages.click() binds the code inside to the click event on any of the images.
The .each() function then loops over all those images, passing itself as a jquery object to the switchImg function.
My modified version of the switchImg function doesn't need a second parameter, because it can simply use the jQuery object to access the data-fullImg attribute. If using a version of jQuery prior to 1.6 (or something like that), using the .data() method in the way I did won't work. You'd instead need to use .attr('data-fullImg').
EDIT
In response to the OP's comment on this post:
$(function(){
$('img.showOriginal').click(function(){
$(this).parent().children().each(function(){
switchImg($(this));
});
});
});
This code assumes that you put the class"showOriginal" on every img tag, since I doubt that you truly want to apply this functionality to every single img tag on the page. Beyond that, we have this part: $(this).parent().children(). That simply traverses the DOM up to the parent element (#5, #2, whatever), and then back down to all the children (the images you want to change).

Categories

Resources