Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 847
regex Avatar asked Feb 03 '09 22:02

regex


4 Answers

@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

like image 105
wes Avatar answered Oct 05 '22 16:10

wes


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();
like image 41
aleemb Avatar answered Oct 05 '22 16:10

aleemb


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.

like image 24
Sasha Avatar answered Oct 05 '22 15:10

Sasha


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/

like image 44
sparker Avatar answered Oct 05 '22 16:10

sparker