I'm having some problems with a project I'm currently involved with. Here is my situation. I am dynamically building and rendering a web page to an iframe, and I am wanting to offer the user the ability to resize the div elements within that rendered page in the iframe. To setup the context, consider the following snippets:
Host Page:
<html>
<head></head>
<body>
<div id="container">
<iframe id="site" src="proxy.php" style="width:100%;height:100%;"></iframe>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.11/jquery-ui.min.js"></script>
<script src="http://jqueryui.com/ui/jquery.ui.resizable.js"></script>
<script>
$("#site").load(function() {
$("#site").contents().find("#test-resize").resizable({
create: function(event, ui) {
console.log("Create");
},
start: function(event, ui) {
console.log("Start");
},
resize: function(event, ui) {
console.log("Resize");
}
});
});
</script>
</body>
</html>
Rendered Page:
<html>
<head>
<style>
body { margin: 0; padding: 0; }
#container { width: 960px;margin: auto;border: 1px solid #999; }
header { display: block;background: #dedede;padding: 5px; }
footer { display: block;padding: 10px;background: #555;colo开发者_开发百科r: #eee; }
.ui-resizable { position: relative;}
.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}
.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}
</style>
</head>
<body>
<div id="container">
<div id="main">
<header>
<div><h1>Header</h1></div>
</header>
</div>
<div id="body">
<h2>Body</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<p>Mauris et sapien ligula, sit amet tincidunt ligula.</p>
</div>
<footer>
<!-- I want the user to be able to resize this div -->
<div id="test-resize">Footer Div</div>
</footer>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.11/jquery-ui.min.js"></script>
<script src="http://jqueryui.com/ui/jquery.ui.resizable.js"></script>
</body>
</html>
So, what the host page is trying to do is reach into the rendered page and allow the 'test-resize' element to be resized. What I find puzzling is that the resizable plugin finds the 'test-resize' element and then adds the necessary resize handle divs and fires the 'create' event. However, when attempting to actually resize, nothing happens. Nothing changes, and no event fires.
With that, my question is, how can I (if at all) reach into an iframe and resize an element? Please note that these two pages are on the same domain.
Edit: I guess I should clarify another point. When adding the resize code to the generated page, the resize works fine, but I was wanting to keep the code at the host page level.
Okay, so after a little more digging, I was able to come up with a (hacked at best) solution. Unfortunately, it involves actually modifying jQuery UI. Note that I haven't performed a thorough analysis of this result to determine what the performance (and potentially other metrics) implications are. But at any rate, there are a couple of spots that need to be changed in order to get this to work. Please note that all these changes are happening within events in the UI Mouse widget. The first change is in the _mouseDown event when the widget is binding the mousemove and mouseup events. Change:
$(document)
.bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
.bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
To:
$($(this.element).get(0).ownerDocument)
.bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
.bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
So, this basically binds these events to the owner document regardless if the owner document is a regular old HTML page or a page in an iframe. Second, we need to unbind these events when the user lets up off the mouse. In the UI Mouse widget's _mouseUp event, change:
$(document)
.unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
.unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
To:
$($(this.element).get(0).ownerDocument)
.unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
.unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
Just unbinding the events that we bound above. Finally, we need to go back to the _mouseDown event and make a final change. At the top of this function, notice the line:
// don't let more than one widget handle mouseStart
if(mouseHandled) {return};
We need to comment that out or delete it. Either one. After that, it appears that we can have resizability from within the and outside the iframe. Whether or not this breaks any other widgets or plugins, idk. But lets hope not. I would appreciate it if you all could offer some advice over potential effects of this and hopefully offer a more elegant solution. Thanks.
I would suggest running resizable from the Rendered Page. It is your editor and would eliminate all the calls between parent and iframe. I've found that manipulating elements from other windows is complicated and not always the best practice. Instead, I've been limiting interaction between windows to calls to javascript functions. I've found this compartmentalizes my code better and makes it easier to port to other instances.
精彩评论