Everything works fine except one thing, I'd like it so when you have the .show class already visible, it will fade again when you click on another of the #c- divs.
http://jsfiddle.net/7KdR6/1/
$('[id^="c-"]').each(function(i){
$this = $(this);
$(this).text(i);
$(this).on('click',function(){
$('.show').fadeIn().text(i);
event.stopPropagation();
});
})
$(document).on('click', function(){
$('.show').fadeOut();
});
One of your problems is that you are not stopping the propagation because event is not being defined. You'll have to use the parameter for the click handler. Edit: Actually, it looks like event is automatically passed - I did not realize this before now. However, I still think it best to put the event object as the parameter if you are going to use it - jQuery does this in their examples and it makes it more obvious.
I also notice you are caching this but then not using that cached var. This means that every time you write $(this), it will have to rewrap that jquery object.
Then you can have a fadeOut and use the fadeIn as a callback for the fadeOut. This way if the .show element is already shown, it will fadeOut first. I'd write it like this:
$('[id^="c-"]').each(function (i) {
$this = $(this);
$this.text(i);
$this.on('click', function (event) {
event.stopPropagation();
$show = $(".show");
$show.fadeOut(function () {
$show.fadeIn().text(i);
});
});
})
Fiddle
You need to hide the element before using fadeIn on a visible element
$('[id^="c-"]').each(function (i) {
var $this = $(this);
$this.text(i);
$this.on('click', function () {
$('.show').hide().fadeIn().text(i);
event.stopPropagation();
});
})
Demo: Fiddle
Try calling .hide() before calling .fadeIn().
DEMO FIDDLE
Related
I created the next jsfiddle:
http://jsfiddle.net/AHyN5/6/
This is my code:
var mainDiv = document.getElementsByClassName('mainDiv');
var div = mainDiv[0].getElementsByClassName('data');
mainDiv[0].addEventListener("click", function(e) {
alert('1');
});
$(mainDiv[0]).children('img').click(function (e) {
e.stopImmediatePropagation()
return false;
})
I want that click on the pink background will popup a message with value of 1(an alert message).
When clicking the yellow, I want nothing to happen.
I read this blog but with no success..
Any help appreciated!
I agree with the others stating to use jQuery or straight DOM calls.
Here is another shot at the jQuery solution - very similar to the one above. I went ahead and presented it because it targets the images directly - in case that's what you're really trying to accomplish.
$(function()
{ var mainDiv = $('div.pink:first'),
imgs = $('img');
mainDiv.click(function()
{ alert('1');
});
imgs.click(function(e)
{ e.stopImmediatePropagation();
});
});
You could add pointer-events: none; to the yellow class. That will cause those elements to not fire click events.
See here for more info https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events
You have a mix of jQuery and DOM methods calls. Note also that for attaching event listeners, you should wait for all HTML document to be ready.
I'd recommend using either DOM methods ot jquery methods. Following is an example of jquery:
$(function(){
$('.pink:first').on("click", function(e) {
alert('1');
});
$('.yellow').on('click', function (e) {
e.stopPropagation();
});
})
See also this JSfiddle
With $('#sidebar').toggleClass('small'); Im adding adding/removing specified class from #sidebar.
When #sidebar has class small I should be able to perform additional actions when user hover over #sidebar.small.
I have tried to accomplish that with code bellow:
$("#sidebar.small").on({
mouseenter: function () {
alert(1); //doesn't work
},
mouseleave: function () {
//stuff to do on mouse leave
}
});
But that doesn't work.
How should I perform hover function on changed DOM element?
You should be able to use the jquery hover method to do this: https://api.jquery.com/hover/
Update:
Sorry noticed one other thing... when you originally set your event handler, does #sidebar have the css tag or not? The way your code is written, if it doesn't, it will try to attach to the element $("#sidebar.small"), so if the css tag is not there it won't attach to anything.
I think you want more like this:
$("#sidebar").on({
mouseenter: function() {
if($('#sidebar').hasClass('small')) {
alert(1);
}
}
});
Update again for a typo, sorry...
Jquery only binds the handlers for the found elements at the time of binding.
The solution is to rebind the appropriate handlers when you add the class.
jsfiddle
code from the fiddle:
$('#foo').click(function(){
$('<span></span>')
.text('A Span')
.appendTo('#container');
});
$('#bar').click(function(){
$('span').first().toggleClass('small');
bindHover();
})
function bindHover(){
$('span.small').unbind('hover'); // Avoid re-binding something
$('span.small').hover(function(){
alert('a')
});
}
bindHover();
This causes multiple buttons to take action:
$(document).on("click", ".file-this-email", fileThisEmail);
When fileThisEmail runs, I'd like to remove it from ONLY the current one (there are others on the page that still need it):
window.fileThisEmail = function(e) {
console.log('this was clicked');
}
I tried off, but couldn't seem to get it right. Any ideas?
In this case, you have to make the current element no longer match the ".file-this-email" selector.
$(document).on("click", ".file-this-email", function() {
console.log('this was clicked');
$(this).removeClass("file-this-email");
});
An alternative would be to add a filter to the selector, with the same concept.
$(document).on("click", ".file-this-email:not(.clicked)", function() {
console.log('this was clicked');
$(this).addClass("clicked");
});
Or, don't use delegation for this particular case. Delegation isn't some new technology that replaces direct binding, it's just another way of binding events. If used correctly, it can make code more efficient. The opposite is true too; if used incorrectly, it can make the code very bloated.
$(".file-this-email").on("click", function () {
console.log("this was clicked");
$(this).off("click");
});
// or even better (thanks #overachiever):
$(".file-this-email").one("click", function () {
console.log("this was clicked");
});
Bind individual handlers to each element like this:
$(".file-this-email").one("click",fileThisEmail);
What you should do is
$(document).on("click", ".file-this-email", fileThisEmail);
change this to
$(document).ready(function(){
$(".file-this-email").on("click",fileThisEmail);
$(".file-this-email").click(function(){
$(this).off("click",fileThisEmail);
});
});
The .one() method is good for this. http://api.jquery.com/one/
$(document).ready(function(){
$('.file-this-email').one('click', fileThisEmail);
});
I'm trying to apply a cool animation effect on a list with Jquery using a pseudo-recursive function.
It works pretty well for the first item, but after the first loop, the this which was selecting #column-left section becomes the li so of course, the function does not find the next li:hidden because it is already inside. Is there a way for me to come back to my original this once the "this" has changed or maybe do something different ?
$("#column-left section").mouseenter(function fadeItem(){
console.log(this);
$(this).find('ul li:hidden:first').delay(500).fadeIn(fadeItem);
});
Thank you very much for your help.
How about after the .fadeIn() trigger a mouseenter event on the parent section element:
$("#column-left section").mouseenter(function () {
$(this).find('ul li:hidden:first').delay(500).fadeIn(function () {
var $this = $(this);
//check to make sure there are more hidden `<li>` elements
if ($this.siblings('li:hidden').length > 0) {
//trigger a `mouseenter` event on the parent `section` element to continue the queue
$this.parents('section').trigger('mouseenter');
}
});
});
Here is a demo: http://jsfiddle.net/bhTnL/2/
You can use .end():
$(this)
.find('ul li:hidden:first')
.delay(500)
.fadeIn(fadeItem)
.end(); // returns to first selector
But you don't actually need to do this. To select the next hidden li, just do this:
$(this)
.find('ul li:hidden:first')
.delay(500)
.fadeIn(fadeItem)
.closest("li:hidden")
.delay(500)
.fadeIn(fadeItem);
Every function has access to the call method which allows you to pass in your this parameter. I rewrote your original solution using it here:
$("#column-left section").mouseenter(function fadeItem(){
$(this).find('ul li:hidden:first').delay(500).fadeIn.call(this, fadeItem);
});
Ok guys, I found an even better way:
$(this).find('ul li:hidden:first').delay(100).show("fast",function(){
$(this).next(':hidden').show("fast",arguments.callee);
});
Simply use next() (more info) to select the next li then call the function itselt using arguments.callee (more info)
Which gives the full following script below to show the list and hide it:
//show
$("#column-left section").mouseenter(function(){
$(this).find('ul li:hidden:first').delay(100).show("fast",function(){
$(this).next().show("fast",arguments.callee);
});
});
//hide
$("#column-left section").mouseleave(function(){
$(this).find('ul li:visible:last').delay(100).hide("fast",function(){
$(this).prev().hide("fast",arguments.callee);
});
});
I am using jquery to hide/show an DIV on hover of an LI. When I do this the div appeared but pops up and down without stopping until I take my mouse off the LI.
$(document).ready(function () {
$('li.menu_head').mouseover(function () {
$('div.newsadviceDrop').slideToggle('medium');
});
});
Try:
$(document).ready(function () {
$('li.menu_head').hover(function () {
$('div.newsadviceDrop').slideToggle('medium');
});
});
EDIT: To keep it open until you mouse over again do this
$(document).ready(function () {
$('li.menu_head').mouseenter(function () {
$('div.newsadviceDrop').slideToggle('medium');
});
});
Try to use .mouseenter instead of .mouseover
While the mouse is over li.menu_head, you will repeatedly call .slideToggle, which explains why you see the continuous behaviour. You could perhaps replace this with behaviour on mouseenter and mouseexit.
There is an issue like that with "mouseover".
Try "mouseenter" instead...
OR...
just use the jQuery hover()
EDIT:
silent1mezzo submitted the best/correct answer first.