views:

4417

answers:

4

Hello All,

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.

+2  A: 

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();
aleemb
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
A: 

@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

wes
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!!
regex
+1  A: 

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/

CitizenParker
+1  A: 

Unfortunately there is a problem with the iframeFix in that it is difficult to release the transparent divs once being draggable. I had written another stronger version before but Unfortunately I lost the code... If I manage to resolve the prob I will repost my code.

EDIT: OK I worked out a manual but better way of doing it... at least in my case

You still create a transparent div over the top of the iframe's container when the containing div is clicked (onmousedown). This transparent div is positioned top:-90%, which should bring it over the iframe (depnding on your styling it may be more like top:-100%;). On the onmouseupEvent of the transparent div, you add the code to remove the transparent divs.

JSFUNCTIONS function coverIframes() { $(".normalWindow").append(""); }

function uncoverIframes() {
 $(".cover").remove();
}

CSS Styling for transparent div div.cover { width:100%; height:100%; top:-90%; position:relative; }

Example HTML