About the lightboxes. The box adjusts its dimension to match the picture. Question is how do the box find out the size of the picture?
To answer the comment about detecting when its done loading, i believe you can use the onLoad event. in jquery this would look somthing like:
$('img').attr('src', 'uri/for/image').load(callbackFunction);
or manually:
var tmp = new Image();
tmp.onload = callbackFunction;
tmp.src = 'uri/for/image';
your callbackFunction could then use $(this).height() and $(this).height() safely. so your callbackFunction is where you would have the actual logic to trigger the rest of your implementation.
in alot of cases if seen this callback (or its equiv. implementation) simply set a global variable and then somewhere else in the code youll see polling of this variable every N ms. and when its set it will trigger the rest of the script.
I assume something akin to:
imgWidth = $(img).width();
imgHeight = $(img).height();
It would load the image in a hidden element (or positioned off screen), get the dimensions, animate the container to fit, then expose the image (usually via some sort of transition/animation).
Related
I have two images with same dimensions and same positions, but placed in divs with dynamic width depending on user interaction using the jquery beforeAfter plugin.
I would like to enable scroll zooming on these images using wheelzoom, such that zooming on one of these images will zoom the same amount in the same position as the other.
What I am unable to do is this linking of (I suppose) the event handlers along the lines of this:
function onwheel(e){
//adjust image to fit zoom level ...
other_img.onwheel(e);
}
If this is not possible, is it possible to copy the event and change the target image?
I am looking for a solution using either jquery or native Javascript.
Code here (ignore the handle).
EDIT: Any top-level pointers to what should work would also be appreciated
I made a worked example: http://plnkr.co/edit/kH0ec8TVMXUIYlMoBaMq?p=preview
here is the core code:
document.getElementsByClassName("before")[0].addEventListener("wheel", function(event){
if(flag){
flag= false;
return;
};
flag=true;
var newEvent = new WheelEvent("wheel",event);
var elementToTrigger = document.getElementsByClassName("after")[0];
elementToTrigger.dispatchEvent(newEvent);
});
I do something simple, when an event happening("wheel") a trigger the same event to another element and pass as argument the data from the first event to the new event. I use flag variable to deter the custom event trigger again the other event and start an eternal loop.
This is a solution without to edit the source code of plugin. You can do more good solutions if you change the code of wheelzoom.js.
Make the zooming a function that takes enough parameters to handle zooming, and get the values you need from the event handler.
function handleZoom(domNode, zoomDirection, zoomAmount) {
// Do stuff to change the size of `domNode`
}
var img1, img2;
img1 = /* select image node */;
img2 = /* select image node */;
function handleScroll(scrollEvent) {
var direction, amount;
// Use `scrollEvent` to figure out which direction and how far to zoom
handleZoom(img1, direction, amount);
handleZoom(img2, direction, amount);
}
img1.onscroll = handleScroll;
img2.onscroll = handleScroll;
I need to hide a div and, with this code it works fine:
var idObj = $(this).attr('key');
var valH = $(this).attr('hideval');
var valS = $(this).attr('showval');
if ($('div[name='+idObj+']').attr('isdisplay') == 'no') {
$('div[name='+idObj+']').children().show("slow");
$('div[name='+idObj+']').attr('isdisplay','yes');
var divTitle = $('div[name='+idObj+']').children().first();
var divArrow = $(this).children().first();
//.attr('src',prefixImg+valH);
//divTitle.show();
//divArrow.show();
$(this).children().first().attr('src',prefixImg+valH);
} else {
var divTitle = $('div[name='+idObj+']').children().first();
var divArrow = $('div[name='+idObj+']').children().last();
//.attr('src',prefixImg+valS);
$('div[name='+idObj+']').children().hide();
$('div[name='+idObj+']').attr('isdisplay','no');
divTitle.show();
divArrow.show();
$(this).children().first().attr('src',prefixImg+valS);
}
My div is hidden and the Title and arrows to reopen the div are shown. But if I try to use hide("slow") the divTitle and divArrow don't appear when my div is closed. Same problem using hide(1000).
Is there a difference between hide with and without "slow" parameter?
thanks,
Andrea
From the official site
The matched elements will be hidden immediately, with no animation. This is roughly equivalent to calling .css('display', 'none'), except that the value of the display property is saved in jQuery's data cache so that display can later be restored to its initial value. If an element has a display value of inline, then is hidden and shown, it will once again be displayed inline.
When a duration is provided, .hide() becomes an animation method. The .hide() method animates the width, height, and opacity of the matched elements simultaneously. When these properties reach 0, the display style property is set to none to ensure that the element no longer affects the layout of the page.
So, if hide is used without delay, it hides immediately without animating - eg, poof.
If it's used with time, it becomes animated, so it disapears over time.
For your problems, it is difficult to judge without the corresponding html code.
$(element).hide() hides an element instantly, where $(element).hide('slow') will animate its disappearance (slowly).
It looks like (though I'm not sure) you want to do stuff after the animation is finished. In that case, do something like this:
var that = this; // here to preserve scope for the block below
$('div[name='+idObj+']').children().hide('slow', function() {
// This stuff happens after the hide animation is done.
$('div[name='+idObj+']').attr('isdisplay','no');
divTitle.show();
divArrow.show();
$(that).children().first().attr('src',prefixImg+valS); // <= note "that" instead of "this"
});
According to the jQuery documentation
The strings 'fast' and 'slow' can be supplied to indicate durations of
200 and 600 milliseconds, respectively.
Also duration in milliseconds can be supplied to it..
I want to load only certain images from HTML DOM, based on image width and height.
I dont know how to access the width and height properties of a image using JavaScript.
This must run under any browser.
My app is a bookmarklet, so all the images will be loaded by the time a user will start the bookmarklet. So, i will only scan the DOM, get all the img srv values, and use them. The trick is that i dont want all the images, just the ones that match my wanted sizes.
I have this code so far, and it gets all the images from DOM :
var imgObj = document.getElementsByTagName('img');
for(var i=0;i<imgObj.length;i++)
{
imgsList[i] = imgObj[i].getAttribute('src');
if(consoleLog)console.log(imgsList[i]);
}
return images = imgObj.length;
my problem has been solved here: How to get image size (height & width) using JavaScript?
But i dont know how to adapt my code to img.clientWidth
Is it imgsList[i].clientWidth ?
imgObj[i].clientWidth, imgList contains a list of just the src attributes.
Be careful when using any widths and heights of images as they load asynchronously into the browser. This means that when the DOM loads the width and height will be 0. Only after the images themselves finish loading will the element have a width and height appropriately set.
To get around this you can have load handlers whose callback will be executed once the image finishes loading.
Again though a slightly odd behaviour is that a browser that caches the image will not call this load function again (at least not ones in jQuery) and so you need to make sure for cached versions you do any width checks in a DOM load callback.
You can do this in standard javascript however as an example and since I have a jQuery example in front of me which I was working on earlier I will show you how it can be done in jQuery.
Suppose the image has an id=imageid
function checkWidths() {
//do anything you want here
//jQuery uses the .width and .height functions to get the appropriate attributes of an element, these return a value without the px % etc. To get the actual css use .css('width') instead.
}
$(document).ready(function() {
if($('#imageid').width() > 0)
checkWidths();
});
$('#imageid').load(function() {
checkWidths();
}
To know the dimensions of an image, you need either :
to have the image loaded (then clientWidth is OK if your script is executed in an onload callback)
to have them specified as attributes (<img src=... width=33>). In this case use imgObj[i].getAttribute('width');
Note that if you want to reload an image and avoid all cache problems, the simplest is to change its URL, for example like this :
var srcbase = imgObj.getAttribute('src').split('?')[0];
imgObj.src = srcbase + '?time='+(new Date()).getTime();
(this supposes the image is defined by the path until the '?')
This is it guys, and it works perfect.
populateImgsList : function()
{
var imgObj = document.getElementsByTagName('img');
var j = 0;
for(var i=0;i<imgObj.length;i++)
{
if(consoleLog)console.log('w '+imgObj[i].clientWidth+' h: '+imgObj[i].clientHeight);
if( (imgObj[i].clientWidth>100) && (imgObj[i].clientHeight>100) )
{
imgsList[j] = imgObj[i].getAttribute('src');
if(consoleLog)console.log(imgsList[j]);
j++;
}
}
return images = imgList;
},
For starters... I have no sinister intention of subjecting users to popups or anything like that. I simply want to prevent a user from resizing the browser window of a webpage to which they've already navigated (meaning I don't have access to / don't want to use window.open();). I've been researching this for quite a while and can't seem to find a straightforward answer.
I felt like I was on track with something along the lines of:
$(window).resize(function() {
var wWidth = window.width,
wHeight = window.height;
window.resizeBy(wWidth, wHeight);
});
...to no avail. I have to imagine this is possible. Is it? If so, I would definitely appreciate the help.
Thanks
You can first determine a definite size.
var size = [window.width,window.height]; //public variable
Then do this:
$(window).resize(function(){
window.resizeTo(size[0],size[1]);
});
Demo: http://jsfiddle.net/DerekL/xeway917/
Q: Won't this cause an infinite loop of resizing? - user1147171
Nice question. This will not cause an infinite loop of resizing. The W3C specification states that resize event must be dispatched only when a document view has been resized. When the resizeTo function try to execute the second time, the window will have the exact same dimension as it just set, and thus the browser will not fire the resize event because the dimensions have not been changed.
I needed to do this today (for a panel opened by a chrome extension) but I needed to allow the user to change the window height, but prevent them changing the window width
#Derek's solution got me almost there but I had to tweak it to allow height changes and because of that, an endless resizing loop was possible so I needed to prevent that as well. This is my version of Dereck's answer that is working quite well for me:
var couponWindow = {
width: $(window).width(),
height: $(window).height(),
resizing: false
};
var $w=$(window);
$w.resize(function() {
if ($w.width() != couponWindow.width && !couponWindow.resizing) {
couponWindow.resizing = true;
window.resizeTo(couponWindow.width, $w.height());
}
couponWindow.resizing = false;
});
If need some particular element to handle resize in some particular mode, and prevent whole window from resizing use preventDefault
document.getElementById("my_element").addEventListener("wheel", (event) =>
{
if (event.ctrlKey)
event.preventDefault();
});
I'm currently working on a web application which has a page which displays a single chart (a .png image). On another part of this page there are a set of links which, when clicked, the entire page reloads and looks exactly the same as before except for the chart in the middle of the page.
What I want to do is when a link is clicked on a page just the chart on the page is changed. This will speed things up tremendously as the page is roughly 100kb large, and don't really want to reload the entire page just to display this.
I've been doing this via JavaScript, which works so far, using the following code
document.getElementById('chart').src = '/charts/10.png';
The problem is that when the user clicks on the link, it may take a couple of seconds before the chart changes. This makes the user think that their click hasn't done anything, or that the system is slow to respond.
What I want to happen is display a spinner / throbber / status indicator, in place of where the image is while it is loading, so when the user clicks the link they know at least the system has taken their input and is doing something about it.
I've tried a few suggestions, even using a psudo time out to show a spinner, and then flick back to the image.
A good suggestion I've had is to use the following
<img src="/charts/10.png" lowsrc="/spinner.gif"/>
Which would be ideal, except the spinner is significantly smaller than the chart which is being displayed.
Any other ideas?
I've used something like this to preload an image and then automatically call back to my javascript when the image is finished loading. You want to check complete before you setup the callback because the image may already be cached and it may not call your callback.
function PreloadImage(imgSrc, callback){
var objImagePreloader = new Image();
objImagePreloader.src = imgSrc;
if(objImagePreloader.complete){
callback();
objImagePreloader.onload=function(){};
}
else{
objImagePreloader.onload = function() {
callback();
// clear onLoad, IE behaves irratically with animated gifs otherwise
objImagePreloader.onload=function(){};
}
}
}
You could show a static image that gives the optical illusion of a spinny-wheel, like these.
Using the load() method of jQuery, it is easily possible to do something as soon as an image is loaded:
$('img.example').load(function() {
$('#spinner').fadeOut();
});
See: http://api.jquery.com/load-event/
Use the power of the setTimeout() function (More info) - this allows you set a timer to trigger a function call in the future, and calling it won't block execution of the current / other functions (async.).
Position a div containing the spinner above the chart image, with it's css display attribute set to none:
<div> <img src="spinner.gif" id="spinnerImg" style="display: none;" /></div>
The nbsp stop the div collapsing when the spinner is hidden. Without it, when you toggle display of the spinner, your layout will "twitch"
function chartOnClick() {
//How long to show the spinner for in ms (eg 3 seconds)
var spinnerShowTime = 3000
//Show the spinner
document.getElementById('spinnerImg').style.display = "";
//Change the chart src
document.getElementById('chart').src = '/charts/10.png';
//Set the timeout on the spinner
setTimeout("hideSpinner()", spinnerShowTime);
}
function hideSpinner() {
document.getElementById('spinnerImg').style.display = "none";
}
Use CSS to set the loading animation as a centered background-image for the image's container.
Then when loading the new large image, first set the src to a preloaded transparent 1 pixel gif.
e.g.
document.getElementById('mainimg').src = '/images/1pix.gif';
document.getElementById('mainimg').src = '/images/large_image.jpg';
While the large_image.jpg is loading, the background will show through the 1pix transparent gif.
Building on Ed's answer, I would prefer to see something like:
function PreLoadImage( srcURL, callback, errorCallback ) {
var thePic = new Image();
thePic.onload = function() {
callback();
thePic.onload = function(){};
}
thePic.onerror = function() {
errorCallback();
}
thePic.src = srcURL;
}
Your callback can display the image in its proper place and dispose/hide of a spinner, and the errorCallback prevents your page from "beachballing". All event driven, no timers or polling, plus you don't have to add the additional if statements to check if the image completed loading while you where setting up your events - since they're set up beforehand they'll trigger regardless of how quickly the images loads.
Some time ago I have written a jQuery plugin which handles displaying a spinner automatically http://denysonique.github.com/imgPreload/
Looking in to its source code should help you with detecting when to display the spinner and with displaying it in the centre of the loaded image.
I like #duddle's jquery method but find that load() isn't always called (such as when the image is retrieved from cache in IE). I use this version instead:
$('img.example').one('load', function() {
$('#spinner').remove();
}).each(function() {
if(this.complete) {
$(this).trigger('load');
}
});
This calls load at most one time and immediately if it's already completed loading.
put the spinner in a div the same size as the chart, you know the height and width so you can use relative positioning to center it correctly.
Aside from the lowsrc option, I've also used a background-image on the img's container.
Be aware that the callback function is also called if the image src doesn't exist (http 404 error). To avoid this you can check the width of the image, like:
if(this.width == 0) return false;
#iAn's solution looks good to me. The only thing I'd change is instead of using setTimeout, I'd try and hook into the images 'Load' event. This way, if the image takes longer than 3 seconds to download, you'll still get the spinner.
On the other hand, if it takes less time to download, you'll get the spinner for less than 3 seconds.
I would add some random digits to avoid the browser cache.