How to get a class name based on div hover in jquery - javascript

I'm looking for a way to fetch the class name based on hovering on a div. Both div has same id but slightly different class name. take a look at the below example:
<div id="1-someid" class="1-example-class border cz">
...more element goes here....
</div>
and
<div id="2-someid" class="2-example-class border cz">
...more element goes here....
</div>
Update: I've made the id name unique based on expert's opinion posted below. :) Thanks for all the helps.
Now what I want is, when user hover on the div with 1-example-class it will return me the class name 1-example-class. and when people will hover on the div with 2-example-class it will return me 2-example-class name.
So that I can use parseInt() on that name to fetch the number, 1, 2, 3 and so on.
Also please note that writing a static script for just 1-example-class or 2-example-class will not help as there are many more divs like this with 3, 4, 5 and so on attached to it.
Can anyone help? I have tried the following but it didn't helped.
$('#someid').hover(function() {
var class_names = $(this).attr('class');
var class_name = class_names.split( ' ' );
var c = parseInt( class_name[0] );
console.log( c );
});
If anyone can help it will be really helpful.

Attribute selector and Regex is the way to go:
$("[class*=example-class]").hover(function() {
var c = this.className.match(/(\d+)-example-class/)[1];
console.log(c);
});
$("[class*=example-class]") matches all elements that their class
attribute includes 'example-class' string.
this.className.match(/(\d+)-example-class/)[1] gives the related
number.

Here is a way to do it based on your current configuration:
$('div').hover(function() {
// grab class attribute, split on space character (like you're doing already)
var class_names = $(this).attr('class').split( ' ' );
// loop through each class
$.each( class_names, function( k,v ){
// see if this 1 class matches your example
if ( v.indexOf("example-class") > 0 ){
// if it does, remove text part of class name
var this_num = v.replace( '-example-class', '' );
// output numeric value only to console
console.log( parseInt( this_num ) );
}
});
});
This method does not expect the same class configuration (meaning the classes in your class attribute can be in any order, so long as it does contain the example string). In your question, the code expects first class listed to be the example string class.
See this example: https://jsfiddle.net/31505tw1/
In the example, I have replaced your duplicate IDs into classes. As others have pointed out, HTML spec requires each ID to be unique.

There are several ways to do this- but other users are correct that your issue is in using the same ID multiple times, that's the only reason the code you already have doesn't work. If you use one of the other shared classes as your selector your original script will work:
$('.border').hover(function() {
var class_names = $(this).attr('class');
var class_name = class_names.split( ' ' );
var c = parseInt( class_name[0] );
console.log( c );
});

Firstly, you should use unique ID's on your div's: https://stackoverflow.com/a/9454716/984323
Not only for the HTML to be valid, but your jQuery script wouldn't be able to differentiate between the two. Then you can target each div and the rest of your code seems to work.
<div id="someid" class="1-example-class border cz">
...more element goes here....
</div>
<div id="someid2" class="2-example-class border cz">
...more element goes here....
</div>
https://jsfiddle.net/05r8f013/1

ID's must be unique all over html. Since you are using classname to get the data, you can add name field to the div:
<div name="someid" class="1-example-class border cz">
...more element goes here....
</div>
<div name="someid" class="2-example-class border cz">
...more element goes here....
</div>
$('[name="someid"]').hover(function() {
var class_names = $(this).attr('class');
var class_name = class_names.split( ' ' );
var c = parseInt( class_name[0] );
console.log( c );
});

