Overview:
I am using Masonry Cascading grid layout library and adding Masonry Remove Method.
This method allows to click on any part of the item --> remove it--> and rests nicely the layout.
Issue:
I would like to remove an item (<div class="item 1"></div> “pink-box”) only by clicking on a specific area (i.e. button) within the item.
I tried to manipulate the function within the JavaScript file, but was unsuccessful to find a solution to my problem. (I started for the first time to build some website 2month ago, so have very little experience in jS or jQ)
Question:
Do you have any rough idea how I could fix this issue?
Here is a link to jsfiddle to show a brief overview of what I would like to achieve: http://jsfiddle.net/intimur/SfU5T/22/
HTML
<div class="masonry">
<div class="item 1"></div>
<div class="item 2">
<div class="remove-btn"> Click here to remove item </div>
</div>
</div>
JavaScript
// http://masonry.desandro.com/masonry.pkgd.js added as external resource
// added http://rawgithub.com/desandro/classie/master/classie.js
docReady( function() {
var container = document.querySelector('.masonry');
var msnry = new Masonry( container, {
columnWidth: 200
});
eventie.bind( container, 'click', function( event ) {
// don't proceed if item was not clicked on
if ( !classie.has( event.target, 'item' ) ) {
return;
}
// remove clicked element
msnry.remove( event.target );
// layout remaining item elements
msnry.layout();
});
});
I haven't checked yet the classie.js as I don't know if it's really needed to remove the item by clicking the button. Just adjusted your Fiddle with:
$(document).on('click', ".remove-btn", function () {
msnry.remove($(this).parent(".item"));
msnry.layout();
});
If you already have the .remove-btn in the actual DOM, it's not necessary to delegate the click-event to the .remove-button from the $(document), so if this is the case this can be simplified to
$(".remove-btn").click(function () {
msnry.remove($(this).parent(".item"));
msnry.layout();
});
Adjusted Fiddle for this version.
Related
I'm using swiper.js for a particular project, for the most part it's ok. However I wanted to adjust the container's look based on the when the slide is at the beginning, middle or at the end.
I know there's an event to watch for it, but I don't know how to add the class to the container DOM that triggered that particular event because there are several carousels in the same page. I tried using this.addClass('reached-end') and $(this).addClass('reached-end'), but it didn't work.
<div class="carousel-container">
<div class="swiper-wrapper">
<div class="swiper-slide">First Slide</div>
<div class="swiper-slide">Last Slide</div>
</div>
</div>
var cardDeck = new Swiper('.carousel-container', {
on: {
reachEnd: function () {
//add .reached-end to .carousel-container
// $(this).addClass('reached-end') // this didn't work
// this.addClass('reached-end') // this didn't work either
}
}
});
From the documentation you can see that all the events run under the scope of the Swiper instance, not the container element as your code expects:
Please note, that this keyword within event handler always points to Swiper instance
As such, you will need to select the element within the event handler. Note that Swiper provides both $el and $wrapperEl properties for this, depending on exactly which parent you want to target.
var cardDeck = new Swiper('.carousel-container', {
on: {
reachEnd: function () {
this.$el.addClass('reached-end');
}
}
});
I have been working on getting a popup menu on a button.
There are 7 buttons with this menu, on the page in different containers. So far you can click the button and the menu opens.
Each menu opens with its own version of this, which works but not efficient:
$('.country-btn-portugal').click(()=>{
$(".dropdowna").toggleClass('active');
});
$('.country-btn-uk').click(()=>{
$(".dropdowna").toggleClass('active');
});
....etc... x7, one for each button menu.
I have tried to close the menu if an item is clicked but doesnt function with:
//close if menu <a> is clicked
$('#mclose').click(()=>{
$('.dropdown').removeClass('active');
});
And using the following to close the menu if an item that is not this element is clicked (does not work):
$(document).mouseup(function (e)
{
var container = $("#oclick");
if (!container.is(e.target) // if the target of the click isn't the container...
&& container.has(e.target).length === 0) // ... nor a descendant of the container
{
container.hide();
}
});
which i was hoping would also fix the issue when 1 menu is open and your next click is another menu, so you have both open.
The menu buttons will be serving separate divs (or card like boxes and are not siblings next to eachother. Hence finding it hard to compact the code. had to give each menu its own click functions.
it is a mess sorry. would be nice to see where im going wrong here.
fiddle --> https://jsfiddle.net/s4nk1zev/118/
html structure for one "card" with one "menu button".
<div class="country_card">
<span class="cc-t goth upperC">Portugal </span> <span class="cc-t goth upperC blued">Visa</span>
<div class="cc-txt">
text in here
</div>
<div class="cc-btn">
<button class="tablabel country-btn-portugal" id="portimg"></button>
<div id="mcontainer" class="dropdowna">
<a id="mclose" class="mclose" href="#home">Overview</a>
<a id="mclose" href="#about">Application Process</a>
<a id="mclose" href="#contact">Investment Options</a>
</div>
</div>
</div>
Well, this is how I would have done that.
Here is the updated fiddle
And this script would do enough
//open menu
$('.tablabel').click(function(event){
$('.tablabel').not(this).next().removeClass("active")
$(this).next().toggleClass("active")
});
//close if menu clicked
$(".dpd").click(function(e){
$(this).toggleClass("active")
})
//close if anything but menu clicked
What it does is, just listen for any click on the button and add active class to the next of it. Removing active class from all the active elements if there is any.
Secondly, you can use a class (as I've added one dpd) on the menue items to detect a click on them to close the open menu.
One more thing. Identifiers must be unique for each element you use. I've also updated them to be unique
Hope that helps
SInce your button and menu tags appear to always be siblings, if you add a common class to all your dropdowns, you can get a list of all of them more easily. Like this:
<div id="mcontainer" class="dropdown dropdowna">
Also as a suggestion, it's really not a very good idea to have duplicate ids in your document. It's against the html standard, and it can cause strange issues with getting tags by id.
Once you have a common class on all your dropdowns, you can do something like this to close all others, and toggle the one related to the button you're clicking.
function fnClick(e){
var $dd = $(this).next();
$('.dropdown').not($dd).removeClass('active');
$dd.toggleClass('active');
}
//open menu
$('.country-btn-portugal').click(fnClick);
$('.country-btn-uk').click(fnClick);
here's an update of your fiddle to demonstrate:
https://jsfiddle.net/s4nk1zev/143/
You can try using promise().done(), and reviewing the html class. This is a fiddle for you: https://jsfiddle.net/zxoLmf71/
using a promise on an element let you wait for the code to finish execution before start the new one. this is the code:
//open menu
const buttons = $('.country-btn');
const dropDownMenus = $('.dropdownmenu');
const dropDownItems = $('.dropDownItem')
buttons.click(function() {
dropDownMenus.removeClass('active');
$(this).next('div').promise().done(function() {
$(this).toggleClass('active');
});
});
//close if menu clicked
dropDownItems.click(function() {
dropDownMenus.removeClass('active');
});
Hope it helps
I'm trying to get a fade toggle to work. When you click on (+) two it is supposed to show two links and change to (-) two and when you press again it closes those links and goes back to (+) two. Right now, I can't get anything to happen when you press on the toggle.
<div id="ending">
An everyday snapshot of
<div class="toggle"><span style="font-size:11px">(+) </span>two </div> sfsfs
</div>
<div class="content">
sfs & sfsf
</div>
$(document).ready(function() {
$(".content").hide();
$(".toggle").on("click", function() {
var txt = $(".content").is(':visible') ? '(+) two' : '(-) two';
$(".toggle").text(txt);
$(".toggle").toggleClass('active');
$(this).next('.content').slideToggle(450);
e.stopPropagation();
});
});
https://jsfiddle.net/Dar_T/b5tbfn5g/
1) You actually have to reference/include the jQuery library for jQuery functions to work.
2) You had an improper selector.
Rather than $(this).next('.content').slideToggle(450);
just use $('.content').slideToggle(450); or $(this).parent().next('.content').slideToggle(450);
The content div is not a sibling of the toggle div.. so next() isn't going to find it. But if you back up to the parent of the toggle div, then the content div is a sibling, so next() will find it.....
Depending on the rest of the markup, the selector may need to be further altered, but that's the main issue with the function overall.
Seems to work with the selector fixed and the jQuery library actually included.
$(document).ready(function() {
$(".content").hide();
$(".toggle").on("click", function() {
var txt = $(".content").is(':visible') ? '(+) two' : '(-) two';
$(".toggle").text(txt);
$(".toggle").toggleClass('active');
$(this).parent().next('.content').slideToggle(450);
e.stopPropagation();
});
});
Updated Fiddle
I am attempting to loop a hover effect such that an image dances to the four corners of the site (top left corner -> top right corner -> bottom right corner -> bottom leftcorner -> then back up to the top left corner)
The way I am doing this is by adding a class, hoverleft, right, down, up, etc. and removing the previous class. The issue I have is that the dynamically added classes are not recognized after the page loads. I have been trying to work with the .on() function but have been having difficulty. Not sure why and pretty sure I am just missing something simple.
Here is what I have, HTML then JS: fiddle here: http://jsfiddle.net/5w0nk6j9/4/
<div class="bodycontainer">
<div id="kim">
<div id="dance" class="dancingkim">
<div class="header">
<h2 class="introheader">Hover original</h2>
</div>
<img src="http://placehold.it/240x208" />
</div>
</div>
$('#kim').hover(function(){
$(".header h2").text("Hover text");
});
$('#kim').hover(function(){
$(".dancingkim").css("cursor", "pointer");
});
$('.dancingkim').hover(function(){
$(this).addClass("hoverleft");
$(this).removeClass("dancingkim");
});
$('#kim').on('hover', '.hoverleft', function() {
$('#dance').addClass("hoverdown");
$('#dance').removeClass("hoverleft");
});
In place of hover, try using mouseover or mouseenter or mouseleave.
$('#kim').on('mouseover', '.hoverleft', function() {
$('#dance').addClass("hoverdown");
$('#dance').removeClass("hoverleft");
});
From the JQuery source code, hover is not included in the event list that triggered leading to JQuery .on()
Dynamically generated elements are referenced by using .on() but it should be implemented on the document body. The javascript traverses the whole document and adds the property to it.
So, instead of using :
$('#kim').on('hover', '.hoverleft', function() {
$('#dance').addClass("hoverdown");
$('#dance').removeClass("hoverleft");
});
Try this:
$('body').on('mouseover', "#kim", function(){
$(this).next().addClass("hoverdown");
$(this).next().removeClass("hoverleft");
});
I have the following HTML code:
<div id='parentDiv'>
<div class='firstDiv'>
<div class='firstDivChild1'></div>
<div class='firstDivChild2'>
<div class='firstDivChild2_Child1'></div>
<div class='firstDivChild2_Child2'></div>
</div>
</div>
<div class='secondDiv'>
<div class='secondDivChild1'>
<div class='secondDivChild1_child'>
<div class='secondDivChild1_child_child'></div>
</div>
</div>
</div>
</div>
Now my requirement is when I click on any div I want to get an top most parent Id (i.e. parentDiv). Presently I'm using the below script to get parent Id:
<script type='text/javascript'>
$('div').click(function(e){
var parentDivId = (e.target).parentNode.id;
alert(parentDivId );
});
</script>
but it doesn't work. Can anyone correct this code to reach my requirement?
If that parent DIV is unique across document, then you just can refer to it by ID, i.e. $('#parentDiv'), but if it's not, then you should change your HTML and add to parentDiv some class (i.e. parentDiv), and you'll be able to refer to it by this expression $(this).parents('.parentDiv:first');
$('div').click(function() {
alert($(this).parents('div').last().attr('id'));
return false;
});
Live DEMO
then use the natural power of event bubbling. any descendant clicked will bubble up the event upwards (hence bubble) and will act as if the parent is clicked. so adding a click handler to the parent also does the same thing.
$('#parentDiv').on('click',function(){
var id = this.id
});
Try this little function :
$.fn.root = function() {
var $all = $( this[0] ).parents();
// omit "html", "body" and one index to the last item;
return $all.slice( $all.length - 3, $all.length - 2 );
};
Sample Usage :
$('input').click(function() {
alert($(this).root().prop('id'));
});
Simple working example using your HTML here
It is still not completely obvious what you're asking for, but based on a few of your comments, here's my best guess.
Using event bubbling, you can examine all clicks in your document and you then determine where the click originated with e.target and you can then figure out whether that click originated in your div tree or elsewhere:
$(document).click(function(e) {
// determine if click was in our div tree or not
if ($(event.target).closest("#parentDiv").length) {
// click was in our parentDiv tree
} else {
// click was not in our parentDiv tree
}
});
Regardless of where the click was located, you can get the top of your div tree id="parentDiv" at any time with this with this jQuery:
$("#parentDiv")
If, you just want the top-most div that is above what is clicked, no matter where the click is in the document, you can use event bubbling like this to get that:
$(document).click(function(e) {
e.stopPropagation();
var topMostDiv = $(e.target).parents("div").last();
// do whatever you want with topMostDiv here
});