I am wondering if there is a special DOM event that is triggered whenever an element needs to be re-layouted.
In my usecase, I want to display a "remove button" on a image. However, the position of the image is not fixed and I need to update the position of the button once the image is moved. For resizing, there are some jQuery plugins but I haven't found information how to listen to layout changes.
Thanks a lot in advance!
There isn't a DOM event that I know of, but one method would be to supply a function to setInterval to keep polling the position of the element, and act when it changes.
Related
I am working on a drag and drop project.
How: I am using the HTML5 drag events.
Code: See fiddle here
Problem: It only works sometimes, and I checked the code a million times
Idea:
- Get element and drag it over a div with id: LayerN (N=number)
- Create a new layer before LayerN when dropping
- AppendChild to new Layer.
- Remove empty layers if there are any.
Is there anything I am doing wrong or too complex? I don't want to use a JQuery framework, i want to understand what I am doing. Thanks a lot for reading, any help will be highly appreciated.
I can't get your fiddle to work so I'm giving general comments rather than a full 'answer' so hope it helps!
For D&D I find what works best is attach a mousedown event to the document on page load (or the containing element of the draggable objects if that's more appropriate).
Don't attach any events to the draggable elements themselves at this stage.
On mousedown, check the classname/id of the target and if it's draggable:
If you want to show it dragging, clone the element and append to a position:fixed or :absolute DIV - you can move this on mousemove relative to the cursor. Keeping this element offset to the cursor means you can still detect what's under the cursor.
Hide the element you're dragging. You can put some sort of image showing where it came from at this stage if you wish using insertBefore.
I hide the element rather than move it because if you cancel the drag it's very easy to restore it.
Attach mousemove and mouseup events to the window or document. The function you call on mousemove can, based upon the event.target/event.srcElement, decide whether the dragged object can be dropped or not (again, I generally look for a className here).
This way you've only got a maximum of two event listeners running everything rather than multiple events on every single element. I suspect your event listeners may be tripping over each other.
I don't know if that gets you any further, but good luck!
I am building an app that allows you to move list items from one list to another by simply clicking on them. However, in order for the user to know what the intended action for a clik is, I set up a :hover state in the CSS which shows an instruction such as "<< move"
The problem I have found however is that in Internet Explorer (tested versions 7-9), when I move a DOM element the :hover state of that element remains (becomes sticky), even when the mouse is moved around. The :hover state only disappears when a user hovers over the item in it's new location and then moves their mouse away. This is an Internet Explorer only issue it seems.
You can see the problem if you are using IE by going to http://jsfiddle.net/hc2Eu/32/
There is of course a workaround which is to not use CSS :hover state and use a JQuery hover event instead, but this is certainly not the best way of doing things, and keeping elements :hover state controlled in CSS is by far and away the most robust way of doing this. The workaround can be seen at http://jsfiddle.net/hc2Eu/29/
Has anyone figured out how I can tell Internet Explorer somehow that an element is no longer under the mouse, and it should release the :hover state?
Matt
Try cloning the element instead of appending it directly. When you append, you're taking the element from it's current position and state in the DOM and placing it in its new position - basically just moving it. IE is clearly not repainting the element when this happens, or resetting its state until you mouseover.
By cloning it, you force IE to create a new element, which, since it's not on the page, can't have the hover state applied to it anyway. Then just append it in its new container, remove the original, and you're done.
See an example in this fiddle: Two lines of code, cross-browser, and you'll remain concise and not pollute your code. :)
http://jsfiddle.net/hc2Eu/36/
this will handle your issue. clone the clicked item(add true if you want to save click event and other handlers) insert it after itself so it has the same place in the dom. then remove it. the clone will not be stuck with the hover state stuck. All references are relative (this) so it'll work anywhere without changing selectors.
$("#elementwithhover").click(function() {
// code that makes element or parent slide or
// otherwise move out from under mouse.
$(this).clone(true).insertAfter($(this));
$(this).remove();
});
Here's a basic example of what I have going on here:
http://jsfiddle.net/kgqkM/2/
What I'm trying to do is dedicate the area outside of this list to be a "delete" area where I can set up the appropriate logic to remove the dragged element from the page. I'm attempting to show when the user drags the element off the list it would color the outside red/ semi-transparent. When I set events on the outer-wrapper, they seem to take over all the dragenter/ dragleave events.
Guessing my issue has to do something with setting the event on the parent div? I'm starting to try and perhaps have one master event on top and deciding what to do based on the e.target and .parents('.switch'), but insofar it's resulting in buggy behavior.
It would seem that I had to do some (correct) logic on the event target. I have to refactor my code a bit, but it's working out.
I have a div in which there is a link. When a user takes the mouse pointer over the link, I call the basic_nav_mouseover() function which changes the background-image of the parent div. I have also added the function basic_nav_mouseout to the ommouseout attribute of the parent which should set the background-image of the parent div to none when the mouse pointer leaves the div. However, strangely, the function basic_nav_mouseout() is getting called as soon as the mouse pointer in leaving the link in the parent div. Here is a test page : http://spats.in/test/. Look at the links 'about' ,'people','connect' on the top right corner.
Where am I going wrong?
There's a really good explanation of the limitations of the mouseover and mouseout events in the jQuery docs (about half way down that page).
Mouseover and mouseout events trigger when you move the mouse over the bound element, as expected, but they also fire a separate event when you mouse over any inner elements within the parent element - this is obviously undesirable in most circumstances.
Basically, to fix your problem, use the mouseenter and mouseleave events instead.
From a user experience point of view, I'd encourage you to bind both events to the link, so that the special background colour actually indicates that the link is active - I think I'd find the effect you are trying to achieve quite misleading, because the highlighted background would make me think that I can still click the link, even though I cannot..
If you want to keep the visual effect you've current got (with a tall coloured area behind each link), make the link take up the whole box - i.e. 100% of the height and width of the div.
If onmouseover is set on the link, onmouseout should be set on the same element.
onmouseout gets triggered every time a child node is hovered over, you need to check the calling target.
http://www.quirksmode.org/js/events_mouse.html is a good resource.
I'm no javascript expert, but shouldn't you wait with binding the function to the event until the page is fully loaded? So:
window.onload = function(){
$('.item1').bind('mouseleave',basic_nav_mouseout);
};
Also (correct me if I'm wrong) I don't think you have to give the object as an argument in 'basic_nav_mouseout('.item1','red')', you can just use the 'this' keyword. So:
function basic_nav_mouseout(){
this.css('background-image',"none");
}
I don't know anything about the JQuery library though, my only (little) experience is with the Prototype library.
I have a couple of divs overlaid on each other with differing z-index values.
The default behaviour for browsers seems to be the event bound to the top-most z-index div gets fired. I.e. I have multiple onclicks one for each div but only the top one is fired when the area is clicked.
Is there a way to fire the events attached to all divs no matter what the z-index of each is, so long as the action is 'over' that div without regard to z-index?
The event doesn't actually occur on the element that is obscured by another unless the other element is contained in the first, then it will bubble up. The only way that I can think of to achieve what you want is to go through all of the potential elements and see if any of them contain the point at which the click occurred and trigger a click on that element (if it's not the current one).
If you are using an javaScript framework event bubbling might be included. (ExtJS I know for sure has this kind of event feature.)