I have the following JavaScript code for a simple hover which uses JQuery:
$('.product_img_link').hover(function(){
$(this).prev('.hoverProduct').show();
},function(){
$(this).prev('.hoverProduct').hide();
});
(finds the previous div with class hoverProduct, and displays it on hover and hides it on mouse out).
How can I write this snippet without JQuery, using only plain JavaScript?
Something like this:
var links = document.querySelectorAll('.product_img_link');
[].forEach.call(links, function(link) {
var prev = link.previousSibling;
link.addEventListener('mouseover', function() {
prev.style.display == 'block';
});
link.addEventListener('mouseout', function() {
prev.style.display == 'none';
});
});
In jQuery prev with a selector gets the previous element only if it matches the selector. If you want the same behavior in plain JS you can test like this:
...
var prev = link.previousSibling;
var hasClass = /\bhoverProduct\b/.test(prev.className);
if (hasClass) {
// events
}
...
Related
Hy guys, I would like to know how remove css styles after click event,
In fact at the first click I add css and remove some other things but I would like at the second click get the same css code at the beginning.
$('#show').click(function (){
$('.sub-menu').css('width', '185px');
$('.sub-menu').css('-webkit-transform', 'none');
$('.sub-menu').css('transform', 'none');
// and second click
$('.sub-menu').css('width', '');
$('.sub-menu').css('-webkit-transform', 'scale(0)');
$('.sub-menu').css('transform', 'scale(0)');
})
I don't want use toggleclass method cuz I don't want touch the css file.
Thanks.
A very simple option is to keep some kind of boolean marker.
var applied = false;
$('#show').click(function() {
if (!applied) {
$('.sub-menu').css('width', '185px');
$('.sub-menu').css('-webkit-transform', 'none');
$('.sub-menu').css('transform', 'none');
applied = true;
} else { // and second click
$('.sub-menu').css('width', '');
$('.sub-menu').css('-webkit-transform', 'scale(0)');
$('.sub-menu').css('transform', 'scale(0)');
applied = false;
}
})
You mentioned that you don't want to touch the css file. How about you create a css rule using jQuery and append it to the head tag.
var rule = $('<style>.myclass{width:185px; -webkit-transform:none; transform:none;}</style>');
$('html > head').append(rule);
$('#show').on('click',function(){
$('.sub-menu').toggleClass('myclass');
});
I'm using quicksand but I'd like to add a hover effect inside the element that is filtered by Quicksand jquery.
(function ($) {
var $itemsHolder = $('ul.proyectosthumb');
var $itemsClone = $itemsHolder.clone();
var $filterClass = "";
$('ul.filter li').click(function(e) {
e.preventDefault();
$filterClass = $(this).attr('data-value');
if ($filterClass == 'all') {
var $filters = $itemsClone.find('li');
}
else {
var $filters = $itemsClone.find('li[data-type='+ $filterClass +']');
}
$itemsHolder.quicksand($filters);
});
}(jQuery));
Function for hover effect:
$('.thumbnail').hover(
function(){
$(this).find('.caption-hover').fadeIn(250); //.fadeIn(250)
},
function(){
$(this).find('.caption-hover').fadeOut(250); //.fadeOut(205)
}
);
Any Idea to add this function inside Quicksand?
I also had the same issue with quick sand elemnts question here. this worked for me.use this function .this may help .
jQuery(document).on('hover',".thumbnail",function(){
//code here .
});
reason behind this is
The .on() method attaches event handlers to the currently selected set of elements in the jQuery object. check full desc
Please take a look at this jsfiddle
If you click on the divs on the top quickly enough, you'll find that eventually two divs end up appearing. I've had this problem with jQuery before as well. I just ended up disabling the buttons (or animation triggers) in that case, but I'm wondering if there is a more elegant solution to this.
Here is my jQuery code -
$(function () {
var _animDuration = 400;
$("#tabLists a").click(function () {
var attrHref = $(this).attr('href');
// Get shown anchor and remove that class -
$('.shownAnchor').removeClass('shownAnchor');
$(this).addClass('shownAnchor');
// first hide currently shown div,
$('.shownDiv').fadeOut(_animDuration, function () {
debugger;
// then remove the shownDiv class, show the clicked div.
$(this).removeClass('shownDiv');
$('#' + attrHref).fadeIn(_animDuration, function () {
// then add that shownDiv class to the div currently being shown.
$(this).addClass('shownDiv');
})
});
return false;
});
});
I'm using callbacks everywhere. I would like a solution that would queue up the animation rather than, not allow me to click
try this code with a check var:
$(function(){
var check = 1;
var _animDuration = 400;
$("#tabLists a").click(function(){
if(check == 1){
check = 0;
var attrHref = $(this).attr('href');
// Get shown anchor and remove that class -
$('.shownAnchor').removeClass('shownAnchor');
$(this).addClass('shownAnchor');
// first hide currently shown div,
$('.shownDiv').fadeOut(_animDuration, function(){
debugger;
// then remove the shownDiv class, show the clicked div.
$(this).removeClass('shownDiv');
$('#' + attrHref).fadeIn(_animDuration, function(){
// then add that shownDiv class to the div currently being shown.
$(this).addClass('shownDiv');
check = 1;
})
});
}
return false;
});
});
DEMO
I am trying to create a tagging system just like SO has.
I have added the tags,now I want to remove them.
MyQuestion:
How do I remove the tags appended?
how do I make the cross button(a span) look identical to that in SO tagging system?
SO TAGGING
var tags = [];
$("#textBox").keypress(function (e) {
if (e.which === 13) {
$(".target").append("X</span>'+ "");
function remove_tag(){
//what to do here?
}
tags.push(this.value);
this.value = "";
}
});
Here's my JSFiddle: http://jsfiddle.net/Wky2Z/11/
Basically, listen on the .cross to be clicked, and then remove from array and delete element
//enter something in textbox and press enter....
var tags = [];
$("#textBox").keypress(function (e) {
if (e.which === 13) {
$(".target").append("X</span>'+ "");
tags.push(this.value);
this.value = "";
}
});
$('body').on('click','.cross',function(){
tags.splice($(this).parent('a').html(), 1);
$(this).parent('a').remove();
});
As for the look of the cross, SO use a CSS Sprite, so you can do the same by making a png or gif or jpeg of the two states, off(grey) and hover(red) and switch the background-position to red with css eg: .cross:hover { background-position:0px -20px }
You can delete elements making use of remove().
Also, i would recommend you to make use of jQuery events instead of using inline events. (if you take a look at the source code of stackoverflow you will notice there are no inline javascript calls)
In this case you would need to add an event handler to the document object as you want to assign the events to elements which are not loaded in the DOM from the start.
$(document).on('click', '.tag span', function(){
$(this).parent().remove();
});
Living example: http://jsfiddle.net/Wky2Z/7/
Update
I updated the example removing the element from the list of tags too:
http://jsfiddle.net/Wky2Z/8/
Added a data-value for the tag links:
$(".target").append("X</span>'+ "");
And modified the click event:
$(document).on('click', '.tag span', function(){
$(this).parent().remove();
var removeItem = $(this).parent().data('value');
tags = $.grep(tags, function(value) {
return value != removeItem;
});
});
For a full jQuery solution you can remove the inline remove_tag function and use jQuery on function. it works for dynamically created elements too.
Attach an event handler function for one or more events to the
selected elements.
Here you can get the parent element of the deleted element and remove it from the DOM using remove.
To "sync" the array with the current situation you can use grep to delete the item from the array; note the removedItem variable used to get the text only of the parent excluding the children from the text.
Code:
//enter something in textbox and press enter....
var tags = [];
$(document).ready(function () {
$('body').on('click', 'span.cross', function () {
var removedItem = $(this).parent().contents(':not(span)').text();
$(this).parent().remove();
tags = $.grep(tags, function (value) {
return value != removedItem;
});
});
$("#textBox").keypress(function (e) {
if (e.which === 13) {
$(".target").append("X</span>' + "");
tags.push(this.value);
this.value = "";
}
});
});
Demo: http://jsfiddle.net/IrvinDominin/pDFnG/
Here's the updated link: http://jsfiddle.net/Wky2Z/6/
Move remove_tag outside of keypress event handle and pass a this pointer to it for quick solution:
//enter something in textbox and press enter....
var tags = [];
function remove_tag(x) {
$(x).parent('a').remove();
}
$(function () {
$("#textBox").keypress(function (e) {
if (e.which === 13) {
$(".target").append("X</span>' + "");
tags.push(this.value);
this.value = "";
}
});
});
I've got simple multi level accordion plugin. It's almost perfect for me.
(function(jQuery){
jQuery.fn.extend({
accordion: function() {
return this.each(function() {
var $ul = $(this);
if($ul.data('accordiated'))
return false;
$.each($ul.find('ul, li>div'), function(){
$(this).data('accordiated', true);
$(this).hide();
});
$.each($ul.find('a'), function(){
$(this).click(function(e){
activate(this);
return void(0);
});
});
var active = $('.active');
if(active){
activate(active, 'toggle');
$(active).parents().show();
}
function activate(el,effect){
$(el).parent('li').toggleClass('active').siblings().removeClass('active').children('ul, div').slideUp('fast');
$(el).siblings('ul, div')[(effect || 'slideToggle')]((!effect)?'fast':null);
}
});
}
});
})(jQuery);
Full code - http://jsfiddle.net/SKfax/
I'm trying to slightly remake this code, but without any success.
I need to toggleClass('.active') and removeClass('.active') only inside 'a' elements and not their parent 'li'
P.S.: '.active' class applies only to the headings of currently opened sections.
This was a proper logical conundrum, but I think I have got it working (let me know if I have misunderstood):
JSFiddle
I think the key was to prevent the first chain in the activate function from running on the first pass. So when you call activate here:
var active = $('.active');
if(active){
activate(active, 'toggle');
$(active).parents().show();
}
...you don't want to execute the chain that slides up siblings and toggles the active class.
I have also tweaked the activate function as described below:
function activate(el,effect){
//only do this if no effect is specified (i.e. don't do this on the first pass)
if (!effect) {
$(el)
.toggleClass('active') //first toggle the class of the clicked element (i.e. the 'a' tag)
.parent('li') //now we go up the DOM to the parent 'li'
.siblings() //get the sibling li's
.find('a') //get the 'a' tags below them (assuming there are no 'a' tags in the content text!)
.removeClass('active') //remove active class from these 'a' tags
.parent('li')
.children('ul, div')
.slideUp('fast'); //and hide the sibling content
}
//I haven't touched this
$(el).siblings('ul, div')[(effect || 'slideToggle')]((!effect)?'fast':null);
}