Trouble Using JQuery UI.Resizable() and UI.Draggable() with an iFrame

15,343

Solution 1

@aleemb: I don't believe that is what he's talking about. I believe the problem to be the Iframe and not the combination of the draggable and resizable.

@regex: I have this same issue and it also manifested itself with a prior implementation using the prototype toolkit.

My implementation uses an Iframe as a canvas on which to drop draggables. The way you can see the bug is to move your mouse too fast so that the cursor leaves the edge of the draggable DIV. The DIV stops moving and your mouse keeps going; by moving your mouse back to the surface of the DIV, it picks up the DIV again and starts moving even if you've released the click on your mouse.

My suspicion is that the Iframe events somehow interfere with the jquery events.

My solution was to position a transparent DIV tag between the Iframe and the draggables/resizables.

In this manner, the iframe never sees the mouse movement and as such doesn't interfere.

EDIT: See code sample: http://dpaste.com/hold/17009/

Wes

UPDATE! I revisited this issue and the iframeFix seems to work great in all browsers for the draggables, but the resizables do not have the equivalent fix.

I used this code to manually add a mask DIV:

$elements.resizable({ //mark it as resizable
    containment: "#docCanvas",
    start: function(event, ui) {
        //add a mask over the Iframe to prevent IE from stealing mouse events
        $j("#docCanvas").append("<div id=\"mask\" style=\"background-image:url(images/spacer.gif); position: absolute; z-index: 2; left: 0pt; top: 0pt; right: 0pt; bottom: 0pt;\"></div>");
    },
    stop: function(event, ui) {
        //remove mask when dragging ends
        $j("#mask").remove();
    }
});

And the HTML:

<div id="docCanvas" style="position: relative;">
    <iframe src="something.html"></iframe>
</div>

spacer.gif is a 1x1 pixel transparent gif.

This fixes the issue for IE7 & IE8. IE6 has trouble with z-index and can't seem to figure out that the DIV should be between the IFrame and the resizable DIV. I gave up on IE6.

Wes

Solution 2

Ran into the same resizable/redraggable problem recently.

// this will make <div id="box"> resizable() and draggable()
$('#box').resizable().parent().draggable();

// same but slightly safer since it checks parent's class
$('#box').resizable().parent('.ui-wrapper').draggable();

Solution 3

After using a solution similar to the one suggested by @wes, I found a simpler one, with no javascript code required. Just add the following to your CSS:

.ui-resizable-resizing:after
{
    content: '';
    position: absolute; 
    z-index: 999; 
    left: 0px; 
    top: 0px; 
    right: 0px;
    bottom: 0px;
}

Once the user starts to resize, jQuery adds the .ui-resizable-resizing class, and an overlay is added. Note that you'll need "position: relative" on the resized object.

Solution 4

I believe you can also fix this by adding the "iframeFix" parameter to the draggable initialization as described in the docs under "Options" http://jqueryui.com/demos/draggable/

Solution 5

try this

$('#Div').draggable({ iframeFix: true });

this should work

http://docs.jquery.com/UI/API/1.8/Draggable

Share:
15,343
regex
Author by

regex

Updated on June 08, 2022

Comments

  • regex
    regex almost 2 years

    I'm trying to create a dialog window using JQuery. I'm making progress so far, but running into some issues w/ the iframe... I know that iframes are usually frowned upon, but they are the only things that will meet the requirements of the project.

    Anyway, I can successfully implement the resizable and draggable plugins, but I run into issues if the user drags to fast and mouses over the iframe that is contained in the dialog's inner div. Kind of difficult to explain, but the code below should help show what is happening.

    It almost seems like once the mouse crosses over the iframe, the iframe steals the focus of the mousedown event. I'm wondering if there is any way around this.

    Thanks, Chris

    <div id="container" style="border: solid 1px Black; padding: 10px 10px 10px 10px; height: 520px; width: 420px;">
        <iframe id="if" src="http://google.com" style="width: 400px; height: 500px;"></iframe>
    </div>
    
    <script type="text/javascript" src="jquery-1.2.6.js"></script>
    <script type="text/javascript" src="jquery.ui.all.js"></script>
    <script type="text/javascript">
    
    $(document).ready(function()
        {
            $("#container").draggable();
            $("#container").resizable(
                {
                    alsoResize: "#if"
                }
            ).parent().draggable();
        }
    );
    


    EDIT: In order to run the app, the jquery files referenced in the code will need to be downloaded. The code should be backwards compatible with previous versions though.

    EDIT: I changed the code up a bit to simplify things a bit.

    EDIT: I found an alternative method to solving this problem by using the prototype-window libraries. I would much rather use jQuery over prototype since many of the benchmarks are a lot better, but due to my time crunch the protype route will do. I'm still interested in figuring this out though if anyone has some advice. Thanks again for all your help.

    EDIT: If I change the iframe to a div, the code above works flawlessly. The issue only appears to be the way that the draggable and resizable extensions function when and iframe is involved.

  • regex
    regex about 15 years
    Thanks for the help. However, your fix is not working for me. It is very likely that I am applying it wrong though. The issue that I'm running into is that if I mouse to fast, once I mouse over the iframe, the dragging / resizing stops because the iframe steals focus.
  • regex
    regex about 15 years
    I found a third party script online to help me out, but this answer seems like it would work as well, so I am marking it as the answer. Thanks a bunch!!
  • user185953
    user185953 about 3 years
    There is also a similar fix for dragging: Do the same for .ui-draggable-dragging {}