jquery-ui实现一个多tab标签页可拖动编辑器记事本效果代码
代码语言:html
所属分类:其他
代码描述:jquery-ui实现一个多tab标签页可拖动编辑器效果代码
代码标签: jquery-ui tab 标签页 编辑器 记事本 拖动
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <style> @font-face { font-family: 'icomoon'; src:url('data:application/font-woff;base64,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') format('woff'), url('') format('truetype'), url('') format('svg'); font-weight: normal; font-style: normal; } [class^="icon-"], [class*=" icon-"] { font-family: 'icomoon'; speak: none; font-style: normal; font-weight: normal; font-variant: normal; text-transform: none; line-height: 1; /* Better Font Rendering =========== */ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } .icon-paragraph-left:before { content: "\e600"; } .icon-paragraph-center:before { content: "\e601"; } .icon-paragraph-right:before { content: "\e602"; } .icon-bold:before { content: "\e603"; } .icon-underline:before { content: "\e604"; } .icon-italic:before { content: "\e605"; } .icon-plus:before { content: "\e606"; } .icon-minus:before { content: "\e607"; } .icon-quill:before { content: "\e608"; } @import url(https://fonts.googleapis.com/css?family=Telex); * { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; -webkit-font-smoothing: antialiased; } body { background: #5deaba; } .launch { font-family: "Telex", sans-serif; text-decoration: none; width: 240px; height: 60px; display: block; text-align: center; line-height: 38px; border-radius: 3px; font-size: 60px; color: #fff; position: absolute; left: 50%; top: 50%; margin: -30px 0 0 -120px; display: none; } .texteditor { width: 550px; height: 450px; position: absolute; left: 50%; top: 50%; background: #fff; margin: -205px 0 0 -275px; border-radius: 0 0 10px 10px; box-shadow: 0px -12px 200px #20b080; } .texteditor .ops { height: 288px; width: 50px; background: #ebebeb; position: absolute; right: 0px; border-radius: 0 10px 10px 0; z-index: 1; display: none; } .texteditor .ops ul { list-style: none; margin: 0; padding: 0; } .texteditor .ops ul li { text-align: center; padding: 10px 0; } .texteditor .ops ul li:first-child { border-radius: 0 10px 0 0; } .texteditor .ops ul li:last-child { border-radius: 0 0 10px 0; } .texteditor .ops ul li:hover { background: #31d687; } .texteditor .ops ul li:hover a { color: #fff; } .texteditor .ops ul li a { text-decoration: none; color: grey; display: block; } .texteditor .textareawrap .fontsize { background: #5deaba; position: absolute; z-index: 400; bottom: 5px; left: 5px; padding: 5px 10px; font-family: "Telex", sans-serif; color: #fff; font-size: 16px; border-radius: 0 0 0 5px; display: none; } .texteditor .textareawrap .textarea { display: none; margin: 0; padding: 10px; width: 100%; height: 100%; position: absolute; border: 0; outline: none; resize: none; overflow: auto; border-radius: 0 0 10px 10px; font-family: "Telex", sans-serif; font-size: 13px; color: #666; background: #fff; z-index: 2; } .texteditor .top { font-family: "Telex", sans-serif; position: absolute; height: 45px; background: #ebebeb; top: -45px; width: 100%; border-radius: 10px 10px 0 0; border-bottom: 1px solid #bababa; cursor: move; overflow: hidden; } .texteditor .top .icon-quill { font-size: 25px; float: right; margin: 0 10px 0 0; color: grey; text-decoration: none; } .texteditor .top .icon-quill:hover { color: #31d687; } .texteditor ul.controls { padding: 0; margin: 16px 0 0 15px; list-style: none; float: left; width: 65px; } .texteditor ul.controls li { width: 15px; height: 15px; float: left; margin: 0 4%; border-radius: 50%; cursor: pointer; } .texteditor ul.controls li:after { content: ""; background: linear-gradient(225deg, #ffffff 50%, transparent 50%); width: 15px; height: 15px; position: absolute; z-index: 2; border-radius: 50%; opacity: 0.4; } .texteditor ul.controls .close { background: #e57069; } .texteditor ul.controls .min { background: #f5ce56; } .texteditor ul.controls .expand { background: #31d687; } .texteditor ul.tabs { margin: 9px 0 0 100px; padding: 0; list-style: none; } .texteditor ul.tabs .addtab { font-size: 22px; z-index: 305; color: grey; position: relative; cursor: pointer; float: left; margin: 0 0 0 5px; } .texteditor ul.tabs .addtab:hover { color: #31d687; } .texteditor ul.tabs li { float: left; width: auto; margin: 0 -5px; padding: 0 15px; border-bottom: 35px solid #dad8d8; border-right: 20px solid transparent; border-left: 20px solid transparent; height: 0; line-height: 37px; position: relative; z-index: 2; cursor: pointer; } .texteditor ul.tabs li span { position: absolute; top: -12px; left: 2px; display: none; width: 17px; height: 17px; border-radius: 50%; top: -5px; left: -7px; text-align: center; line-height: 16px; background: #e57069; font-size: 20px; z-index: 3; } .texteditor ul.tabs li span:after { content: ""; background: linear-gradient(225deg, #ffffff 50%, transparent 50%); width: 15px; height: 15px; position: absolute; z-index: 2; border-radius: 50%; opacity: 0.2; left: 2px; } .texteditor ul.tabs li a { text-decoration: none; color: #fff; } .ui-resizable-e { right: 0; position: absolute; width: 5px; height: 100%; } .ui-resizable-s { bottom: 0; height: 5px; width: 100%; position: absolute; } .ui-icon-gripsmall-diagonal-se { z-index: 90; bottom: 0; right: 0; position: absolute; width: 10px; height: 10px; } .ui-resizable-s:hover { cursor: ns-resize; } .ui-resizable-e:hover { cursor: ew-resize; } .ui-icon-gripsmall-diagonal-se:hover { cursor: nwse-resize; } .active { border-bottom-color: #bababa !important; z-index: 300 !important; } .bold { font-weight: bold; } .italic { font-style: italic; } .underline { text-decoration: underline; } .leftalign { text-align: left; display: inline; } .rightalign { text-align: right; display: block; } .centeralign { text-align: center; display: block; } </style> </head> <body> <a href="#" class="launch"> LAUNCH </a> <div class="texteditor"> <div class="top"> <ul class="controls"> <li class="close"> <a href="#"></a> </li> <li class="min"> <a href="#"></a> </li> <li class="expand"> <a href="#"></a> </li> </ul> <ul class="tabs"> <span class="tabwrap"> </span> </ul> <a href="#" class="icon-quill"></a> </div> <div class="textareawrap"> <span class="fontsize"></span> </div> <aside class="ops"> <ul> <li> <a href="#" class="icon-bold"></a> </li> <li> <a class="icon-underline" href="#"></a> </li> <li> <a class="icon-italic" href="#"></a> </li> <li> <a class="icon-paragraph-left" href="#"></a> </li> <li> <a class="icon-paragraph-right" href="#"></a> </li> <li> <a class="icon-paragraph-center" href="#"></a> </li> <li> <a class="icon-plus" href="#"></a> </li> <li> <a class="icon-minus" href="#"></a> </li> </ul> </aside> </div> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/jquery.2.11.js"></script> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/jquery-ui-1.10.3.min.js"></script> <script> (function (factory, root) { if (typeof define == "function" && define.amd) { // AMD. Register as an anonymous module. define(factory); } else if (typeof module != "undefined" && typeof exports == "object") { // Node/CommonJS style module.exports = factory(); } else { // No AMD or CommonJS support so we place Rangy in (probably) the global variable root.rangy = factory(); } })(function () { var OBJECT = "object",FUNCTION = "function",UNDEFINED = "undefined"; // Minimal set of properties required for DOM Level 2 Range compliance. Comparison constants such as START_TO_START // are omitted because ranges in KHTML do not have them but otherwise work perfectly well. See issue 113. var domRangeProperties = ["startContainer", "startOffset", "endContainer", "endOffset", "collapsed", "commonAncestorContainer"]; // Minimal set of methods required for DOM Level 2 Range compliance var domRangeMethods = ["setStart", "setStartBefore", "setStartAfter", "setEnd", "setEndBefore", "setEndAfter", "collapse", "selectNode", "selectNodeContents", "compareBoundaryPoints", "deleteContents", "extractContents", "cloneContents", "insertNode", "surroundContents", "cloneRange", "toString", "detach"]; var textRangeProperties = ["boundingHeight", "boundingLeft", "boundingTop", "boundingWidth", "htmlText", "text"]; // Subset of TextRange's full set of methods that we're interested in var textRangeMethods = ["collapse", "compareEndPoints", "duplicate", "moveToElementText", "parentElement", "select", "setEndPoint", "getBoundingClientRect"]; /*----------------------------------------------------------------------------------------------------------------*/ // Trio of functions taken from Peter Michaux's article: // http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting function isHostMethod(o, p) { var t = typeof o[p]; return t == FUNCTION || !!(t == OBJECT && o[p]) || t == "unknown"; } function isHostObject(o, p) { return !!(typeof o[p] == OBJECT && o[p]); } function isHostProperty(o, p) { return typeof o[p] != UNDEFINED; } // Creates a convenience function to save verbose repeated calls to tests functions function createMultiplePropertyTest(testFunc) { return function (o, props) { var i = props.length; while (i--) {if (window.CP.shouldStopExecution(0)) break; if (!testFunc(o, props[i])) { return false; } }window.CP.exitedLoop(0); return true; }; } // Next trio of functions are a convenience to save verbose repeated calls to previous two functions var areHostMethods = createMultiplePropertyTest(isHostMethod); var areHostObjects = createMultiplePropertyTest(isHostObject); var areHostProperties = createMultiplePropertyTest(isHostProperty); function isTextRange(range) { return range && areHostMethods(range, textRangeMethods) && areHostProperties(range, textRangeProperties); } function getBody(doc) { return isHostObject(doc, "body") ? doc.body : doc.getElementsByTagName("body")[0]; } var forEach = [].forEach ? function (arr, func) { arr.forEach(func); } : function (arr, func) { for (var i = 0, len = arr.length; i < len; ++i) {if (window.CP.shouldStopExecution(1)) break; func(arr[i], i); }window.CP.exitedLoop(1); }; var modules = {}; var isBrowser = typeof window != UNDEFINED && typeof document != UNDEFINED; var util = { isHostMethod: isHostMethod, isHostObject: isHostObject, isHostProperty: isHostProperty, areHostMethods: areHostMethods, areHostObjects: areHostObjects, areHostProperties: areHostProperties, isTextRange: isTextRange, getBody: getBody, forEach: forEach }; var api = { version: "1.3.1-dev", initialized: false, isBrowser: isBrowser, supported: true, util: util, features: {}, modules: modules, config: { alertOnFail: false, alertOnWarn: false, preferTextRange: false, autoInitialize: typeof rangyAutoInitialize == UNDEFINED ? true : rangyAutoInitialize } }; function consoleLog(msg) { if (typeof console != UNDEFINED && isHostMethod(console, "log")) { console.log(msg); } } function alertOrLog(msg, shouldAlert) { if (isBrowser && shouldAlert) { alert(msg); } else { consoleLog(msg); } } function fail(reason) { api.initialized = true; api.supported = false; alertOrLog("Rangy is not supported in this environment. Reason: " + reason, api.config.alertOnFail); } api.fail = fail; function warn(msg) { alertOrLog("Rangy warning: " + msg, api.config.alertOnWarn); } api.warn = warn; // Add utility extend() method var extend; if ({}.hasOwnProperty) { util.extend = extend = function (obj, props, deep) { var o, p; for (var i in props) { if (props.hasOwnProperty(i)) { o = obj[i]; p = props[i]; if (deep && o !== null && typeof o == "object" && p !== null && typeof p == "object") { extend(o, p, true); } obj[i] = p; } } // Special case for toString, which does not show up in for...in loops in IE <= 8 if (props.hasOwnProperty("toString")) { obj.toString = props.toString; } return obj; }; util.createOptions = function (optionsParam, defaults) { var options = {}; extend(options, defaults); if (optionsParam) { extend(options, optionsParam); } return options; }; } else { fail("hasOwnProperty not supported"); } // Test whether we're in a browser and bail out if not if (!isBrowser) { fail("Rangy can only run in a browser"); } // Test whether Array.prototype.slice can be relied on for NodeLists and use an alternative toArray() if not (function () { var toArray; if (isBrowser) { var el = document.createElement("div"); el.appendChild(document.createElement("span")); var slice = [].slice; try { if (slice.call(el.childNodes, 0)[0].nodeType == 1) { toArray = function (arrayLike) { return slice.call(arrayLike, 0); }; } } catch (e) {} } if (!toArray) { toArray = function (arrayLike) { var arr = []; for (var i = 0, len = arrayLike.length; i < len; ++i) {if (window.CP.shouldStopExecution(2)) break; arr[i] = arrayLike[i]; }window.CP.exitedLoop(2); return arr; }; } util.toArray = toArray; })(); // Very simple event handler wrapper function that doesn't attempt to solve issues such as "this" handling or // normalization of event properties var addListener; if (isBrowser) { if (isHostMethod(document, "addEventListener")) { addListener = function (obj, eventType, listener) { obj.addEventListener(eventType, listener, false); }; } else if (isHostMethod(document, "attachEvent")) { addListener = function (obj, eventType, listener) { obj.attachEvent("on" + eventType, listener); }; } else { fail("Document does not have required addEventListener or attachEvent method"); } util.addListener = addListener; } var initListeners = []; function getErrorDesc(ex) { return ex.message || ex.description || String(ex); } // Initialization function init() { if (!isBrowser || api.initialized) { return; } var testRange; var implementsDomRange = false,implementsTextRange = false; // First, perform basic feature tests if (isHostMethod(document, "createRange")) { testRange = document.createRange(); if (areHostMethods(testRange, domRangeMethods) && areHostProperties(testRange, domRangeProperties)) { implementsDomRange = true; } } var body = getBody(document); if (!body || body.nodeName.toLowerCase() != "body") { fail("No body element found"); return; } if (body && isHostMethod(body, "createTextRange")) { testRange = body.createTextRange(); if (isTextRange(testRange)) { implementsTextRange = true; } } if (!implementsDomRange && !implementsTextRange) { fail("Neither Range nor TextRange are available"); return; } api.initialized = true; api.features = { implementsDomRange: implementsDomRange, implementsTextRange: implementsTextRange }; // Initialize modules var module, errorMessage; for (var moduleName in modules) { if ((module = modules[moduleName]) instanceof Module) { module.init(module, api); } } // Call init listeners for (var i = 0, len = initListeners.length; i < len; ++i) {if (window.CP.shouldStopExecution(3)) break; try { initListeners[i](api); } catch (ex) { errorMessage = "Rangy init listener threw an exception. Continuing. Detail: " + getErrorDesc(ex); consoleLog(errorMessage); } }window.CP.exitedLoop(3); } function deprecationNotice(deprecated, replacement, module) { if (module) { deprecated += " in module " + module.name; } api.warn("DEPRECATED: " + deprecated + " is deprecated. Please use " + replacement + " instead."); } function createAliasForDeprecatedMethod(owner, deprecated, replacement, module) { owner[deprecated] = function () { deprecationNotice(deprecated, replacement, module); return owner[replacement].apply(owner, util.toArray(arguments)); }; } util.deprecationNotice = deprecationNotice; util.createAliasForDeprecatedMethod = createAliasForDeprecatedMethod; // Allow external scripts to initialize this library in case it's loaded after the document has loaded api.init = init; // Execute listener immediately if already initialized api.addInitListener = function (listener) { if (api.initialized) { listener(api); } else { initListeners.push(listener); } }; var shimListeners = []; api.addShimListener = function (listener) { shimListeners.push(listener); }; function shim(win) { win = win || window; init(); // Notify listeners for (var i = 0, len = shimListeners.length; i < len; ++i) {if (window.CP.shouldStopExecution(4)) break; shimListeners[i](win); }window.CP.exitedLoop(4); } if (isBrowser) { api.shim = api.createMissingNativeApi = shim; createAliasForDeprecatedMethod(api, "createMissingNativeApi", "shim"); } function Module(name, dependencies, initializer) { this.name = name; this.dependencies = dependencies; this.initialized = false; this.supported = false; this.initializer = initializer; } Module.prototype = { init: function () { var requiredModuleNames = this.dependencies || []; for (var i = 0, len = requiredModuleNames.length, requiredModule, moduleName; i < len; ++i) {if (window.CP.shouldStopExecution(5)) break; moduleName = requiredModuleNames[i]; requiredModule = modules[moduleName]; if (!requiredModule || !(requiredModule instanceof Module)) { throw new Error("required module '" + moduleName + "' not found"); } requiredModule.init(); if (!requiredModule.supported) { throw new Error("required module '" + moduleName + "' not supported"); } } // Now run initializer window.CP.exitedLoop(5);this.initializer(this); }, fail: function (reason) { this.initialized = true; this.supported = false; throw new Error(reason); }, warn: function (msg) { api.warn("Module " + this.name + ": " + msg); }, deprecationNotice: function (deprecated, replacement) { api.warn("DEPRECATED: " + deprecated + " in module " + this.name + " is deprecated. Please use " + replacement + " instead"); }, createError: function (msg) { return new Error("Error in Rangy " + this.name + " module: " + msg); } }; function createModule(name, dependencies, initFunc) { var newModule = new Module(name, dependencies, function (module) { if (!module.initialized) { module.initialized = true; try { initFunc(api, module); module.supported = true; } catch (ex) { var errorMessage = "Module '" + name + "' failed to load: " + getErrorDesc(ex); consoleLog(errorMessage); if (ex.stack) { consoleLog(ex.stack); } } } }); modules[name] = newModule; return newModule; } api.createModule = function (name) { // Allow 2 or 3 arguments (second argument is an optional array of dependencies) var initFunc, dependencies; if (arguments.length == 2) { initFunc = arguments[1]; dependencies = []; } else { initFunc = arguments[2]; dependencies = arguments[1]; } var module = createModule(name, dependencies, initFunc); // Initialize the module immediately if the core is already initialized if (api.initialized && api.supported) { module.init(); } }; api.createCoreModule = function (name, dependencies, initFunc) { createModule(name, dependencies, initFunc); }; /*----------------------------------------------------------------------------------------------------------------*/ // Ensure rangy.rangePrototype and rangy.selectionPrototype are available immediately function RangePrototype() {} api.RangePrototype = RangePrototype; api.rangePrototype = new RangePrototype(); function SelectionPrototype() {} api.selectionPrototype = new SelectionPrototype(); /*----------------------------------------------------------------------------------------------------------------*/ // DOM utility methods used by Rangy api.createCoreModule("DomUtil", [], function (api, module) { var UNDEF = "undefined"; var util = api.util; var getBody = util.getBody; // Perform feature tests if (!util.areHostMethods(document, ["createDocumentFragment", "createElement", "createTextNode"])) { module.fail("document missing a Node creation method"); } if (!util.isHostMethod(document, "getElementsByTagName")) { module.fail("document missing getElementsByTagName method"); } var el = document.createElement("div"); if (!util.areHostMethods(el, ["insertBefore", "appendChild", "cloneNode"] || !util.areHostObjects(el, ["previousSibling", "nextSibling", "childNodes", "parentNode"]))) { module.fail("Incomplete Element implementation"); } // innerHTML is required for Range's createContextualFragment method if (!util.isHostProperty(el, "innerHTML")) { module.fail("Element is missing innerHTML property"); } var textNode = document.createTextNode("test"); if (!util.areHostMethods(textNode, ["splitText", "deleteData", "insertData", "appendData", "cloneNode"] || !util.areHostObjects(el, ["previousSibling", "nextSibling", "childNodes", "parentNode"]) || !util.areHostProperties(textNode, ["data"]))) { module.fail("Incomplete Text Node implementation"); } /*----------------------------------------------------------------------------------------------------------------*/ // Removed use of indexOf because of a bizarre bug in Opera that is thrown in one of the Acid3 tests. I haven't been // able to replicate it outside of the test. The bug is that indexOf returns -1 when called on an Array that // contains just the document as a single element and the value searched for is the document. var arrayContains = /*Array.prototype.indexOf ? function(arr, val) { return arr.indexOf(val) > -1; }:*/ function (arr, val) { var i = arr.length; while (i--) {if (window.CP.shouldStopExecution(6)) break; if (arr[i] === val) { return true; } }window.CP.exitedLoop(6); return false; }; // Opera 11 puts HTML elements in the null namespace, it seems, and IE 7 has undefined namespaceURI function isHtmlNamespace(node) { var ns; return typeof node.namespaceURI == UNDEF || (ns = node.namespaceURI) === null || ns == "http://www.w3.org/1999/xhtml"; } function parentElement(node) { var parent = node.parentNode; return parent.nodeType == 1 ? parent : null; } function getNodeIndex(node) { var i = 0; while (node = node.previousSibling) {if (window.CP.shouldStopExecution(7)) break; ++i; }window.CP.exitedLoop(7); return i; } function getNodeLength(node) { switch (node.nodeType) { case 7: case 10: return 0; case 3: case 8: return node.length; default: return node.childNodes.length;} } function getCommonAncestor(node1, node2) { var ancestors = [],n; for (n = node1; n; n = n.parentNode) {if (window.CP.shouldStopExecution(8)) break; ancestors.push(n); }window.CP.exitedLoop(8); for (n = node2; n; n = n.parentNode) {if (window.CP.shouldStopExecution(9)) break; if (arrayContains(ancestors, n)) { return n; } }window.CP.exitedLoop(9); return null; } function isAncestorOf(ancestor, descendant, selfIsAncestor) { var n = selfIsAncestor ? descendant : descendant.parentNode; while (n) {if (window.CP.shouldStopExecution(10)) break; if (n === ancestor) { return true; } else { n = n.parentNode; } }window.CP.exitedLoop(10); return false; } function isOrIsAncestorOf(ancestor, descendant) { return isAncestorOf(ancestor, descendant, true); } function getClosestAncestorIn(node, ancestor, selfIsAncestor) { var p,n = selfIsAncestor ? node : node.parentNode; while (n) {if (window.CP.shouldStopExecution(11)) break; p = n.parentNode; if (p === ancestor) { return n; } n = p; }window.CP.exitedLoop(11); return null; } function isCharacterDataNode(node) { var t = node.nodeType; return t == 3 || t == 4 || t == 8; // Text, CDataSection or Comment } function isTextOrCommentNode(node) { if (!node) { return false; } var t = node.nodeType; return t == 3 || t == 8; // Text or Comment } function insertAfter(node, precedingNode) { var nextNode = precedingNode.nextSibling,parent = precedingNode.parentNode; if (nextNode) { parent.insertBefore(node, nextNode); } else { parent.appendChild(node); } return node; } // Note that we cannot use splitText() because it is bugridden in IE 9. function splitDataNode(node, index, positionsToPreserve) { var newNode = node.cloneNode(false); newNode.deleteData(0, index); node.deleteData(index, node.length - index); insertAfter(newNode, node); // Preserve positions if (positionsToPreserve) { for (var i = 0, position; position = positionsToPreserve[i++];) {if (window.CP.shouldStopExecution(12)) break; // Handle case where position was inside the portion of node after the split point if (position.node == node && position.offset > index) { position.node = newNode; position.offset -= index; } // Handle the case where the position is a node offset within node's parent else if (position.node == node.parentNode && position.offset > getNodeIndex(node)) { ++position.offset; } }window.CP.exitedLoop(12); } return newNode; } function getDocument(node) { if (node.nodeType == 9) { return node; } else if (typeof node.ownerDocument != UNDEF) { return node.ownerDocument; } else if (typeof node.document != UNDEF) { return node.document; } else if (node.parentNode) { return getDocument(node.parentNode); } else { throw module.createError("getDocument: no document found for node"); } } function getWindow(node) { var doc = getDocument(node); if (typeof doc.defaultView != UNDEF) { return doc.defaultView; } else if (typeof doc.parentWindow != UNDEF) { return doc.parentWindow; } else { throw module.createError("Cannot get a window object for node"); } } function getIframeDocument(iframeEl) { if (typeof iframeEl.contentDocument != UNDEF) { return iframeEl.contentDocument; } else if (typeof iframeEl.contentWindow != UNDEF) { return iframeEl.contentWindow.document; } else { throw module.createError("getIframeDocument: No Document object found for iframe element"); } } function getIframeWindow(iframeEl) { if (typeof iframeEl.contentWindow != UNDEF) { return iframeEl.contentWindow; } else if (typeof iframeEl.contentDocument != UNDEF) { return iframeEl.contentDocument.defaultView; } else { throw module.createError("getIframeWindow: No Window object found for iframe element"); } } // This looks bad. Is it worth it? function isWindow(obj) { return obj && util.isHostMethod(obj, "setTimeout") && util.isHostObject(obj, "document"); } function getContentDocument(obj, module, methodName) { va.........完整代码请登录后点击上方下载按钮下载查看
网友评论0