I'm a jQuery novice, so the answer to this may be quite simple:
I have an image, and I would like to do several things with it.
When a user clicks on a 'Zoom' icon, I'm running the 'imagetool' plugin (http://code.google.com/p/jquery-imagetool/) to load a larger version of the image. The plugin creates a new div around the image and allows the user to pan around.
When a user clicks on an alternative image, I'm removing the old one and loading in the new one.
The problem comes when a user clicks an alternative image, and then clicks on the zoom button - the imagetool plugin creates the new div, but the image appears after it...
The code is as follows:
// Product Zoom (jQuery)
$(document).ready(function(){
$("#productZoom").click(function() {
// Set new image src
var imageSrc = $("#productZoom").attr("href");
$("#productImage").attr('src', imageSrc);
// Run the imagetool plugin on the image
$(function() {
$("#productImage").imagetool({
viewportWidth: 300,
viewportHeight: 300,
topX: 150,
topY: 150,
bottomX: 450,
bottomY: 450
});
});
return false;
});
});
// Alternative product photos (jQuery)
$(document).ready(function(){
$(".altPhoto").click(function() {
$('#productImageDiv div.viewport').remove();
$('#productImage').remove();
// Set new image src
var altImageSrc = $(this).attr("href");
$("#productZoom").attr('href', altImageSrc);
var img = new Image();
$(img).load(function () {
$(this).hide();
$('#productImageDiv').append(this);
$(this).fadeIn();
}).error(function () {
// notify the user that the image could not be loaded
}).attr({
src: altImageSrc,
id: "productImage"
});
return false;
});
});
It seems to me, that the imagetool plugin can no longer see the #productImage image once it has been replaced with a new image... So I think this has something to do with binding? As in because the new image is added to the dom after the page has loaded, the iamgetool plugin can no longer use it correctly... is this right?
If so, any ideas how to deal with it?
Wehey! I've sorted it out myself...
Turns out if I remove the containing div completely, and then rewrite it with .html, the imagetool plugin recognises it again.
Amended code for anyone who's interested:
$(document).ready(function(){
// Product Zoom (jQuery)
$("#productZoom").click(function() {
$('#productImage').remove();
$('#productImageDiv').html('<img src="" id="productImage">');
// Set new image src
var imageSrc = $("#productZoom").attr("href");
$("#productImage").attr('src', imageSrc);
// Run the imagetool plugin on the image
$(function() {
$("#productImage").imagetool({
viewportWidth: 300,
viewportHeight: 300,
topX: 150,
topY: 150,
bottomX: 450,
bottomY: 450
});
});
return false;
});
// Alternative product photos (jQuery)
$(".altPhoto").click(function() {
$('#productImageDiv div.viewport').remove();
$('#productImage').remove();
// Set new image src
var altImageSrc = $(this).attr("href");
// Set new image Zoom link (from the ID... is that messy?)
var altZoomLink = $(this).attr("id");
$("#productZoom").attr('href', altZoomLink);
var img = new Image();
$(img).load(function () {
$(this).hide();
$('#productImageDiv').append(this);
$(this).fadeIn();
}).error(function () {
// notify the user that the image could not be loaded
}).attr({
src: altImageSrc,
id: "productImage"
});
return false;
});
});
You could try abstracting the productZoom.click() function to a named function, and then re-binding it after changing to an alternate image. Something like:
// Product Zoom (jQuery)
$(document).ready(function(){
$("#productZoom").click(bindZoom);
// Alternative product photos (jQuery)
$(".altPhoto").click(function() {
$('#productImageDiv div.viewport').remove();
$('#productImage').remove();
// Set new image src
var altImageSrc = $(this).attr("href");
$("#productZoom").attr('href', altImageSrc);
var img = new Image();
$(img).load(function () {
$(this).hide();
$('#productImageDiv').append(this);
$(this).fadeIn();
}).error(function () {
// notify the user that the image could not be loaded
}).attr({
src: altImageSrc,
id: "productImage"
});
$("#productZoom").click(bindZoom);
return false;
});
});
function bindZoom() {
// Set new image src
var imageSrc = $("#productZoom").attr("href");
$("#productImage").attr('src', imageSrc);
// Run the imagetool plugin on the image
$(function() {
$("#productImage").imagetool({
viewportWidth: 300,
viewportHeight: 300,
topX: 150,
topY: 150,
bottomX: 450,
bottomY: 450
});
});
return false;
}
Also, rolled both your ready() blocks into the same block.
First, i have one question, are the .altPhoto links or images? Cause if its images then this line is wrong
var altImageSrc = $(this).attr("href");
it should be
var altImageSrc = $(this).attr("src");
its the only thing i could find in a glance
Related
This code works, but is it an efficient way to go about displaying an image once it has been loaded?
LightBoxNamespace.SetupLightBox = function(path, lightBox) {
// Create a new image.
var image = new Image();
// The onload function must come before we set the image's src, see link for explanation.
// http://www.thefutureoftheweb.com/blog/image-onload-isnt-being-called.
// Anonymous function set to onload event, to make sure we only proceed if the image has been loaded.
image.onload = function () {
if ($('#image').length) {
$('#image').attr('src', path); // If the element already exists, change the src to our loaded image.
}
else {
$('<img id="image" alt="">').attr('src', path).insertAfter('#close'); // If the element does not exist, insert the full image html into the lightbox.
}
LightBoxNamespace.CentreBoxInViewport(lightBox);
LightBoxNamespace.ShowOverlay(lightBox);
};
// Set the src, and show the image.
image.src = path;
};
var img = $('<img>');
img.load(function(){alert("image loaded!")});
img.attr('src', "url");
if (!! img) img.appendTo('#close');
http://jsfiddle.net/W57QR/4/
"The jQuery way":
var $img = $('<img/>').prop({ src: path });
$img.load(function() {
console.log('image loaded correctly');
$(this).insertAfter('#close');
}).error(function() {
console.log('error loading image');
});
i have downloaded the https://github.com/edspencer/Ext.ux.Printer and
import the Printer.js and Base.js
in Base.Js i added the image rendder code:
Ext.ux.Printer.imageRenderer = Ext.extend(Ext.ux.Printer.BaseRenderer, {
generateBody: function(image) {
return String.format("<div class='image-print'>{0}</div>", image.body.dom.innerHTML);
}
});
Ext.ux.Printer.registerRenderer('image', Ext.ux.Printer.imageRenderer);
this is the place display the image with id displayimage
items: [Printtoolbar,{
xtype : 'image',
id : 'displayimage',
style: {
'display': 'block',
'margin': 'auto'
},
width: 320,
height: 240,
}]
When Pressed Print Button Print The Image
var PrintImgBtn = Ext.getCmp('btnPrint');
PrintImgBtn.on('click', function(){
printImg = Ext.getCmp('displayimage');
Ext.ux.Printer.print(printImg);
Unfortunately when i pressed the print button,nothing happen.
You can just open a window and print it. In your button handler:
...
handler: function() {
var img = Ext.getCmp('displayimage');
if(img) {
var html = img.container.dom.innerHTML;
var win = window.open();
win.document.write(html);
win.print();
win.close();
}
}
...
Example with print: http://jsfiddle.net/wXfFN/3/
if your are using Iframe 'Ext.ux.iFrame', then you can use something like this
var iframe = this.down('iframe');
iframe.getFrame().contentWindow.print();
if you want to add some additional content along with iframe content
var iframe = this.down('iframe');
var contentWindow = iframe.getFrame().contentWindow;
var iFrameNewContent = "<div>This will be helpfull</div>" + contentWindow.document.body.innerHTML;
// set iFrameNewContent to content window
contentWindow.document.body.innerHTML = iFrameNewContent;
contentWindow.print();
Advantage is that all the styles applied to iframe content, you can see in print document
Also check this link whether it comes usefull
https://druckit.wordpress.com/2014/02/15/ext-js-4-printing-the-contents-of-an-ext-panel/
I've got this calling function
$(document).ready(function(){
$('#change-background').click(function(){
layers['map'] = new Kinetic.Layer();
buildMap(layers['map'],'img/test.png');
stage.add(layers['map']);
});
});
And, I've got this function to display the image
function buildMap(layer, img_src){
var img = new Image();
img.src = img_src;
img.onload = function(e) {
var map = new Kinetic.Image({
id: 'map_img',
x: 0,
y: 0,
image: img,
draggable: true,
dragBoundFunc: function(pos) {
// THIS SHOULD EXECUTE
console.log('hahaha');
return { x:0, y:0 };
}
});
layer.add(map);
layer.draw();
};
}
I have a similar code on a separate project of mine, and it works like a charm.. But its quite awkward that it does not work well here. The image showed up in the canvas, and its draggable, which in this case it should not be because I explicitly returned { x:0, y:0 }(the return values is for my testing only). I also looked at the console logs the 'hahaha' text never appears.. It did not call the function when the image has been dragged. Both of these are inside a <script> tags and in one html document.
Fixed this: http://jsfiddle.net/xpLPT/2/
try :
dragBoundFunc: function(pos) {
console.log('hahaha'); //check the jsfiddle, this does work.
return {
x: this.getAbsolutePosition().x, //constrain vertically
y: this.getAbsolutePosition().y //constrain horizontally
}
}
also change your click function by adding stage.draw();:
$(document).ready(function(){
$('#change-background').click(function(){
//if(layers['map'])
// layers['map'].remove(); // this is optional, but recommended, as it removes the current map layer before adding a new one
layers['map'] = new Kinetic.Layer();
buildMap(layers['map'],'img/test.png');
stage.add(layers['map']);
stage.draw();
});
});
try using a newer version of kinetics:
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.3.0.min.js"></script>
i am trying to make a gallery viewer on which the webpage shows thumbs of the real images and then when the image is clicked, the original image(with original size) is displayed, the div which holds the html "img" element is changed to visible(else by default it is set to hidden) and meanwhile am trying to get the dimensions of the image so that i can center the images of different dimensions properly acc. to their width and the problem am having is that whenever i click any thumb for the first time after the page is loaded, the statement which gets the width of the image sends 0, and after that when clicking any other image without reloading the page (including the previous one) it shows the previous image's dimension and sometimes it works and sometimes not(mostly doesn't), please help me out. The javascript code is below.
// JavaScript Document
$(document).ready(function() {
$.post(
"loadup.php",
{
refer:"yes"
},function(response){
$("#gallery_view_tab").html(response);
initAll();
});
});
function initAll(){
$("<div id='imgViewer'></div>").appendTo("body"); //set up image viewer
$("#imgViewer").insertBefore("#monster_wrap"); //set before monster_wrap
var thumbimgs = $(".thumbimg");
for(i=0; i<thumbimgs.length; i++){
var thumbimg = thumbimgs[i].id;
var thumbid = '#'+thumbimg;
$(thumbid).click(loadImgviewer);
}
}
function loadImgviewer(){
var imgLink = this.getAttribute("data-link");
$("<img id='closeImgviewer' src='images/close.png' /><img src='' id='imgview' />").appendTo("#imgViewer");
$("#imgview").attr('src', imgLink);
$("#imgViewer").css('visibility', 'visible');
imgwidth = $("#imgview").width();
screenwidth = $(window).width();
var pos = (screenwidth - imgwidth)/2;
$("#log").html(pos);
$("#imgview").css('margin-left', pos);
$("#closeImgviewer").click(unloadImgviewer); //set click event handler on image view closer
}
function unloadImgviewer(){
$("#imgViewer").css('visibility', 'hidden');
$("#imgview").attr('src', '');
$("#imgViewer").empty();
}
I just rewrote your code a little.
$(document).ready(function() {
$.post(
"loadup.php",
{
refer:"yes"
},
function(response){
$("#gallery_view_tab").html(response);
initAll();
}
);
});
function initAll(){
$("<div id='imgViewer'></div>").appendTo("body"); //set up image viewer
$("#imgViewer").insertBefore("#monster_wrap"); //set before monster_wrap
$(".thumbimg").on('click', loadImgviewer);
}
function loadImgviewer(){
var imgwidth, pos,
screenwidth = $(window).width();
var imgLink = this.getAttribute("data-link");
$("<img id='closeImgviewer' src='images/close.png' /><img src='' id='imgview' />").appendTo("#imgViewer");
$("#imgview").attr('src', imgLink).on('load',function(evt){
imgwidth = $(this).width();
pos = (screenwidth - imgwidth) / 2;
$("#log").html(pos);
$("#imgview").css('margin-left', pos);
$("#imgViewer").css('visibility', 'visible');
};
$("#closeImgviewer").click(unloadImgviewer); //set click event handler on image view closer
}
function unloadImgviewer(){
$("#imgViewer").css('visibility', 'hidden');
$("#imgview").attr('src', '');
$("#imgViewer").empty();
}
Please try it our. Didn't try it but I think it should work.
I've some images on a page which are loaded randomly and they are over 100kbs, is it possible to have it fully loaded then fade it in rather than progressively loading it?
My JS looks like this...
(function($){
$.randomImage = {
defaults: {
//you can change these defaults to your own preferences.
path: '_images/', //change this to the path of your images
myImages: ['hero_eagle.jpg', 'hero_giraffe.jpg', 'hero_owl.jpg', 'hero_rabbit.jpg']
}
}
$.fn.extend({
randomImage:function(config) {
var config = $.extend({}, $.randomImage.defaults, config);
return this.each(function() {
var imageNames = config.myImages;
//get size of array, randomize a number from this
// use this number as the array index
var imageNamesSize = imageNames.length;
var lotteryNumber = Math.floor(Math.random()*imageNamesSize);
var winnerImage = imageNames[lotteryNumber];
var fullPath = config.path + winnerImage;
//put this image into DOM at class of randomImage
// alt tag will be image filename.
$(this).attr( { src: fullPath });
});
}
});
})(jQuery);
Should be able to, just set the image to display:none in your stylesheet and modify the bit of the script that sets the src to this:
$(this).attr( { src: fullPath }).load(function() {
$(this).fadeIn()
});
Start with the images hidden using CSS. Then use:
$(document).ready(function() {
// Code goes here.
});
and have the fade-in execute there.
There's another SO question that discusses preloading images using jQuery right here: Preloading images with jQuery
Quoting from the top answer:
function preload(arrayOfImages) {
$(arrayOfImages).each(function(){
$('<img/>')[0].src = this;
// Alternatively you could use:
// (new Image()).src = this;
});
}
// Usage:
preload([
'img/imageName.jpg',
'img/anotherOne.jpg',
'img/blahblahblah.jpg'
]);
if you want all images to preload before fading in, and display a loading message to the user, you can use something like this:
var gotime = imgArray.length;
$(".maxCount").text(gotime);
var imgCounter = 0;
$.each(imgArray, function(){
$(new Image()).load(function(){
imgCounter++;
$(".presentCount").text(imgCounter);
if (--gotime < 1) {
$("#content").fadeIn();
}
}).attr('src', this);
});