JQuery append image not showing - javascript

For this code block
$(document).ready(() => {
for (let i = 0; i < 10; i++) {
$("#main").append(factory());
}
});
this will show the image:
function factory() {
return $('<image class="champ-icon rounded-circle" src="resources/irelia.jpg" />');
}
while this doesn't
function factory() {
let $champIcon = $(document.createElement("image"))
.addClass("champ-icon rounded-circle")
.attr("src", "resources/irelia.jpg");
return $champIcon;
}
I'm using Bootstrap 4 as well.
The page currently is just a static mock up. I want to dynamically build elements from data given to it by a local server.
I literally just messed around with HTML/CSS and jQuery over the weekend so I'm not sure what went wrong here. Shouldn't both function return the same jQuery object?
Thanks!
CSS class
.champ-icon {
width: 100px;
height: 100px;
}
Edit: creating it with normal javascript works as well.
function factory() {
let img = new Image();
img.src = "resources/irelia.jpg";
img.className = "champ-icon rounded-circle";
return img;

That's because you are trying to programmatically create <image> element in html, which... doesn't exist. To insert element on a page you should use <img src="">, not <image...>. Change this line
let $champIcon = $(document.createElement("image"))
to
let $champIcon = $(document.createElement("img"))
And it should work.

Related

Javascript – PNG not showing when adding dynamically

I’m a beginner JS coder and I’m struggling with the following – can anyone please help?
I’m trying to add a series of PNGs to a page using a function which will allow the placement of multiple copies of the same image and also assign a unique reference to each copy of the image.
The images are not showing in the page, plus the console.log() shows that the 2 images created by the code below both have the same position on the page.
var imgSrc = 'arrow_red.png';
function generateArrow(numArrows) {
var img = document.createElement('img');
img.src = imgSrc;
for (i = 1; i <= numArrows; i++) {
window['arrow'+i] = img;
}
}
generateArrow(2);
arrow1.style.position = 'absolute';
arrow1.style.top = '50px';
arrow1.style.left = '50px';
arrow2.style.position = 'absolute';
arrow2.style.top = '100px';
arrow2.style.left = '100px';
console.log(arrow1);
console.log(arrow2);
Why are the images not showing in the page and why does the console.log() show that the 2 images created are both using the same positional co-ordinates?
When you create a new element, it only exists in memory - - it hasn't been added to the document that the browser is currently rendering. So, it's not enough to create new elements and configure them. You must then inject them into the DOM with parentElement.appendChild(newChild).
Here's an example:
let newChild = document.createElement("img");
newChild.src = "https://static.scientificamerican.com/sciam/cache/file/D14B1C22-04F8-4FB4-95937D13A0B76545.jpg?w=590&h=393";
let parent = document.querySelector(".parent");
parent.appendChild(newChild); // <-- Now, inject the new element
img { width: 400px; }
<div class="parent"></div>
Now, in your particular case, you've got more issues than just this to work on. You are only creating a new image element one time because your line that does that is not inside of your loop. Also, the way you are referring to arrow1 and arrow2 in your code and with window['arrow' + i] indicates that you have img elements with ids already set up in your HTML, which is not an ideal approach. Next, it's much simpler to set up the CSS you'll want to work with as pre-made classes ahead of time, rather than setting up the CSS as inline styles in the script.
As my answer above indicates, you need to have a parent element that will contain the new element(s) that you create, so your solution would really look something like this:
var imgSrc = 'https://icon2.kisspng.com/20180320/rle/kisspng-arrow-computer-icons-clip-art-red-arrow-line-png-5ab19d059bfa98.5843437015215895096389.jpg';
// You can pick any pre-existing element to be the "parent"
var parent = document.getElementById("parent");
function generateArrow(numArrows) {
for (i = 1; i <= numArrows; i++) {
// The creation of the elementt and it's configuration
// need to be inside of the loop to make several of them
var img = document.createElement('img');
img.classList.add("position" + i); // Add pre-made CSS classes
img.src = imgSrc;
parent.appendChild(img); // Inject the new element inside of the parent
}
}
generateArrow(5);
/*
Instead of setting inline styles, use pre-made CSS classes
that you can just connect or disconnect to/from
*/
/* All the injected images get this: */
#parent > img { width:40px; position:absolute; }
/* These get assigned individually */
.position1 { top:50px; left:50px; }
.position2 { top:100px; left:100px; }
.position3 { top:150px; left:150px; }
.position4 { top:200px; left:200px; }
.position5 { top:250px; left:250px; }
<div id="parent"></div>
You usually add elements to DOM using document.appendChild(element);, or in your case: document.appendChild(img);. (Or any preferred parent instead of document)
Edit: removed second part addressing variable declaration, since I didn't notice the window["arrow" + i] = img.
You need to add the generated element to the DOM using the appendChild() method.
Furhermore you're actually just generating a single instance of the image because it's happening once outside of the for-loop. This is why the console shows identical screen positions for 'both' images because actually you're referring to the same image instance.
Try this:
function generateArrow(numArrows) {
var img;
for (i = 1; i <= numArrows; i++) {
img = document.createElement('img');
img.src = imgSrc;
document.body.appendChild(img);
window['arrow' + i] = img;
}
}

How to get ALT from IMG tag in JavaScript

I am using THIS script to display my galleries in lightbox. I was using some plugins but all of them does not display the alt=""(alt added in media in wordpress).
How can I modify the code from the link below to display the alt attributes ?
I found something in the code, but I dont know how to put the dynamic alt there(commented by uppercase text in the code). Dynamic I mean that as user will add the img in wordpress dashboard, he will put the alt then.
{
key: '_preloadImage',
value: function _preloadImage(src, $containerForImage) {
var _this4 = this;
$containerForImage = $containerForImage || false;
var img = new Image();
if ($containerForImage) {
(function () {
// if loading takes > 200ms show a loader
var loadingTimeout = setTimeout(function () {
$containerForImage.append(_this4._config.loadingMessage);
}, 200);
img.onload = function () {
if (loadingTimeout) clearTimeout(loadingTimeout);
loadingTimeout = null;
var image = $('<img />');
image.attr('src', img.src);
image.addClass('img-fluid');
image.attr('alt',"Temp TEXT"); // HERE I WOULD LIKE TO DISPLAY THE ALT AUTOMATICALLY - NOT STATIC AS IT IS NOW
// backward compatibility for bootstrap v3
image.css('width', '100%');
$containerForImage.html(image);
if (_this4._$modalArrows) _this4._$modalArrows.css('display', ''); // remove display to default to css property
_this4._resize(img.width, img.height);
_this4._toggleLoading(false);
return _this4._config.onContentLoaded.call(_this4);
};
img.onerror = function () {
_this4._toggleLoading(false);
return _this4._error(_this4._config.strings.fail + (' ' + src));
};
})();
}
img.src = src;
return img;
}
},
I am using wordpress on my page and my skills in JS are rather poor, so I am asking you :).
We don't really know what is the type of your img variable. If you want to set the alt tag of image to the one of img, simply do:
image.attr('alt', img.attr('alt'));
…if it's a jQuery object. Otherwise, if img is pure JavaScript, you can do:
image.attr('alt', img.alt);
if the img object holds the existing alt and image is the new jQuery object, then set it with jQuery
image.attr('alt', img.getAttribute('alt'))

