jQuery rollovers using multiple ids and classes - javascript

I'm building a photo gallery and what I would like to do is make it so that as the user rolls over an image (let's say for the purposes of this question it's a picture of an apple), all the other images of apples on the page also show their "over" state.
Any and all help would be greatly appreciated, and thank you for your time in advance!

You could add the 'type' of the image as a class. For example an apple will be:
<img src='' class='apple fruit red' />
You can have as many space separated classes as you want.
Then add the following handler:
$(".apple").mouseover(function() {
$(".apple").addClass("overState");
});
You need to define in your CSS the overState. On mouseout you must remove the class.

So each image has a number of tags (eg: "apple", "red", "big"), and when you mouse over the big red apple, you want all other apples, big things and red things to light up?
As kgiannakakis suggested, I'd put that data into the class attribute of the image - the only difference is that I'd prefix each class with something so you don't clash with other classes on your page.
<img src="the-big-red-apple.jpg" class="tagged tag-big tag-red tag-apple" />
I've also added an extra class there called "tagged" so you can tell your tagged photos from navigational images or whatever.
$('img.tagged')
.each(function() {
var thisClasses = this.className.split(/s+/); // array of classes.
var search = [];
for (var i = 0; i < thisClasses.length; ++i) {
if (thisClasses[i].substr(0, 4) == "tag-") {
search.push("." + thisClasses[i]);
}
}
$(this).data("tags", search.join(",")); // ".tag-big,.tag-red,.tag-apple"
})
.hover(function() {
$('img.tagged')
.filter(this.data('tags'))
.addClass("highlight")
;
}, function() {
$('img.tagged')
.filter(this.data('tags'))
.removeClass("highlight")
;
})
;
What this does is initially loop through all your tagged images and work out what the tags are on each of them, storing that into that element's data(). This means we only need to do that once, and not each time.
Then it adds a hover event to each tagged image to find anything which matches any of this image's tags and add the "highlight" class. Similarly it removes the class when you mouseout.

If these are links (anchor tag) you don't need jQuery to do this. You can use :hover in CSS.
a.apple:hover img {
/* whatever you want to change here */
}
EDIT: Ignore me. This won't change all apple elements on the page at the same time. That's what I get for perusing SO late at night when I'm sleepy.

Change the image source
This method would actually change the image sources in a uniform way, rather than just applying a class to them.
function swapImageGroup(imgSelector,suffix){
if (suffix == null) {suffix = "-hover";}
//imgSelector is the jQuery selector to use
//both imgSelector and suffix must be strings
$(selector).hover(
function() {
$(selector).each(function(){
//store ".jpg" or ".png" or whatever as fileExtension
var fileExtension = $(this).attr("src").substr($(this).attr("src").lastIndexOf("."));
//replace something like ".jpg" with something like "-hover.jpg",
//assuming suffix == "-hover"
$(this).attr("src", $(this).attr("src").replace(fileExtension, suffix + fileExtension));
});
},
function() {
$(selector).each(function(){
//chop off the end of the filename, starting at "-hover" (or whatever)
//and put the original extension back on
$(this).attr("src", $(this).attr("src").split(suffix + ".").join("."));
});
}
);
}
So you'd use the function like this:
swapImageGroup("img.apple");
or
swapImageGroup("img.foo","-active");

Related

How to toggle color of random sentences in a text in Meteor

I have a text and several tags on my website and I want to highlight a random sentence every time I click a tag (at the same time, the tag become "active"). Here's my code:
'click #mytag .selectize-control.multi .selectize-input [data-value]': function(){
if($(event.target).attr('class') == "item"){
$(event.target).removeClass().addClass('item active');
var dataval = $(event.target).attr('data-value');
//to "deactivate" other active tags
$('.selectize-control.multi .selectize-input [data-value]').each(function(){
if($(this).attr('class') == "item active" && $(this).attr('data-value') != dataval){
$(this).removeClass().addClass('item');
}
});
//generate a random random index and find the corresponding sentence to change the color
Meteor.call("generateSentence",asin, function(error, result){
Session.set("colorSentence", result);
});
var sid = Session.get("colorSentence");
var id = 'span#sentence'+sid.toString();
$(id).css("background","yellow");
}
}
I can get a random sentence highlighted with a background color yellow every time i click on one tag. However, I want to toggle the color off next time i click another tag so that there's only one line with background color each time. Can anyone suggest how to do it?
Also, in order to only keep one tag "active" each time, I loop through all tags to check its status and turn other active ones off. It's pretty brute but at least works as my tags are too many. But as there're much more sentences here, I don't want to do the same thing here. I also appreciate any ideas about a cleverer way to deactivate other tags each time. Thanks
First of all, add a class="sentence" to all your sentence spans.
Now, to deactivate your backgrounds, do
$('span.sentence').attr( style, '' );
Secondly, the way you are using Session variables to handle the result of the Meteor call is a bad pattern. It uses an unnecessary reactive observer and is harder to follow than doing the work in the callback. So in total, your code becomes:
Meteor.call( "generateSentence", asin, function(error, result){
$( 'span.sentence' ).attr( style, '' );
$( 'span#sentence' + result ).css( "background", "yellow" );
});
Replace your explicit loop to deactivate your tags with jQuerys build in handling of multiple element selections, the same way as you clear the sentence styles.

