I have an empty div with a scrollbar:
<div id="figure1" style="width:1000px; height:300px; overflow:scroll;"></div>
And using javascript I am adding images into the div:
function add_img(imgID, src, x, y, height, width){
var img = document.createElement("img");
img.setAttribute('id', imgID);
img.setAttribute('src', src);
img.style.left = x;
img.style.top = y;
img.style.width = width;
img.style.height = height;
img.style.position = 'absolute';
document.getElementById('figure1').appendChild(img);
}
When I add a new image outside of the 1000x300px box, I want that image to only be visible when you use the scrollbar.
Instead, the images which lie outside of the box overflow beyond the edges of figure1. The scrollbar doesn't do anything.
How can I stop the images from overflowing?
Thanks!
I see two issue - first you need to add + "px" to your dimensions (at least if you use integer type parameters like I did).
The other thing would be not to use position = "absolute". For example position = "relative" seems to do the trick. (If you like, have a further read on the layout options in CSS, good luck)
https://jsfiddle.net/xpsu9usw/
Related
So I have this html / css / jQuery / js code that toghether shows a VERY large image in width. The base element should be invisible untill the image is loaded and set. Then the base element is made visible by a small fade.
However the behaviour is a little different.
Once the image is being loaded i can see the small text fading in and it takes a few seconds before then the image just pops up in once (not loading style like from top to bottom appearing)
This is the simplified code i use:
<script>
$(function() {
$("#base").hide();
var baseHeight = $(window).height();
var backLayerSRC = $('#img').attr('data-src');
$('#base').height(baseHeight);
var img = new Image();
var imgWidth, imgHeight;
img.onload = function() {
imgHeight = this.height;
imgWidth = this.width;
var factor = 1 * baseHeight / imgHeight;
totalWidth = Math.round(factor * imgWidth);
currentWidth = totalWidth;
$('#base').width(totalWidth);
$('#img').attr('src', backLayerSRC);
$('#img').height(baseHeight);
$('#base').fadeIn(500);
};
img.src = backLayerSRC;
});
</script>
<style>
#base {
position:absolute;
left:0px;
height:100%;
}
#base #img {
position:absolute;
left:0px;
top:0px;
}
</style>
<div id='base'>
some tekst
<img src='' id='img' data-src='path_to_very_large/image.png' />
</div>
Now, how could it be that it just doesn't fade in WITH the image?
Here is an example WITH the image, please check so it becomse clear what i mean
http://jsfiddle.net/uz8mvtap/3
It might depend on the time the browser needs to render the image after the script loaded it.
I played a little with your fiddle and came up with this:
$(function() {
$("#base").css({opacity: 0});
var baseHeight = $(window).height();
var backLayerSRC = $('#img').attr('data-src');
$('#base').height(baseHeight);
var img = new Image();
var imgWidth, imgHeight;
img.onload = function() {
imgHeight = this.height;
imgWidth = this.width;
var factor = 1 * baseHeight / imgHeight;
totalWidth = Math.round(factor * imgWidth);
currentWidth = totalWidth;
$('#base').width(totalWidth);
$('#img').attr('src', backLayerSRC);
$('#img').height(baseHeight);
$('#base').delay(1000).animate({opacity: 1.0},500);
};
img.src = backLayerSRC;
});
Basically using opacity for such a purpose is better because #base continues to occupy the same space, not disrupting the page. And the delay is for the browser, I figured for a big image it takes time to render, so let's give it it.
You could do that.
$('<img />').load( function(){
console.log('loaded');
}).attr('src', imgUrl);
After it loads, it summons a callback, use that callback to do custom function. Let me know how it goes.
or, by the way. You could enter image width and image height into custom var, and compare them on the load, once it reaches your wanted width and height, fade it in.
You seem to be slightly misinterpreting the timeline of your code:
Page loads, (text is visible on screen)
jQuery kicks in, hides #base (text is not visible on screen)
jQuery fades in #base (text is visible on screen again)
This is why you are briefly seeing the text before the image loads - because it is not initially hidden.
Add:
display: none;
To your #base style, add keep the rest of your code the same.
Also I've created an alternative JavaScript solution after you have added the above CSS:
$(function() {
const base = $("#base"),
img = $("#img"),
backLayerSRC = img.attr('data-src'),
baseHeight = $('#base').height();
img.attr('src', backLayerSRC);
img.one("load", () => {
img.height(baseHeight).promise().done(() => { base.fadeIn(2500); });
});
});
Here is the working example of your code I have created:
https://codebrace.com/editor/b16cabfee
Your baseHeight variable is undefined.
May be you should change
$('#base').height(baseHeight);
to
var baseHeight = $('#base').height();
Update:
I have updated the solution. I this solution I have wrapped div around both the text and image. Div wrapped around image is set to position:relative; to keep the image(set to absolute position) from covering the text.
https://codebrace.com/editor/b16f33afb
I'm trying to draw some stuff over loaded image. However, for some reason canvas appears below the image not on top. I'm doing it as follows:
I have the following container:
<div id="container">
<img src="{{url_for('static', filename='nature.jpg')}}" id="target" style="zIndex=1">
</div>>
And the I'm trying to add canvas as follows:
window.onload = function() {
var img = document.getElementById('target');
var width = img.naturalWidth;
var height = img.naturalHeight;
var canvas = document.createElement('canvas'); //Create a canvas element
//Set canvas width/height
canvas.style.width=width;
canvas.id = 'mycanvas';
canvas.style.height=height;
//Set canvas drawing area width/height
canvas.width = width;
canvas.height = height;
//Position canvas
canvas.style.position='absolute';
canvas.style.left=0;
canvas.style.top=0;
canvas.style.zIndex=100000;
canvas.style.pointerEvents='none'; //Make sure you can click 'through' the canvas
$('#container').append(canvas);
}
However, canvas appears below the image rather than on top of it. What am I doing wrong?
thanks
You've used the wrong syntax for the inline style style="zIndex=1", it should be style="z-index: 1", still, for z-index to work its element need a position other than static
In this case, since the img has no position, you can actually drop the z-index all together, as the canvas has a position, position: absolute, and will be layered on top of the image because of that alone.
For the canvas to be positioned relative to the container, the container need a position, i.e. position: relative
I am trying to create a button in javascript and make that button positioned below a canvas, the same width as the canvas, however, I don't seem to be able to set the top and width as a variable (the code is ignored). Here is my code: (problem lines commented)
var myButton = document.createElement('button');
myButton.style.position = 'absolute';
myButton.style.left = '0px';
myButton.style.top = canvasHeight; //
myButton.style.width = canvasWidth; //
myButton.style.height = '100px';
myButton.innerHTML = 'Restart!';
document.body.appendChild(myButton);
Note that the canvas is resizable, so I can't just type in a px value.
Here's my comment in an answer:
Make sure you have the correct format in canvasHeight and canvasWidth, e.g. "100px" rather than just "100".
I am trying to create a new div layer using JavaScript that can be absolutely positioned on the page after page load.
My code is as follows:
<html><head>
<script type="text/javascript">
function showLayer() {
var myLayer = document.createElement('div');
myLayer.id = 'bookingLayer';
myLayer.style.position = 'absolute';
myLayer.style.x = 10;
myLayer.style.y = 10;
myLayer.style.width = 300;
myLayer.style.height = 300;
myLayer.style.padding = '10px';
myLayer.style.background = '#00ff00';
myLayer.style.display = 'block';
myLayer.style.zIndex = 99;
myLayer.innerHTML = 'This is the layer created by the JavaScript.';
document.body.appendChild(myLayer);
}
</script>
</head><body bgcolor=red>This is the normal HTML content.
<script type="text/javascript">
showLayer();
</script>
</body></html>
The page can be seen here.
The problem I am having is that the div is sitting after the original body content rather than over it on a new layer. How can I remedy this?
Try with this instead:
var myLayer = document.createElement('div');
myLayer.id = 'bookingLayer';
myLayer.style.position = 'absolute';
myLayer.style.left = '10px';
myLayer.style.top = '10px';
myLayer.style.width = '300px';
myLayer.style.height = '300px';
myLayer.style.padding = '10px';
myLayer.style.background = '#00ff00';
myLayer.innerHTML = 'This is the layer created by the JavaScript.';
document.body.appendChild(myLayer);
The reason it was not working is that you used x and y css properties (which don't exist) instead of left and top. Also, for left, top, width, height you had to specify a unit (e.g. px for pixels).
Try these,
Set the position using top and left rather than x and y.
An absolute positioned element needs to be contained inside something that also has a position style. The usual trick is to create a container with position: relative.
You should be setting styles such as width, height, top, left etc with + 'px'.
You don't need to set display: block for the div as it is already a block element.
I want to set the width and height of the container <div> of <img> after the image is downloaded, how to do it?
function fn (div, url_path) {
var img = new Image();
img.onload = function () {
div.style.width = img.width;
div.style.height = img.height;
};
img.src = "url_path";
}
fn(document.getElementsByTagName('div')[0], 'http://some-url-to-image.com/1.jpg');
Put it on the page hidden, then measure its width. See here for a good explanation of how to measure the width of a hidden object (just calling width() returns 0).
It is best to wait for the image to be loaded unless you want false results.
jQuery('#image').load(function() {
var jThis = jQuery(this);
var width = jThis.width();
var height = jThis.height();
yourFunction(width, height); //whatever you want to do with these values
jThis.unbind('load'); //might be necessary if you only want this to happen once. Remove this if #image is a container for multiple uses.
})
EDIT 1
Instead of yourFunction(), you could use this since it fits your description better:
jThis.parents('#container').css({
width: width,
height: height
});