UNPKG

zent

Version:

一套前端设计语言和基于React的实现

97 lines (75 loc) 2.97 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.getNodeFromSelector = getNodeFromSelector; exports.prepareNode = prepareNode; exports.openPortal = openPortal; exports.destroyPortal = destroyPortal; var _classnames = require('zent-utils/classnames'); var _classnames2 = _interopRequireDefault(_classnames); var _react = require('react'); var _reactDom = require('react-dom'); var _reactDom2 = _interopRequireDefault(_reactDom); var _isFunction = require('zent-utils/lodash/isFunction'); var _isFunction2 = _interopRequireDefault(_isFunction); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function createContainerNode(parent) { var div = document.createElement('div'); return parent.appendChild(div); } function removeNodeFromDOMTree(node) { var parentNode = node.parentNode; if (parentNode) { parentNode.removeChild(node); } } function getNodeFromSelector(selector) { var node = typeof selector === 'string' ? document.querySelector(selector) : selector; return node || document.body; } function prepareNode(node, prefix, className, css) { node.className = (0, _classnames2['default'])(prefix + '-portal', className); node.style.cssText = Object.keys(css || {}).map(function (k) { return k + ': ' + css[k]; }).join('; '); } function openPortal(props) { props = props || this.props; // 确保container存在,这个container是必须的,因为React的render会覆盖这个节点下的所有东西。 var node = this.node; if (!node) { var _props = props, selector = _props.selector, prefix = _props.prefix, className = _props.className, css = _props.css; var parentNode = getNodeFromSelector(selector); this.node = node = createContainerNode(parentNode); prepareNode(node, prefix, className, css); } // 这个API虽然是unstable,但是现在实现portal只能用它,如果用ReactDOM.render会导致 // context失效。 var _props2 = props, children = _props2.children; _reactDom2['default'].unstable_renderSubtreeIntoContainer(this, _react.Children.only(children), node); } function destroyPortal(callback) { var _this = this; var node = this.node; if (node) { // React不支持在event handler中unmount组件,会引起问题。Portal的使用场景很容易出现 // 这种情况,比如在portal内部按了关闭按钮关掉portal。setTimeout的作用是把unmount放到下一个tick // 中去做。 // // Invariant Violation: React DOM tree root should always have a node reference. // https://github.com/facebook/react/issues/2605 // https://github.com/facebook/react/issues/3298 setTimeout(function () { _reactDom2['default'].unmountComponentAtNode(node); removeNodeFromDOMTree(node); _this.node = undefined; (0, _isFunction2['default'])(callback) && callback(); }, 0); } }