Parsing horribly deprecated HTML with jQuery

I'm having some trouble understanding how to use nested selectors in jQuery. I'm parsing a list of classes from my university and I want it to let me know if a class I want is open. However, the website doesn't use css AT ALL, so the only way of identifying the class I want is open is to read the color attribute of the font tag.
Here's the block of HTML I'm trying to read
<TD><FONT FACE='Arial' SIZE='-1' COLOR='Black'>nameOfClass</TD>
Here's how am I'm trying to read it, and display an alert if the font tag attribute color of nameOfClass is "Black", which means its open. It's nasty but its the only way I can tell if the class is available or not.
function main() {
$(document).ready(function(){
if $("td").text()=="nameOfClass"
if $(this "font").attr("COLOR")=="Black" {
alert("It actually works!");
}
});
I never get an alert when I run this though. I'm pretty sure its my syntax, it's been a long while since I did any sort of coding so I might be making some stupid mistake.
You can use .children. But in order for your code to work, you have to iterate over all td elements, not just compare the text value of the first one:
$("td").each(function() {
if($(this).text() === 'nameOfClass' &&
$(this).children('font').attr('color') === 'Black') {
alert("It actually works!");
}
});
Otherwise, $("td").text()=="nameOfClass" only tests whether the text of the first td element in the page is "nameOfClass", which is certainly not what you want. You want to find all td element which contain that string.
You could do it much simpler if you'd directly select all font elements whose color attribute has the value "Black", with the attribute selector. Then you filter out the ones that don't contain the class name and count how many elements are left over. If none, then the class is not open.
var classIsOpen = $('font[color="Black"]').filter(function() {
return $(this).text() === 'nameOfClass';
}).length > 0;
You only need to do an exact comparison of the class name if it could occur as part of an other name, e.g. "Web" and "Advanced Web". If that's not the case, you can make the code even shorter, with the :contains selector:
var classIsOpen = $('font[color="Black"]:contains("nameOfClass")').length > 0;

SImple image replace using Javascript/html

Couldn't find a punctual answer for this simple task and your help is highly appreciated
We have an image we want to switch based on user's color selection.
Tried several methods, none worked.
This is the idea:
$('#YourButton').click(function() {
var oldSrc = 'images/Image1.png';
var newSrc = 'images/Image2.png';
$('img[src="' + oldSrc + '"]').attr('src', newSrc);
});
Just change the image source with javascript by clicking your button with another color
Note: it´s jquery so you have to include the js file..
Just bind a click listener to your button and change the src attribute of your image.
$('#colorButton').click( function() { //choose a new color
$('#imageIcon').attr('src', 'path/to/new/image.png'); //change the img's source
});
EDIT (response to questions):
If you want this code to apply to all of your buttons, give each of your buttons a similar class instead of an ID:
<div class="colorButton"></div>
Then you can use the following selector to apply the above click listener to all of these divs:
$('.colorButton')
Naturally, you want to change your image as simply as possible. You could map all of your colors to their corresponding image file, but as far as design goes this might get messy and unwieldy. I would create a directory that stores all of your image files (for example, /your/color/swatches) and give each of them a name consistent with their color, like 'ff0000.png' for red, '0000ff.png' for blue, etc.
Why would we do this? So that we can switch your image based on the background-color attribute of your buttons. Let's say that you have the following buttons:
<div class="colorButton" style="background-color: '#ff0000'"></div>
<div class="colorButton" style="background-color: '#0000ff'"></div>
You can use the same click listener, but it will have to be modified a bit since we are mapping the background color to an image:
$('.colorButton').click( function() {
var color = $(this).css('backgroundColor');
//(You'll need to modify your color string here)
$('#imageIcon').attr('src', 'your/color/swatches/' + color + '.png');
});
BUT this won't work yet. Since most browsers return "rgb(xx, yy, zz)" from .css('backgroundColor'), you need to convert that string into hex. This post on SO gives a more or less effective way to do so, but you'll need to modify it to fit your model where I have indicated.

How to make those dynamic anchor links with jQuery?

I've recently discovered a website which does something really cool! Example:
There are two links "Cat" and "Dog".
There are two DIV containers, id="catImage" and id="dogImage"
The initial URL looks like http://mysite.com/#cat
Initially, the cat image is visible
Clicking on the Dog link will fade out the catImage div and fade in the dogImage div
Additionally, it will change the anchor in the browser URL to: http://mysite.com/#dog
Opening the website with httü://mysite.com/#dog will show the dog image initially
Is this possible using jQuery? How would I scan for that anchor, and how would I call a function when the link is clicked without causing the link to follow some URL? I'm an objective-c dude and don't know anything about JS... hope my question isn't too dumb for you.
with this markup:
<div id="images">
<div id="catImage">some cat image here</div>
<div id="dogImage" style="display:none;">some dog image here</div>
</div>
<div id="anchors">
catImage anchor
dogImage anchor
</div>
and with this js (assuming jquery 1.4.x)
$(function () {
$("#anchors a").click(function () {
// send the index of the anchor to the function
fadeImage($(this).index());
});
var hash = window.location.hash;
if (hash) {
var elementId = "#" + hash.substring(1) + 'Image';
var $div = $(elementId);
// check if this element exists, and if so, send that index to the function
if ($div.length) {
fadeImage($div.index());
}
}
});
function fadeImage(index) {
$("#images div:eq(" + index + ")").fadeIn().siblings().fadeOut();
}
And to explain what's going on here:
I'm using the jquery index() function to get the index of the element relative to its siblings. I then pass that index to the fadeImage function, which finds the same index div and fades it in. By using chaining, I then look to the siblings of that div to fade them out. This is useful if you have more than 2 divs to fade out here.
For the anchor/hash usage, I just find the div with the matching id and get its index, and pass it to the same function.
jQuery docs can explain the various methods much better than I can.
Using location.href you can get the full URL in javascript.
you can substring or string replace your domain name and rest will be your parameter dog or cat.
When you have the parameter .
jquery functions like show(); hide (); to show cat and hide dog.
By adding or removing style also you can change images
.add() is there
addClass removeClass is there
http://mattwhite.me/11tmr.nsf/D6Plinks/MWHE-695L9Z
http://rockmanx.wordpress.com/2008/10/03/get-url-parameters-using-javascript/
http://api.jquery.com/show/
http://api.jquery.com/addClass/
Update: Oh I forgot, obviously you should read a tutorial about jQuery if you want to use it.
You can get and set the hash of the URL via window.location.hash, e.g.
alert(window.location.hash);
//and
window.location.hash = 'test'
You should read about events in order to fully understand how it works. The event object provides a preventDefault() method, which is exactly doing what it says (preventing the default behavior).
E.g. with jQuery:
$('a').click(function(e) {
//Do something..
// prevent to follow the link
e.preventDefault();
});

How can I apply a function to several images in jQuery?

I need a little help with (probably) something really simple.
I want to use a script which converts images from color to grayscale.
I got it working partially — the first image turns gray, but the second won’t.
I know this is because an id cannot be used multiple times:
var imgObj = document.getElementById('grayimage');
I tried this:
var imgObj = $(’.grayimage’)[0];
But it didn’t work. Changing it to getElementByClass also does not work. (Before people ask, I did change the id to class in the <img> tag.)
I really could use some help here. Thanks in advance!
$('.grayimage').each(function(idx,imgObj){
<do your code here>
});
$('.grayimage') gives you a list of all elements with grayimage as a class. If you add '[0]' you're accessing the first element, so any changes you make will apply to only the first image that it finds with this class.
You should loop through all elements:
var images = $('.grayimage');
for(i = 0; i < images.length; i++) {
var image = images[i];
// Do stuff
}

Categories