jQuery UIを使ってiframeをリサイズできるようにする
jQueryとjQuery UIがあれば大抵のことはできるのですが、意外なことにiframeのリサイズができなかったので、できるようにしてみました。
といっても、jQuery UIのResizableにiframe用の処理追加しただけです。
デモ
iframeをdivで囲む
Resizableは、リサイズハンドラーとしてのdiv要素を対象要素の子ノードとして追加するのですが、iframeにはappendChildできません。そこで、iframeをdivで囲みdivをリサイズ対象にして、alsoResizeとしてiframeを指定します(divのリサイズにiframeを連動させる)。
リサイズ中はiframeをdivで覆っておく
通常iframe上でのイベントは、iframe内で起きます。iframe上でマウス動かしても、$(document).mousemoveが起こらないって事です。そこで、iframeに透明なdiv要素をオーバレイさせることで、iframeにイベント横取りされるのを防ぎます。
以下ソース
$(function() { $('#wrapper').resizable({ handles: 'e, s', alsoResize: '#shinshu-u', start: function(event, ui) { // Add frame helpers $("iframe").each(function() { var offsetWidth = this.offsetWidth, offsetHeight = this.offsetHeight; $('<div class="ui-resizable-iframeFix" style="background: #fff;"></div>') .css({ width: offsetWidth+"px", height: offsetHeight+"px", position: "absolute", opacity: "0.001", zIndex: 1000 }) .css($(this).offset()) .appendTo("body") .data("resizable", { width: offsetWidth, height: offsetHeight }); }); }, resize: function(event, ui) { var self = $('#wrapper').data("resizable"), o = self.options, os = self.originalSize, op = self.originalPosition; var delta = { height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0, top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0 }, _alsoResize = function(exp, c) { $(exp).each(function() { var el = $(this), start = $(this).data("resizable"), style = {}, css = c && c.length ? c : ['width', 'height', 'top', 'left']; $.each(css || ['width', 'height', 'top', 'left'], function(i, prop) { // iframeより少し大きめに設定することで、iframe上でmouseupしてしまったときにmouseupイベント捕捉できない問題解消 var sum = (start[prop]||0) + (delta[prop]||0) + 5; if (sum && sum >= 0) style[prop] = sum || null; }); //Opera fixing relative position if (/relative/.test(el.css('position')) && $.browser.opera) { self._revertToRelativePosition = true; el.css({ position: 'absolute', top: 'auto', left: 'auto' }); } el.css(style); }); }; _alsoResize('div.ui-resizable-iframeFix', ['width', 'height']); }, stop: function(event, ui) { // Remove frame helpers $("div.ui-resizable-iframeFix") .removeData('resizable') .each(function() { this.parentNode.removeChild(this); }); } }); });
<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN' 'http://www.w3.org/TR/html4/strict.dtd'> <html> <head> <meta http-equiv='Content-type' content='text/html; charset=utf-8'> <link href='css/ui.all.css' type='text/css' rel="stylesheet"/> <script type='text/javascript' language='javascript' src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" charset='utf-8'></script> <script type='text/javascript' language='javascript' src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js" charset='utf-8'></script> <script type='text/javascript' language='javascript' src="js/resize-iframe.js" charset='utf-8'></script> <style type='text/css' media='screen'> /* <![CDATA[ */ #wrapper, #shinshu-u { width: 300px; height: 300px; } .ui-resizable-handle { background-color: #CCC; } /* ]]> */ </style> <title>resize</title> </head> <body> <div id="wrapper"> <iframe id="shinshu-u" src="http://www.cs.shinshu-u.ac.jp/"></iframe> </div> </body> </html>