Maybe you could for example:
$('div').hover(function(){
if ( $(this).attr('class') == 'some class' ) {
//Do something
} else {
//Do something else...
}

You could do a Regex on the hovered items that match on the pattern of the class name:
<div name="someid" class="1-example-class border cz">
...more element goes here....
</div>
<script>
$('#someid').hover(function() {
var className = this.className.match(/(\d)-example-class/);
if(className){
console.log(className[0]) // 1-example-classname
console.log(className[1]) // 1
}
});

Related

Change location.href with jQuery

I need to change the location.href of some URLs on my site. These are product cards and they do not contain "a" (which would make this a lot easier).
Here is the HTML:
<div class="product-card " onclick="location.href='https://www.google.com'">
I mean it is pretty simple, but I just cannot get it to work. Did not find any results from Google without this type of results, all of which contain the "a":
$("a[href='http://www.google.com/']").attr('href', 'http://www.live.com/')
Any ideas on how to get this to work with jQuery (or simple JS)?
I cannot change the code itself unfortunaltely, I can just manipulate it with jQuery and JS.
To change the onClick for all the class='product-card', you can do something like this:
// All the links
const links = document.getElementsByClassName('product-card');
// Loop over them
Array.prototype.forEach.call(links, function(el) {
// Set new onClick
el.setAttribute("onClick", "location.href = 'http://www.live.com/'" );
});
<div class="product-card " onclick="location.href='https://www.google.com'">Test</div>
Will produce the following DOM:
<div class="product-card " onclick="location.href = 'http://www.live.com/'">Test</div>
Another option, is to loop over each <div> and check if something like google.com is present in the onClick, if so, we can safely change it without altering any other divs with the same class like so:
// All the divs (or any other element)
const allDivs = document.getElementsByTagName('div');
// For each
Array.from(allDivs).forEach(function(div) {
// If the 'onClick' contains 'google.com', lets change
const oc = div.getAttributeNode('onclick');
if (oc && oc.nodeValue.includes('google.com')) {
// Change onClick
div.setAttribute("onClick", "location.href = 'http://www.live.com/'" );
}
});
<div class="product-card" onclick="location.href='https://www.google.com'">Change me</div>
<div class="product-card">Don't touch me!</div>

Select the elements with at least one value in their data attribute, which is included in a certain array

I am writing a filtering function, in which I need to select the elements that have a certain value in their data attribute, and those values are included in an array, allow me to explain it in an example:
For example, I have three elements and a button as follows:
<div data-foo="aa,cc,ff" ></div>
<div data-foo="bb,cc,ff" ></div>
<div data-foo="bb,dd,ee" ></div>
<div class="button" data-boo="aa,ff" ></div>
The data-foo in each element contains comma-separated values. When I click on the button, I create an array (myArray in the code below) from its data attribute, then I need to select those elements that at least one of the values in that myArray is in their data-foo, for a clear explanation please see the code below:
$( ".button" ).click(function() {
// First I make an array from the button's data attribute
var myArray = $(this).data('boo').split(',');
// Select should be elements that their da-foo has at least one
// — of values in the array above
var Select = "?"
});
How the Select variable can target the first two elements, since the first one has both "aa" and "ff", and the second element has "ff".
I really tried to put it the way that makes sense, if it is not clear enough, please let me know and I will be happy to explain more, thank you.
You can use Attribute Contains Selector:
$( ".button" ).click(function() {
// First I make an array from the button's data attribute
var myArray = $(this).data('boo').split(',');
// produces array of strings like '[data-foo*="aa"]'
var selectors = myArray.map(function(value) {
return '[data-foo*="' + value + '"]';
});
// searches by selectors joined by comma, returns all elements
// that satisfy at least one selector
var selectedElements = $(selectors.join(','));
});
Lets use Array.prototype.some for this:
$(".button").click(function() {
// First I make an array from the button's data attribute
var myArray = $(this).data('boo').split(',');
// Select should be elements that their da-foo has at least one
// — of values in the array above
var Select = $("div[data-foo]"); //select all elements with data-foo
Select.each(function(index, element) {
var isInMyArray = $(element).data("foo").split(",").some(function(element) {
if ( myArray.indexOf(element) != -1)
{return true;}//if true then element is in myArray
}); //using some here - if one value is found in array return true.
console.log(isInMyArray);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div data-foo="aa,cc,ff"></div>
<div data-foo="bb,cc,ff"></div>
<div data-foo="bb,dd,ee"></div>
<div class="button" data-boo="aa,ff">test</div>

jQuery, selecting just number from id like "article-23"

All right, I have a div tag which got a class="blog-post" and id like id="article-23" (where "23" could be any number, as it is id of blog post in a database). I need to somehow get just a number from that id and than apply some rules to that div tag. So say:
if number from id % 2 == 0 {
set text colour black to associated div tag with class of blog-post
} else {
set text colour white to associated div tag with class of blog-post
}
Thats just a "pseudo" code to show logic that I wan't to apply dependent if number from id is even or odd, but the question remains same, how do I just get number from id like "article-23" ?
As simple as
var number = "article-23".match(/\d+/)[0];
But you have to be sure that any digit exists in the string, otherwise you'd get a error.
You can actually apply rules via function, which makes this the cleanest solution (in my opinion):
$(".blog-post").css('color', function () {
return +this.id.replace('article-', '') % 2 ? 'blue' : 'red';
});
http://jsfiddle.net/ExplosionPIlls/Jrc5u/
Try this:
$('.blog-post[id^="article-"]').each(function () {
if (parseInt(this.id.replace('article-', '')) % 2 === 0) {
$('#' + this.id).css('color', 'black');
} else {
$('#' + this.id).css('color', 'white');
}
});
jsFiddle Demo
As an alternative, HTML5 supports these things called "data attributes", which are specifically meant for attaching data to your DOM without abusing things like the "class" or "id" attributes. jQuery provides a handy .data method for reading these attributes in a more obvious way.
You can add your own numeric ID attribute using something like "data-id":
<div class="blog-post" data-id="23" />
$("#blog-post").each(function () {
console.log($(this).data("id")); // Look up the data-id attribute
});
If I'm understanding correctly, you want the number after the hyphen of the id tag of your .blog-post class.
var article = $(".blog-post").attr('id'); //get the id
var article = article.split("-"); // split it on hyphens
return article = article[article.length-1]; // return the last element

Run each for a class but once for group

I have a lot of elements with the same class. These elements are divided into groups by means of attribute "data-xxx"
<div class="myclass" data-n="group1"></div>
<div class="myclass" data-n="group1"></div>
<div class="myclass" data-n="group1"></div>
....
<div class="myclass" data-n="group2"></div>
<div class="myclass" data-n="group2"></div>
...
<div class="myclass" data-n="group3"></div>
...
...
How to perform a function on each item, but only once in each group using something like this?
$('.myclass').each(function(){
/// My function
});
Working example: http://jsfiddle.net/5sKqU/1/
$(document).ready(function() {
var group = {}; //an object that we're going to use as a hash
$('.myclass').each(function(){
if (group[$(this).attr('data-n')] != true) {
group[$(this).attr('data-n')] = true;
//do something here once per each group
alert('Group: '+ $(this).attr('data-n'));
}
});
});
I'm assuming that you only need this to run once on page load. If you could share more about your requirements, I can show you what changes you'll need to make.
Something like this maybe :
var groups = {};
$('.myclass').each(function(i, el) {
var n = $(el).data('n');
if(!groups[n]) {
groups[n] = $();
}
groups[n] = groups[n].add(el);
});
//At this point the object `groups` has one property per group,
//each value being a jquery collection comprising members of the group.
//Now the world's your oyster. You can loop through the groups
//with full access to each group's members if necessary.
$.each(groups, function(groupName, jq) {
//my function
});
You can set a certain HTML attribute on all group elements after processing the first one. After that, you can check the value of that attribute:
$('.myclass').each(function(){
if($(this).attr("processed")!="true") {
// process...
$("[data-n=" + $(this).attr("data-n")).attr("processed", "true");
} else {
// skip, or do something else with the element
}
});
You can select out each group with the jQuery attribute selector, like this:
$( '.myclass[data-n="groupX"]' );
I'm not sure if you meant that you only wanted to apply your function to one element in each group, but if so this will give you only the first in each:
$( '.myclass[data-n="groupX"]' ).first();
Given that you label your groups 1 through N you can just check if there is anything in the resulting set to determine when you have looped through every group.

JQuery - work with divs

I want to set another class for the clicked menu-part. Clicking generates url with #NAME. Here is my menu:
<div id="head_menu">
<div name="order" id="menu_part">make order</div>
<div id="menu_part">portfolio</div>
<div id="menu_part">contacts</div>
<div id="menu_part">vacancies</div>
<div id="menu_part">about company</div>
</div>
I need to add class: 'menu_choosed' for clicked part. Here is my jquery-code:
$(document).ready(
function()
{
currentPage = window.location.hash;
$('#head_menu>div').each(
function()
{
if( currentPage == $(this).hash )
{
$(this).addClass("menu_choosed");
}
}
)
}
)
I really don't know, how to filter values :( Help, please.
The easy way:
$(document).ready(
function()
{
currentPage = window.location.hash;
$('#head_menu a[href=' + currentPage + '] div').addClass('menu_choosed');
}
);
There are a few problems with your HTML I would like to mention:
Nowadays, most people use lists (<ul>, mostly) for navigation.
Having a <div> inside an <a> is invalid if the <div> has display: block (default) and the <a> has display: inline (default).
One document may only have one element per ID. You currently have several elements with the menu_part id.
Using name for anchor points is not recommended. Prefer using ID's.
All IDs must be unique. You're currently repeating menu_part. I'd suggest removing the duplicate IDs. Give the nav links a class of "nav_link" and then use jquery to reference that class with an onclick event that changes the class to "menu_choosed".
Try this:
$(document).ready(
function()
{
var currentPage = window.location.hash;
$('#head_menu a div').each(
function()
{
if( currentPage == $(this).parent().attr("href") )
{
$(this).addClass("menu_choosed");
}
}
)
}
)
it should be $('#head_menu>a>div') I believe.
also, ids are supposed to be unique, so it could cause problems that you have multiple divs with the same id. you may want to change menu_part to a class.
You can use:
$("#head_menu").find("a[href=" + window.location.hash + "]").addClass('highlight')

Categories

Resources