jQuery: Show/hide items using URL hash / fragment identifier - javascript

I have a basic jQuery click function to shows/hides items based on their data-filter attribute—not using a plugin like Isotope, just a simple show/hide function— and I'd also like to apply the filter using the URL hash, when present, and append an 'active' class to the corresponding filter button.
In the markup, there is a grid of divs with the 'item' class, each of which contain anchor elements with the relevant data-filter, like so:
<div class="item">
Item
</div>
In my approach below, I'm trying to get the URL hash, hide all elements whose anchors do not match the hash string, and append the active class to the matching .filter-button element:
$(window).load(function () {
var hash = window.location.hash.substring(1);
if (hash) {
$('.item').each(function() {
$(this).children('.item-anchor').data('filter') !== hash;
}).hide();
$('a.filter-button[href="hash"]').addClass('active');
}
});
I got some assistance from this thread, but my case is a bit different. Interestingly, the code above is causing all the .item divs to hide and the .active class is not being appended as desired, so I'm not sure where I'm going wrong here. Any assistance is greatly appreciated, and please let me know if any further clarification is needed.

You should be invoking the filter function, instead of the each function. Additionally, you need to return the Boolean that we should filter based on. I'm not too sure what your link .active does, but I'm pretty sure you want to filter it by hash.
$(window).load(function () {
var hash = window.location.hash.substring(1);
if (hash) {
$('.item').filter(function() {
return $(this).children('.item-anchor').data('filter') !== hash;
}).hide();
$('a.filter-button[href="#'+hash+'"]').addClass('active');
}
});

Related

jQuery Drag and Drop using class selectors

