These are for two separate codecademy exercises. They both pass me but I'm not getting the result I'm supposed to.
3.2 - Mouse Events - Question
Write a hover handler and attach it to all divs. In the first function add the class "hover" to the current object we are hovering over, and in the second remove the class "hover". We have already learned how to do this by passing the event object, but this time let's try another way by using $(this).addClass(). Though, you can try events if you would like!
When you are done the green boxes should pop out and turn blue as the user hovers over them.
3.2 - Mouse Events - Answer
$(document).ready(function(){
$('div').hover(function() {
(this).addClass('hover');
},
function() {
(this).removeClass('hover');
});
});
3.3 Keyboard Events - Question
keypress is formatted exactly like the click handler.
Write a keypress handler that appends a div with class "box" to the div with id = "boxDiv". Attach the keypress handler to the body of the document.
3.3 Keyboard Events - Answer
$(document).ready(function(){
$("body").keypress(function(event){
$('#boxDiv').append($("<div/>").addClass('box'));
});
});
If you'd like further clarification here's a direct link to the course.
http://www.codecademy.com/courses/jquery-events/2#!/exercises/1
Thanks in advance!
Regards,
Matt
Regarding mouse events, there's a minor syntax error:
(this).addClass('hover'); and (this).removeClass('hover');
are missing leading dollar signs. They should be:
$(this).addClass('hover'); and $(this).removeClass('hover');
As far as the keyboard test, it should work. When you run it, try clicking in the result area before pressing a key.
Related
I have a series of spans (togglers) and a series of divs (toggled). I created a make_toggle function that receives the toggler and its corresponding toggled as arguments.
Everything seems to work kind of ok up to the point where I try to implement a "toggle on click out". What I've tried is to attach to the html click event a function that checks whether the target of the click is contained within the toggled element. On toggle "back", I would then detach the handler so I am only checking when I need.
var check_if_clickingout = function(e) {
if (!toggled[0].contains(e.target)) {
toggle();
}
};
See fiddle: https://jsfiddle.net/andinse/65o211nc/11/
It doesn't even seem to work anymore but when it used to, it was triggering many more times than necessary (which was the reason for me to come here ask for help).
What am I doing wrong? What is the most effective way to go about this kind of situation where I am giving functionality to a series of independent DOM elements?
Just putting this out here that this seems to do the same thing.
$("span").click(function() {
$(this).siblings("div").toggleClass("blue");
});
Maybe I am missing something more that I am not seeing in your example.
See more: http://api.jquery.com/toggleclass/
I have a structure:
<span class="word">This</span><span class="word">is</span><span class="word">the</span><span class="word">text</span><span>.</span>
I want user to be able to make a selection of whole words (spans, class="words") (in browser on desktop and on iOS as well - like in iBooks).
And how can I style it with css?
What is the right way to do this? (didn't work with selections before)
Thanks.
I know you didn't mention jQuery - but with something this dynamic I think it is highly advisable to use it.
Wrap that whole deal in a div.
<div id="wordSelector"><spans></div>
And then attach a mousedown event to the div. Use a semaphore to ensure that events are handled only during mousedown. Capture mouseover events on the spans until the mouseup event is registered.
Note: These events may need to be attached to document instead of the div to ensure that a mousedown event outside of the div but entering the div is handled, and with mouseup as well in case the mouseup event is outside of the div.
var spansTouched = [];
var mouseDown = 0;
$("#wordSelector").mousedown( function(){
//track spans touched with a semaphore
mouseDown++;
});
$("#wordSelector").mouseup( function(){
mouseDown = 0;
//handle spansTouched and then reset it to []
});
$(".word").mouseover( function(){
if(mouseDown > 0){
spansTouched.push(this);
}
});
Obviously there is room for improvement here, this is just to highlight a possible approach to take using a semaphore and mouse events.
Not sure how you mean that the user should select a word. If the user should "select" a word by clicking on it, you could use a jQuery plugin like TipTip or any other tooltip-plugin. At least tiptip support click.
Not sure if any of the tooltip-plugins support triggering on highlight of text by default, but using a JavaScript to listen for highlighting of text and the trigger the appropriate tooltip to show manually, and hide it again if the text is deselected.
Dave Welsh has written a small piece of jQuery to sniff for text-selection, that could be utilized.
i have 5 elements in a page.
i have selected them using class names $('.class')
i am trying to perform a function for those selected elements irrespective of event (click or hover or watever).
eg:
$('.class').hover(function(){definition1});
$('.class').click(function(){definition1});
i dont want to have 2 seperate event as above 2, instead i want the function to be executed irrespective of whether its hover or click event.
$('.class').bind('click mouseenter', function() {
// Go nuts.
});
(if using jQuery >= 1.7, swap bind() with on().)
Keep in mind that hover()'s second argument is for mouseleave event, which you haven't written anything for here.
If you want to cover most events, pass in 'blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error' as the first argument.
You could also try to detect them with code by iterating over properties that start with on, but it sounds too flaky to me.
To bind multiple events to one element in jQuery 1.7 and later you can do the following by separating event names by spaces:
jQuery('.class').on('click hover mousenter mouseleave', function(event){
// do what you need to do
});
which you can see in jsfiddle.
But: be careful, because you can easily fire the event too much times (more than necessary and more than enough). By binding so many events some may be called unnecessarily (as in the example above the code will be fired twice when the mouse cursor will leave the element it hovered over).
If you do not want to exec a function without any event put it in
$(function(){
function test(){definition1}
});
then in html
<body onload="test();">
I'm making a widget that slides in and out of view on hover with showTracker and hideTracker functions. I want to prevent it from sliding out of view if it contains a focussed form element though, so I've got this going:
function hideTracker(){
if($('#tracker').find(':focus').length == 0){
$('#tracker').stop().hide();
}
}
Cool. Now it doesn't hide if the mouse happens to move out if there's a field in focus. Unfortunately, that also means that when the field does lose focus (and it's time for the widget to hide again) it just stays there. The unHover event has been and gone.
So I added this:
$('#tracker *').blur(function(){
hideTracker();
});
And that works too - with one little bug that I need help with!
If the focus moves from one element within the tracker to another which is also within #tracker, the tracker hides. I figured that if($('#tracker').find(':focus').length == 0) would return false, given that the next form element has focus, but I guess it doesn't.
Is it the case that .blur() fires before the next element attains focus?
How can I get around this?
How about something like this?
$('body *').focus(function(){
if(!$(this).is('#tracker *') && $('#tracker:visible').length != 0) hideTracker();
});
Yikes. Tricky. Yes, what's happening is:
mousedown: old form element gets the blur event. $(':focus').length == 0.
mouseup: new form element gets the focus event. $newFormElement.is(':focus') == true.
This is an improvement:
$('#tracker').focusout(function() //basically like $('#tracker, #tracker *').blur(), but "this" is always '#tracker'
{
if(!$(this).is('#tracker:hover')) //for some reason plain old :hover doesn't work, at least on the latest OS X Chrome
hideTracker();
});
But it's not perfect. It only really works if you use the mouse. If you use tab to move between fields (or some other possible mechanism) while your mouse is not hovering over #tracker, it won't work.
Here's another attempt. It's a bit...hackier. The gist is that, instead of handling the blur event, you handle the focus event of the second thing that's focused. But! What if you click something that can't be focused? Blank space on your page? Then no focus event is fired.
Okay. So the trick is: put a tabindex="0" in your root <html> tag. This means that there is always something that can be focused. So there's no way to focus on nothing (at least, I don't think so).
Then you can do this:
$('*').live('focus', function(e)
{
if(!$.contains($('#tracker')[0], this)) //if the new thing you focused on is not a descendant of #tracker
hideTracker();
e.stopPropagation();
});
Eh? So yeah, that's a certified hack. But it's a tough problem, and that's the best I can come up with at this hour.
Thank you all for your answers. Utilising the .focus() event rather than .blur() was a clever way to look at it. Unfortunately, it does raise a couple of browser problems, and I couldn't get any of the above working very robustly.
In the end I decided to use setTimeout(hideTracker, 100); to allow the focus() event to take place before the count of focussed elements within tracker was evaluated. Not ideal, but it's working well and the delay is fairly imperceptible.
Thanks again.
I have a code like this
$('#singleColumn' + time).show(SHOW_COMPONENT_SPEED)
.live('mouseenter', function() { $('#propertiesButtonSingle' + time).fadeIn(FADEIN_SPEED); })
.live('mouseleave', function() { $('#propertiesButtonSingle' + time).fadeOut(FADEOUT_SPEED); });
which I'm using to show/hide a button when mouseenter/mouseleave events are fired on a box.
The problem is that my page is dynamic, i.e. I keep adding new HTML to the page using JQuery .html() function. What happes is that the mouse events are fired only for the last box I added (I add them by drag and dropping): pratically it works fine for the first box, if I add a second one the events are fired correctly for it but when I move the mouse over the first box nothing happens. If I add a third box the second one stops working too, etc...
The code I posted is for one kind of box, but for the other types it is pratically the same apart from the selector names.
take a look at .delegate() - http://api.jquery.com/delegate
you could bind events to an object higher up the DOM tree and listen ...