import template from "./Popover.html"; import style from "antd/lib/popover/style/index.css"; angular .module("esNgAntd") .directive("esPopover", function ($compile, $timeout, esNgAntd) { return { controllerAs: "esPopover", restrict: "E", transclude: true, replace: true, scope: { title: "@", content: "@", context: "=", placement: "@", getPopupContainer: "&", trigger: "@", }, template: template, controller: function ($scope, $element, $attrs) { this.getContext = function () { return $scope; }; $scope.state = { visible: false, content: $scope.content ? $scope.content : "", clickTarget: null, trigger: $scope.trigger || "hover", closing: false, }; $scope.myEvent = function () { setTimeout(() => { $scope.state.visible = false; $scope.$apply(); document.body.removeEventListener( "click", $scope.myEvent ); }, 0); }; $scope.handleClick = function () { if ($scope.state.trigger !== "click") { return; } if ($scope.state.visible === false) { // 气泡层(显示) $scope.state.visible = true; // 处理位置 $scope.handlePosition(); // 事件绑定 document.body.addEventListener("click", $scope.myEvent); } else { setTimeout(() => { $scope.state.visible = false; $scope.$apply(); document.body.removeEventListener( "click", $scope.myEvent ); }, 0); } }; $scope.showPopover = function () { // 气泡层(显示) $scope.state.visible = true; // 调整位置 $scope.handlePosition(); }; $scope.hidePopover = function () { $scope.state.closing = true; $timeout(function () { if ($scope.state.closing === false) { return; } $scope.state.visible = false; }, 100); }; $scope.onMouseEnter = function () { if ($scope.state.trigger !== "hover") { return; } if ($scope.state.closing === true) { $scope.state.closing = false; } $scope.showPopover(); }; $scope.onMouseLeave = function () { if ($scope.state.trigger !== "hover") { return; } $scope.hidePopover(); }; $scope.handlePosition = function () { setTimeout(function () { let popover = $scope.state.popover.querySelector(".ant-popover"); if ($scope.placement === "top") { popover.style["top"] = $scope.getTop(); } else if ($scope.placement === "bottom") { popover.style["top"] = $scope.getTop(); } popover.style.left = $scope.getLeft() + "px"; }, 0); }; $scope.getLeft = function () { let parent = $scope.getPopupContainer(); let popover = $scope.state.popover.querySelector(".ant-popover"); let target = $scope.state.target; if (parent) { return -( popover.clientWidth / 2 - target.clientWidth / 2 ); } else { let offset = esNgAntd.getOffset(target); return ( offset.left - (popover.clientWidth / 2 - target.clientWidth / 2) ); } }; $scope.getTop = function () { let parent = $scope.getPopupContainer(); let popover = $scope.state.popover.querySelector(".ant-popover"); let target = $scope.state.target; if (parent) { if ($scope.placement === "top") { return -popover.clientHeight + "px"; } else if ($scope.placement === "bottom") { } } else { let offset = esNgAntd.getOffset(target); if ($scope.placement === "top") { return offset.top - popover.clientHeight - 4 + "px"; } else if ($scope.placement === "bottom") { return offset.top + target.clientHeight + 4 + "px"; } } }; }, link: function ( $scope, $element, $attrs, $controllers, $transclude ) { esNgAntd.createStyle("ant-popover", style); $scope.state.target = $element[0]; let title = $scope.title ? `
${$scope.title}
` : ""; let content = `
${title}
`; let div = document.createElement("div"); if (typeof $scope.getPopupContainer() === "function") { $scope.state.popupContainer = $scope.getPopupContainer()(); } if (!$scope.state.popupContainer) { div.style.position = "absolute"; div.style.top = "0px"; div.style.left = "0px"; div.style.width = "100%"; div.innerHTML = content; document.body.appendChild(div); } else { $scope.state.popupContainer.appendChild(div); } div.addEventListener("click", function (event) { event.stopPropagation(); }); $scope.state.target.addEventListener("click", (e) => { e.stopPropagation(); }); $compile(div)($scope); div.querySelector(".ant-popover-inner-content").innerHTML = $scope.state.content; $compile(div.querySelector(".ant-popover-inner-content"))( $scope.$parent ); $scope.state.popover = div; }, }; });