I am trying to create a firebug type rollover element selector, but seem to be having problems with the rollover triggering parent elements that contain my target element.
See the following example:
http://jsbin.com/elofe3/edit
There are 3 divs on the page, all with mouseenter/mouseleave listeners, the largest is totally independent of theother two, the second largest is position ontop of the largest but is not contained within it, and the sallest is nested within the second largest, (it's parent). It may be easier to visualise if you look at the source.
If you click preview and roll you mouse over the central div, you will notice that the second largest div also continues to respond to the mouseenter event and remains outlined in red. To fix this, I tried to add $(this).parent().trigger("mouseout"); on each rollover listener.
http://jsbin.com/elofe3/4/edit
But them when your mouse leaves the smallest (pink) div, to the middle (black) div, the middle div does not fire (presumably because mouseenter/mouseover is not being fired as the mouse has never actually left the central div.
I understand that in this situation I could just add $(this).parent().trigger("mouseover"); to the mouseleave listener on each div, but it would'nt work in evey example, (for instance, a div nested within its parent, but is positioned outside of that parent on the page.)
I require some novel solution to this, it needs to work very similarly to the firebug, element selector (the tool that lets you rollover elements on the page (higlighting them) and click to select them and triggering it to show the source for that element).
Any help greatly appreciated.
This is how mouseenter and mouseleave work. But you are mislead, mouseenter is not triggered on the parent element. Instead, mouseleave is not triggered if you hover over descendants. So it is not that the border is added again, but that it is never removed.
Add the event handlers to mouseover and mouseout and prevent the event from bubbling up:
$("div").mouseover(function(e) {
e.stopPropagation();
$(this).css("outline", "solid 3px red");
});
$("div").mouseout(function(e) {
e.stopPropagation();
$(this).css("outline", "none");
});
http://jsbin.com/elofe3/5/edit
Related
I'm using Highmaps to show a simple map and over it I have another div with a component that draws things on top of the map (this has to be done this way, I cannot draw everything inside Highmaps, unfortunely).
Now I would like to have some interation with the map, although it is below my div. I would like to know if there is a way to trigger the click, hover, etc. events on the map when I click on the div on top of it.
I have searched Highmaps docs trying to find a method a-like trigger(ev, x, y) but there seems to be none. Then I tried a pure javascript solution using MouseEvent() and dispatchEvent() on the Map DOM, but it also didn't work.
I have set up a simple fiddle with what I want to work: http://jsfiddle.net/k11yfz58/1/
If we coment the #overlay div, we get an alert when we click in a state. I want the same behavior but clicking on the overlay div, is that possible?
Thanks!
EDIT
It was suggested to use the pointer-events CSS property for this. That does not solve my problem because I also need the events to be triggered on the #overlay div.
You can add this to your css:
#overlay {
pointer-events: none;
}
From MDN:
The pointer-events CSS property specifies under what circumstances (if any) a particular graphic element can become the target of mouse events.
and the none value:
none
The element is never the target of mouse events; however, mouse events may target its descendant elements if those descendants have pointer-events set to some other value. In these circumstances, mouse events will trigger event listeners on this parent element as appropriate on their way to/from the descendant during the event capture/bubble phases.
What this means is that your overlay element is "invisible" to mouse events, and thus mouse events occur on the div below.
I have 2 sibling divs. One div is a sub-navigation that partially overlays the slider div. I have a mouseover event on the slider, which hides the sub-navigation.
The problem is, as soon as I mouse over the sub-navigation, the slider mouseover event is triggered even though my mouse isn't touching the slider yet - although the mouse is technically over the slider - it's just being overlayed by the sub-navigation.
Hopefully I explained this well that someone will understand. Is there any way around this issue?
Thanks.
If you are trying to hide the second sibling, this will work. Just replace the css class names (subNav, slider) with whatever they actually are. Also, instead of left:100px do whatever you wanted to do here to the second div.
div.subNav:hover + div.slider {
left: 100px;
}
The plus sign (+) is a "adjacent sibling selector" in css.
I'm trying to attach click events to a couple of divs. One of which has no height or width, just borders. Maybe it's just the browser, but the clicks are being triggered very unreliably. Even the css parameters .class:hover{} isn't really working.
$("body").on("click", "._tlh_dropdown, ._tlh_dropdown *", function (event) {
isn't working when the a div contained by ._tlh_dropdown is clicked. And the div ._tlh_dropdown_close_button is not removing it's parent div when clicked, nor turning a darker shade of gray when it is hovered over. What am I doing wrong here? I assume it has to do with the click event not being applied to the areas of the divs that are "just padding". Is this the case? How can I overcome this?
http://jsfiddle.net/UrNUM/7/
This is happening because the underline element that is a div element overlaps the elements in question . As you know div is a block level element.
One work around is to to set the 2 divs to inline-block
._tlh_dropdown_input_container, ._tlh_dropdown{
display: inline-block;
}
Check Fiddle for hover
If you want the div to be block level as it is then you can also play around with the z-index
._tlh_dropdown_close_button{
z-index: 1;
}
This will make sure the close div is always on top of the underlying container
UPDATE
2 events fire for every click event on the page..
So the content is not shown when u click on the image because of this condition
if ($targ.hasClass('_tlh_dropdown')
|| $targ.closest('._tlh_dropdown_content').length)
return;
This happens because the e.target when you click on the arrow image will be the arrow and not the tlh_dropdown .. So it fails on this condition and moves to the next statement where the content is removed.
Change it
if ($targ.hasClass('_tlh_dropdown')
|| $targ.closest('._tlh_dropdown').length
|| $targ.closest('._tlh_dropdown_content').length)
return;
It should work..
Check Fiddle
Also I feel the same can be accomplished with a lot less code. You can always have the HTML already built and then hide or show based on the condition.
Regarding the close button, if you hover "_tlh_dropdown_input_container" in the inspector, you can see that it overlaps the bottom part of the X button. That's why the hover/click event on the X is not caught below the middle of it.
Regarding the down arrow, just wrap it with another DIV on which you'll add the events. You can achieve minimal HTML by using a single DIV and adding the arrow to it using CSS :before or :after.
I have an unordered list where each li is a fixed small size but when you hover over it, it will expand to full size. This is done via ng-mouseover and ng-mouseout. The problem is that some of the li text contains other markup ( for example) and when the mouse enters the tag, it triggers a mouseout event and collapses the li.
Obviously the desired behavior is to have the li remain enlarged while the mouse is inside it, even if it's over a child element. Does anyone have an idea on how to basically ignore the mouseover of an inner element? I would also need to ignore the mouseout of the li if it were going into a child element.
There are two choices:
Use CSS pointer-events on your inner elements (but first check how well it is supported in your target browsers).
Use ngMouseenter/ngMouseleave instead (See this plnkr for different behavior between mouseenter/mouseleave vs. mouseover/mouseout)
In have two div in the page,the outer and the inner.
I bind the mousemove event to the outer div,when user mousemove in the outer div,it will show the clientX and clientY of the mouse.
Also I make the inner div dragable,here is the live example.
1) I do not want the outer's mousemove event trigger when I drag the inner div.
Of course I can set the "outer.onmousemove=null" when I drag the inner div,but I do not think it is the best way since the event on the outer div maybe binded by other people.
I try to use the event.cancalBubble,but it seems that it does not work.
2) when I drag the inner div,it will select the text in the firefox,how to stop it?
There are two functions that can be called to make sure that the event bubble stops:
event.stopPropagation();
event.preventDefault();
If you make sure to call both of those then it should prevent both the parent div being selected and the text being selected.
Edit:
Looking more closely at your code I see a few problems. The first thing is that you use the onmousemove event for registering the mouse coordinates in the "outer" div. Then you use the documents onmousemove to drag to "inner" div around. That means that if you stop the propagation for the onmousemove event when you start dragging, it will never bubble up to the document node and in turn will result in the draggable div never being dragged untill you actually move the mouse outside the "inner" div area.
One solution is to set the _mouseMove function on the moveable div instead of the document and then stop the propagation like this:
/* Remove this */
//document.onmousemove=_mouseMove;
//document.onmouseup=_mouseUp;
/* Add this */
move_ele.onmousemove=_mouseMove;
move_ele.onmouseup=_mouseUp;
e.stopPropagation();
e.preventDefault();
This will make it work like you mention except when you drag so fast that the cursor leaves the "inner" div area, then it will stop dragging untill the cursor enters the div area again.
Another solution is to handle it all in the "outer" divs onmousemove event to see if the mouse is actually moving over that div and not the "inner" like this:
out.onmousemove=function(e){
/* Check to see if the target is the "outer" div */
if(e.target == this){
e=e==null?window.event:e;
note.innerHTML=e.clientX+','+e.clientY;
}
}
This will also work like you mention but it will also stop the coordinates from being updated as soon as you move the cursor over the inner div even though you have not started dragging.