Applying Jquery to dynamically created images - javascript

I'm new to Javascript/Jquery and PHP and I'm experimenting with it. Basically, I've created a simple image gallery in which each picture is at an opacity of .4 until you mouse over it and it becomes 100% opacity. Now I've gone a step further and used PHP to scan a directory of images and add them to the list of pictures in the gallery. The current code looks like this:
$(document).ready(function(){
var i = 0;
var names;
function returndata(files){
names = files;
for(i=0; i < names.length ; i++){
$('<li id="img_' + i + '"><img src="../Gallery_pictures/' + names[i] + '"/></li>').appendTo('#thumbnails ul');
}
}
$.post('../php/read_directory.php',function(data){
var files = $.parseJSON(data);
returndata(files);
});
});
The code works and adds the images to the list on the webpage, but how would I go about adding the Jquery fade to the newly created images? I've searched all over the place for an answer to this but maybe I'm just missing the answers. This and the image fade are in separate external Javascript files. Thanks in advance.
*EDIT:*Okay so I got it to work using your suggestions, but the problem now is that the script doesn't start until an image is initially moused over. All the pictures start full opacity until moused over then they all become .4 opacity. Any way to fix this? I'm also going to try if I can easily do this in css.
*DOUBLE EDIT:*So I can easily do this with css and it works like I want it to. Thanks for the replies everyone.

Use on to set events on dynamically added content
$(document).on("mouseover", "#thumbnails img", function() {
$(this).css("opacity", 1);
});
$(document).on("mouseout", "#thumbnails img", function() {
$(this).css("opacity", 0.4);
});
If you're using jQuery pre 1.7, then you can use delegate. Note that delegate takes the selector first, then the event name.
$(document).delegate("#thumbnails img", "mouseover", function() {
$(this).css("opacity", 1);
});
$(document).delegate("#thumbnails img", "mouseout", function() {
$(this).css("opacity", 0.4);
});
Avoid using live since it's deprecated.

Use .live() or .on() to bind event to dynamically added elements.
.live() is deprecated in jQuery 1.7

Try to add class="hoverImg" to your img and then do the following:
$('.hoverImg').on('hover',function(){
// here goes your hover code
});
So every image has the class .hoverImg also the new ones. And you bind the event hover on every single image that has the class .hoverImg. And why do you have to use .on() simply because this makes sure that the code is also executed if img's are added to your dom after it has been fully loaded.

Related

Can't listen to hover (etc) events after creating divs using innerHTML