This must be a simple one for expert. I am new to JS/jQuery. I have got a script to drag and copy and I modified it according to my requirements. It is implemented with "id" selectors. I want to implement the same using "class" selectors.
Here is the fiddle demo
$(document).ready(function(){
$('#arsenal').on("dragstart", ( function (e) {
e.originalEvent.dataTransfer.setData("Text", e.target.id);
}));
$('#leftbox').on("dragenter", ( function (e) {
e.preventDefault();
}));
$('#leftbox').on("dragover", ( function (e) {
e.preventDefault();
}));
$('#leftbox').on("drop", ( function (e) {
e.preventDefault();
$(this).empty();
var data=e.originalEvent.dataTransfer.getData("Text");
var nodeCopy = document.getElementById(data).cloneNode(true);
nodeCopy.id = "newId";
e.target.appendChild(nodeCopy);
}));
});
Explanation:
I have a requirement where I need to implement this for a set of images which are dynamically added(with JS). So I cannot use Id of the target images. I need to use class. I tried but couldn't get it working.
Can anyone help me with this?
Thanks in advance,
Here's a basic JSFiddle of what you're doing using classes.
It's pretty much a matter of changing your selctor:
$('.draggableImg').on("dragstart", ( function (e) {
...
});
There's also a minor problem -- if you have dragged an image to the leftbox, and then drag the image in leftbox to leftbox... you'll get an error. (You might just need to removeClass after copying the image to leftbox).
Alterantively, if you're saying that your elements won't have ID's... then you'll need to pass around the actual source of the image, rather than the element ID. Here's an updated fiddle which does that.
And here's one where you always append to the box, rather than to the target (which may be the img which has just been cleared)!
Use something like '.js-drag-item' and '.js-drop-target' to replace your div id's. I like to add 'js-' so I remember it is a class name that has Javascript associated with it rather than CSS.
e.g.
JS
$('.js-drag-item').on("dragstart", ( function (e) {
e.originalEvent.dataTransfer.setData("Text", e.target.id);
}));
HTML
<section class="js-drag-item">
....
</section>
<section class="js-drag-item">
....
</section>
etc
You can have as many drag items or drop items as you want and the JS will be applied to all of them
Class selector (".class") selects all elements with the given class. An element can have multiple classes; only one of them must match.
So simply replace ids with clas selectors, like this:
$('.class').on("dragstart", ( function (e) {
e.originalEvent.dataTransfer.setData("Text", e.target.id);
}));

Getting ALL First links in a specific class

So I know that using "a:first" will get the first link of a page. Lets assume we have the following:
<div class="masterclass">
Link 1
Link 2
</div>
<div class="masterclass">
Link 1
Link 2
</div>
Naturally I can use the following code to get the first "a" of the class "masterclass"
$('.masterclass a:first').click(function() {
alert('yayfirstlink');
});
However I do not understand how to get the first link of every "masterclass"
You need to use find() here because your selector will find all the anchor elements with in .masterclass then filter only the very first one. But when you use .find(), it will find all the .masterclass elements first then will find the first anchor element in each of them.
$('.masterclass').find('a:first').click(function() {
alert('yayfirstlink');
});
or if you are sure that the target element will be the first child of its parent then you can use :first-child
$('.masterclass a:first-child').click(function() {
alert('yayfirstlink');
});
Try this,
var oFirstAnchor = $(".masterclass a:first-child");
$(".masterclass a:first-child") is what you are looking for.
so:
$('.masterclass a:first-child').click(function() {
alert('yayfirstlink');
});
This is how u loop through each of the masterclass and get the first link of it.
i don't know what you want to do with it though so i can only provide this
$(document).ready(function(){
var fields = $('.masterclass a:first-child');
$.each(fields, function(index, val){
alert(index);
});
});
this alerts the current links array index
http://jsfiddle.net/kBd82/6/
I would recommend using the first of type selector for this.
$('.masterclass a:first-of-type')
This way it will always select the first anchor tag in each masterclass div even if you put other things in the div later.
http://api.jquery.com/first-of-type-selector/

Add active class to menu "parent" item if URL has a a /directory/ listing

trying to add a CSS class to a a parent item when the URL contains a directory path.
For instance if my url is
example.com/directory/about.html
I want to add a CSS class an item in my top navigation if it contains /directory/ in it.
so in this case, example.com/directory/overview.html would get a CSS class "active-parent"
which would be .main-nav li a.active-parent
(mind you I am already using jquery to check for teh URL and make that page active, but its when its a sub page of a section, the parent is not highlighted)
I thought I could usde the :contains() Selector but I dont know how to apply it to a URL
jQuery selectors can't be used on an url. You must parse the url and check the content be yourself.
if (window.location.href.indexOf('/directory/') != -1) {
// Add a css class to a html element
}
You may want to do a more generic way be using the split function :
window.location.pathname.split('/').forEach(function(directory) {
if (directory == 'directory') {
// Add a css class to a html element
}
});
Based on limited information, I'd suggest:
$('a').filter(
function(){
return this.href.match(/(\/\w+\/)/);
}).parent().addClass('parent');
This assumes the class is added if the href contains any directory, not simply a specific directory named 'directory'.
References:
match().
Regular expressions in JavaScript.
I f I understand you correctly, you want to filter through a group of urls and then, based on text within the href, you want to manipulate data. In that case, use the .filter() function like so:
$("a").filter(function(i) { return $(this).attr("href").indexOf("document") > -1; })
This Grabs ALL A tag elements, filters them using the function inside to determine if the href has "document" in it or not. Then simply use the .each() function to do whatever, like so:
$("a")
.filter(function(i) { return this.href.indexOf("document") > -1; })
.each(function(i) {
$(this).parent().addClass("some-class-name");
});
See jsFiddle Example
If you need more understanding, just comment.

Hide div based on value of attribute?

I'm looking to change the class (hide) of certain div's dependent on their attribute values.Here's my code, it might make a bit more sense once you've seen this:
jQuery('#menu1').click(function() {
jQuery([.attr('imageref')]!=[.attr('menuref')]).removeClass('pics').addClass('.pics-hidden').removeClass('pics').fadeOut(200);
jQuery('#projectimages').masonry('reload');
});
So what I'm after is that if you click on #menu1 it will remove .pics with the same imageref attribute as the #menu1 atrribute menuref.
So clicking on #menu1 which has menuref equal to 1, will hide the relevant .pics with an imageref also equal to 1.Hopefully that makes sense, any help would be greatly appreciated!
You can use the css selectors to make this.
ie:
jQuery('#menu1').click(function()
{
jQuery('[imgeref="menuref"]').removeClass('pics').addClass('pics-hidden');
});
edit:
this will search all the elements wich his atribute 'imageref' is set to 'menuref' and then remove the class pics and add the class pics-hidden.
if it's only necesary to img tags. then you could change:
jQuery('[imgeref="menuref"]')
to
jQuery('img[imgeref="menuref"]')
You might use the jQuery filter function.
http://api.jquery.com/filter/
Description: Reduce the set of matched elements to those that match the selector or pass the function's test.
var menuref = ("#menu1").attr('menuref')
// Get all pics with an imageref attribute
jQuery(".pics[imageref]")
// Filter them
.filter(function(){
return $(this).attr('imageref') != menuref;
})
// Do what ever you want e.g. remove the pics class
.removeClass('pics')
You use the attribute-equals selector, and concatenate into the selector the value of the menuref attribute.
jQuery('#menu1').click(function() {
var menu = $(this).attr('menuref');
jQuery(".pics[imageref='" + menu + "']").toggleClass('pics pics-hidden')
.fadeOut(200);
jQuery('#projectimages').masonry('reload');
});

Can I use a multiple selector expression on the jQuery filter method?

I have a bunch of anchor tags that I want to select. But if the href attribute of those links equals "#" or "" (an empty string) then I want to exclude them from the selection.
Currently I have the following which filters out the selection if the href doesn't equal "#":
Demo here: http://jsfiddle.net/dzrRS/2/
jQuery("a[href]").filter("[href!='#']").each(function() {
jQuery(this).addClass("selected");
});
I have then tried altering this to the following in order to also filter out the selection if the href also doesn't equal "". However this doesn't work.
jQuery("a[href]").filter("[href!='#'], [href!='']").each(function() {
jQuery(this).addClass("selected");
});
In order to achieve my selection I have had to use the filter method twice. e.g.:
jQuery("a[href]").filter("[href!='#']").filter("[href!='']").each(function() {
jQuery(this).addClass("selected");
});
Do I really need to do this or can multiple selectors be used within the one filter method?
jQuery("a[href]").filter("[href!='#'][href!='']").each(function() {
jQuery(this).addClass("selected");
});
See http://api.jquery.com/multiple-attribute-selector/ for more information.
If you wanted to be slightly more verbose, and potentially more easily understood, you could use:
jQuery('a[href]').filter(
function(){
var href = jQuery(this).attr('href');
return (href.indexOf('#') > -1 && href.length);
}).addClass('selected');
JS Fiddle demo.
References:
filter().

Categories