Can I "pre-load" an image with JS to be used as a CSS background-image?

Can images be preemptively loaded into the page with javascript so that they can be used at any time as a CSS background image without any request/upload delay?
If so, how?
You don't even need to use JS for this (with the downside of delaying the page load event). Include something like this:
<img src="/path/to/image.jpg.png.gif.bmp" style="display: none" />
This will trigger a request for the image, and add it to the local cache. When you set the CSS background-image property, the image will already be in the local cache, eliminating the delay of another request.
Alternatively, you can accomplish the same thing without delaying the page load by creating the images in JavaScript (this solution allows for multiple images):
function preload(list, callback, imageCallback) {
var at, len;
at = len = list.length;
for (var i = 0; i < len; i++ ) {
var img = new Image();
img.onload = function() {
if( imageCallback ) {
imageCallback.call(this, this, len-at, len);
}
if( !--at ) {
callback(list);
}
};
img.src = list[i];
list[i] = img;
}
}
You'd call this with:
var list = preload(["1.png","2.png","3.png" ... ], function complete(list) {
console.log('images all loaded!');
}, function loaded(image, index, listCount) {
console.log('image ' + index + ' of + 'listCount + 'is loaded');
});
(Thanks to #rlemon for the preload code)
I don't think that using an hidden img tag is the correct way, i'd rather use an "new Img(url)" and attaching to it an onload event where you can set the image as background-image to the element you want.
img = new Image();
img.onload = function(){
// set background-image
};
img.src = image_url;
be sure to put img.src after attaching onload, or you risk that the image is loaded before the event is attached.
Maybe a more complete base to build on:
function preload(list, callback, imageCallback, errorCallback) {
if (typeof(list) === "undefined"
|| list.length === 0) {
return;
}
var len = list.length;
var timers = {};
var checkLen0 = function() {
if (len === 0) {
if (typeof(callback) === "function") {
callback();
}
delete(timers)
}
}
var onload = function() {
clearTimeout(timers[img]);
if (typeof(imageCallback) === "function") {
imageCallback.call(img);
}
len--;
checkLen0();
}
var onerror = function() {
clearTimeout(timers[img]);
if (typeof(errorCallback) === "function") {
errorCallback.call(img);
}
len--;
checkLen0();
}
for (var i = 0; i < list.length; i++ ) {
var img = new Image();
img.onload = onload;
timers[img] = window.setTimeout(5000, onerror);
img.src = list[i];
}
}
While SomeKittens answer is valid, it'll delay the page load as commented by Jimmy. If you are using jquery, I'd go with something like this instead to keep your style, structure and logic separated:
<style>
.preload-img { display: none; }
</style>
...
<div class = "preload-img">/path/to/image.jpg.png.gif.bmp</div>
...
<script>
$(document).ready(function(){
$(".preload-img").each(function(){
preloadImage = new Image();
preloadImage.src = $(this).html();
});
});
</script>
Of course, from there on you can optimize/change it. The advantadge of this is that you can create the <div> dynamically with PHP and you can have all your javascript cached properly as a separated file.
There is an excellent framework for this job called Emerge.js
http://ilyabirman.net/projects/emerge/
Quote from project page:
Emerge.js is a framework for coordinated page loading. Normally, when a complex web page is loading, images appear in random order, causing unpleasant flashing. To replace it with nice and coordinated animations, programming is required. Emerge.js simplifies the task by removing the need to write any Javascript code. The framework uses a declarative approach, where you specify a desired behavior for each element and do not think about the implementation. Emerge.js uses jQuery.
Just as a caveat to SomeKittens' answer above, a particularly large background image should probably be added as a hidden background / via JavaScript after page load, as content images delay the firing of window.onload and may therefore create the perception of a slow loading page.
Given that it sounds like you're using dynamic content anyway, this may be an acceptable solution. It also allows you to do preloading programmatically as required, which may be better for maintenance.

Javascript - swap image on click or rollover

I know how to do this in jquery but i am trying to do the below in pure old school javascript. Can someone help:
$(".thumbnail").click(function() {
$("#mainImage").attr("src", $(this).attr("src"));
});
My ultimate goal is to click on a thumbnail and have the main image change but I need to do it in javascript (no jquery). I know this sounds pretty simple but I cannot figure it out. thank you.
There are so many things that jQuery gives you automatically that it's difficult to give you an answer that will do everything that your jQuery code does. Here is a simple example that will find every image with a class of thumbnail and set its onclick property to an event handler that performs an image swap.
onload = function () {
var bigImg = document.getElementById("mainImage");
for (var i = 0; i < document.images.length; i++) {
var img = document.images[i];
if (/\bthumbnail\b/.test(img.className) {
img.onclick = thumbnailHandler;
}
}
function thumbnailHandler(e) {
bigImg.src = this.src;
}
};
If you don't have to support IE7, you can simplify it slightly by using document.querySelectorAll():
onload = function () {
var bigImg = document.getElementById("mainImage");
var thumbs = document.querySelectorAll(".thumbnail");
for (var i = 0; i < thumbs.length; i++) {
thumbs[i].onclick = thumbnailHandler;
}
function thumbnailHandler(e) {
bigImg.src = this.src;
}
};
As an aside, I don't understand why you are setting the source of the main image to be the source of the thumbnail. Are you loading the full image into the thumbnail? That can be a lot to download and can quickly increase the memory footprint of your page.
Event delegation is probably the easiest way:
function expandThumbnail(e) {
if(~(' ' + e.target.className + ' ').indexOf(' thumbnail ')) {
document.getElementById('mainImage').src = e.target.src;
}
}
if(document.addEventListener) {
document.addEventListener('click', expandThumbnail, false);
} else {
document.attachEvent('onclick', function() {
expandThumbnail({
target: event.srcElement
});
});
}
If I understand right, you have a thumbnail image displayed, let's say '1thumb.png', of an associated image, let's say '1.png', and when you click this thumbnail image you want to change the src attribute of a main image, let's say with id='mainimg', to show the '1.png' image associated to the thumbnail instead of whatever it's showing. I tried this and it works:
Inside your <header>:
<script type='text/javascript'>
function myHandler(source){
document.getElementById('mainimg').src=source;
}
</script>
...
Your thumbnail code:
<img src='1thumb.png' onclick="myHandler('1.png')"/>
or, for rollover triggering:
<img src='1thumb.png' onmouseover="myHandler('1.png')"/>
Check it out: http://jsfiddle.net/d7Q27/7/

How to generate dynamic Image tags by jquery

I have fetched json through
<script>
function getjs()
{
var script =document.createElement("script");
script.setAttribute("type","text/javascript");
script.setAttribute("src","http://localhost:8080/vigs/f4json?user=3&callback=gr");
document.body.appendChild(script);
}
var i=0;
function gr(data)
{
for(i=0;i<data.size;i++)
{
document.getElementById('w').innerHTML =data.itemr[i].itmurl;
}
}
</script>
so, after fetching the urls it simply displays url of images in my div. I just confused how to write up code in jquery for same above task but also display images (by generating dynamix image tag appended to next one by one based on size in div) in my div with id mydiv.Or any alternative ?
your help would be appreciated..
thanks
Using JavaScript
function gr(data)
{
var w = document.getElementById('w');
for(i=0;i<data.itemr.length;i++)
{
var img = document.createElement('img');
img.src = data.itemr[i].itmurl;
w.appendChild(img);
}
}
$("<img>").attr("src", data.itemr[i].itmurl).appendTo($("#w"));

Categories

Resources