So I generate some divs using this
document.getElementById('container').innerHTML += '<div class="colorBox" id="box'+i+'"></div>';
The problem I'm running into is that catching a hover event
$(".colorBox").hover(function(){
alert("!");
});
Won't work after doing that. Any thoughts?
EDIT:
To be more clear, check this out: http://graysonearle.com/test/16_t.html
I need to be able to have hover events happen after changing innerHTML that happen dynamically and many times. So like after changing the number of columns, the hover effect needs to work.
THANKS TO CHOSEN ANSWER:
For those in the future that might want to do something similar, my code looks like this now:
$(document).ready(function(){
document.body.onmousedown = function() {
++mouseDown;
}
document.body.onmouseup = function() {
--mouseDown;
}
$(document).on("mouseenter",".colorBox",function(){
if(mouseDown){
var clicked = $(this).attr("id");
var clicked = clicked.substring('box'.length);
next_color(clicked);
}
$(this).css("border-color","#ff0");
}).on("mouseleave", ".colorBox", function() {
$(this).css("border-color","#aaa");
});
$(document).on("click",".colorBox",function(){
var clicked = $(this).attr("id");
var clicked = clicked.substring('box'.length);
next_color(clicked);
});
});
whenever we update DOM from server side code or client side code.
For EX. DIV we are updating then it will not work with events we loaded before if we load that partial data.
so for this in document ready
code like this.
if you are using jquery 1.7+
then code like
$(document).on("hover",".colorBox",function(){
alert("Hi it will load after partial div update as well");
});
$(document).delegate(".colorBox","hover",function(){
alert("Hi it will load after partial div update as well");
});
and if you are using jquery 1.6 or less then that.
then use
$(".colorBox").live("hover",function(){
alert("Hi it will load after partial div update as well");
});
http://oscarotero.com/jquery/
If this helped you please mark as answer.
First, as you're using jQuery your first code could be simplified using the below function.
$('#container').append('<div class="colorBox" id="box'+i+'"></div>');
Second I think this is because you haven't declared the hover-off function.
$(".colorBox").hover(
function(){
alert("On");
}
);
Working Fiddle
You have to call your hover code AFTER injecting your divs. Jquery doesn't automatically listen to dom changes, so if you hook all your colorBoxes in $(document).ready(){...} and then insert a new div, nothing will ever happen.
So this works fine:
$(document).ready(function(){
for(i=0; i<5; i++) {
document.getElementById('container').innerHTML += '<div class="colorBox" id="box'+i+'"></div>';
}
$(".colorBox").hover(function(){
alert("!");
});
}

Jquery appending in front of div

So I'm using Jquery Drag/Drop to drag and drop something onto a dashboard. I want to now drag anything that I have dropped onto the dashboard out of the dashboard in order to destroy it/remove it from the dashboard.
I've tried adding a class to the thing that is dropped onto the dashboard and then tried adding a draggable to that, but the drag is not working, I think because when I append the element to the dashboard it appears behind the dashboard(the colours are a little faded).
Here is my code-
$(".draggable").draggable({helper:'clone'});
$("#favouritesDashboard").droppable({
accept:".draggable",
drop: function(event,ui) {
var toDrop = $(ui.draggable).clone();
//create smaller version
$(toDrop).addClass("inDashBoard");
$(this).append(toDrop);
}
});
$(".inDashBoard").click(function(){
console.log("clicking elem in dashboard");
});
I've replaced the second draggable with a click, the console.log never prints, suggesting that what I think is going on is actually going on.
Use on for late binding http://api.jquery.com/on/ .
$(document).on('click', '.inDashBoard', function(){
console.log("clicking elem in dashboard");
});
This is due to the nature of event binding / listeners in jQuery.
The elements you want to trigger a click event on do not exist when the page is loaded, they are added dynamically. So to ensure that your method is attached to new elements that match the selector you should use "on" or "live"
$(".inDashBoard").on( "click", function(){
console.log("clicking elem in dashboard");
});
this should work:
$(".inDashBoard").live('click', function(){
console.log("clicking elem in dashboard");
});

CSS Change in multiple locations on hover (jquery solution needed)

I'm working in wordpress, trying to figure out how to change the css color of a side nav element when a remote image is hovered.
I would have done this easily with CSS and just assign the CSS hover class for each item, but since this is a CMS, the navigation and the image gallery will change dynamically.
So, I'm looking for a JQuery of how to accomplish this. Any suggestions?
Here's an example of the html:
<div class="imgGallery">
<img class="page-item-54" src="/image1.jpg">
<img class="page-item-66" src="/image2.jpg">
<div>
When someone hovers over the specific image above, it changes the css of the image below:
<ul class="pageNav">
<li class="page-item-54">Sub Gallery 1</li>
<li class="page-item-66">Sub Gallery 2</li>
</ul>
Thanks!
Troy
You can use the jQuery hover function to hook up handlers for the mouseenter and mouseleave events of the images (which jQuery will happily simulate on browsers that don't support them):
$(".imgGallery img").hover(
function() {
// Code for when the hover starts, the (raw) hovered `img`
// element is `this`, from which we can get the class name
// to feed into a selector for finding the relevant `li`
$(".pageNav ." + this.className).css(/* your change here */);
},
function() {
// Code for when the hover ends, the (raw) unhovered `img`
// element is `this`
$(".pageNav ." + this.className).css(/* your change here */);
}
);
Here's a live example with just one pageNav, and a revision with multiple pageNavs just to show that it is updating multiple locations simultaneously.
mouseenter and mouseleave (IE innovations that still aren't supported natively by many browsers, but which jQuery provides if missing) are a lot less difficult to work with for this sort of thing than mouseover and mouseout, since mouseover and mouseout bubble. (In your case, it may not matter much, as you're using imgs; if you were using elements that could have child elements, though, it would make a big difference.)
Here is a possible solution.
You may want to look at changing <ul class="pageNav"> to <ul id="pageNav"> (unless you know for sure you will never duplicate this class).
Edit: updated to allow for multiple classes in the img tag.
$(function() {
var $pageNav = $('.pageNav');
// hook up hover function to all images under the imgGallery class
$('.imgGallery').find('img').hover(function() {
// find "page-item-" class
var pageItemClassName = this.className.replace(/.*(page-item-\d+).*/, "$1");
// toggle hovered class on matching item under unordered list
$pageNav.find('.' + pageItemClassName).toggleClass('hovered');
});
});​
You can then make a hovered css class which will apply when hovered. For example:
.pageNav .hovered {
background-color: #009900;
}
You can FAKE a CSS HOVER with the code bellow
$(document).ready(function() {
var images = $(".imgGallery img");
$.each(images, function(i, item) {
$(item).mouseover(function() {
$(this).css({
"background-image": "url('alternate_image.png')",
"background-repeat": "no-repeat"
});
}).mouseout(function() {
$(this).css({
"background-image": "url('original_image.png')"
});
});
});
});
In this jQuery script, I add and remove a second class class "over" that you can style accordingly.
$(function () {
$('div.imgGallery img').hover(
function () {
$('ul.pageNav li[class=' + $(this).attr('class') + ']').addClass('over');
},
function () {
$('ul.pageNav li[class=' + $(this).attr('class') + ' over]').removeClass('over');
});
});

JQuery click event, not working

I have the following scenario.
I have a index.php page with the following JQuery code included
jQuery(document).ready(function(){
jQuery('#sIMG img').click(function() {
var currentSRC = jQuery(this).attr('src');
var altSRC = jQuery(this).attr('title');
var imgID = jQuery(this).attr('id');
var cat = jQuery(this).attr('name');
/*Fade, Callback, swap the alt and src, fade in */
jQuery('#main').fadeOut('fast',function() {
jQuery('#main').load("detail.php?id="+imgID+"&category="+cat);
jQuery('#main').fadeIn('fast');
});
});
});
Now I have two div tags called #main and #right in the index.php page. When I click on a menu item right changes to a bunch of images, if I click on one of those images the above code should take effect and load into the main div, but it's just not working. the images are located within a div called sIMG. Any help will be appreciated
Try using live
jQuery('#sIMG img').live("click",function(){
});
As of jQuery 1.7, the .live() method is deprecated. Use .on() to attach event handlers.
jQuery('#sIMG img').on("click",function(){
});
I think what you're doing is setting "click" on the array that is return there. Try this:
jQuery('#sIMG img').each(function() {
jQuery(this).click(function() {
});
});
One of the reasons that the jquery click don't work is that you have dupplicates id's in the form.

Jquery Rollovers, issue with click state

Excuse my noobiness when it comes to Jquery, but I have some jquery code that does rollovers for me:
$("img.rollover").hover(function () {
this.src = this.src.replace("_off","_on");
},
function () {
this.src = this.src.replace("_on","_off");
});
Essentially just switching the images from image_on.jpg to image_off.jpg on hover on a bunch of images, now on click i would like to set the state of "image_on" permanently but the hover state seems to overwrite it and it doesn't stay "_on", i'm guessing it something to do with binding of events? I also don't seem to be able to do it so if a user clicks on one image it sets it to on, but if they click another image to return the previous image to the "_off" state and set the current one to the "_on" state.
Any help appreciated, ta.
i would add a "selected" class to the link when it is actually active and filter against that.
$("img.rollover").bind('click',function(){
$('img.rollover').removeClass('selected');
$(this).addClass('selected');
}).hover(function () {
this.src = this.src.replace("_off","_on");
},
function () {
if(!$(this).hasClass('selected')){
this.src = this.src.replace("_on","_off");
}
});
Of course, you would style your .selected images using the _on image.
sidenote:
Note that the recommended way of implementing rollover images is the css sprite technique: you use an image that contains all the states, use that image as a background image, and adjust the background-position according to :hover, :active states. It's a pure CSS solution that works in all recent browsers.
your hover code seems to run two functions one after the other which will effectively undo each others changes. so _off is turned to _on then back again.
so for hover to toggle it "on" you would just want
$("img.rollover").hover(function () {
this.src = this.src.replace("_off","_on");
});
if you just do this 1 function each time you can then control other states as you'd like e.g.
$("img.rollover").mouseout(function () {
this.src = this.src.replace("_on","_off");
});
You could unbind the hover event $(this).unbind('mouseenter mouseleave') when a click occurs, and rebind if necessary later.

Categories