自定义popover组件HTML结构:
<div class="popover-modal" data-ng-show="isShow">
<div class="triangle"></div>
<div>
<div class="popover-header">
<div class="popover-title">
我是自定义popover标题
</div>
</div>
<div class="popover-body">
<div class="popover-content">
我是自定义popover主体
</div>
</div>
</div>
</div>
自定义popover指令js:
angular.module("popover.module",[])
.directive("popover",function(){
return {
restrict: "E",
scope: {
isShow: "=", //默认是否显示popover
showLocation: "=", //popover的位置:top,right,bottom,left
sourceObj: "=", //触发对象的left、top、width、height
},
templateUrl: $context+"popover/popover.html",
//link用来处理模板,与模板交互
link: function(scope,element,attr){
var target = element.children(".popover-modal");
var triangle = target.children(".triangle");
var top = 0;
var left = 0;
//获取popover的显示位置
switch(scope.showLocation){
case "bottom":
//如果在触发对象的下侧显示
//popover的top为触发对象的top+触发对象的height+1/2小三角的height
//popover的left为触发对象的left+1/2触发对象的width-1/2popover的width-1/2小三角的宽度
top = parseInt(scope.sourceObj.top)+parseInt(scope.sourceObj.height)+10;
left = parseInt(scope.sourceObj.left)+1/2*parseInt(scope.sourceObj.width)-1/2*target.css("width").split("px")[0]-10;
target.css("top", top+"px");
target.css("left", left+"px");
//小三角的方向是bottom
triangle.css("border-style","dashed dashed solid dashed");
triangle.css("border-color","transparent transparent #df2b2b transparent");
//小三角的top为-20
//小三角的left为1/2popover的宽度
triangle.css("top","-21px");
triangle.css("left", 1/2*target.css("width").split("px")[0]+"px");
break;
case "top":
//如果在触发对象的上侧显示
//popover的top为触发对象的top-popover的height-1/2小三角的height
//popover的left为触发对象的left+1/2触发对象的width-1/2popover的width-1/2小三角的宽度
top = parseInt(scope.sourceObj.top)-target.css("height").split("px")[0]-10;
left = parseInt(scope.sourceObj.left)+1/2*parseInt(scope.sourceObj.width)-1/2*target.css("width").split("px")[0]-10;
target.css("top", top+"px");
target.css("left", left+"px");
//小三角的方向是top
triangle.css("border-style","solid dashed dashed dashed");
triangle.css("border-color","#df2b2b transparent transparent transparent");
//小三角的bottom为-20
//小三角的left为1/2popover的宽度
triangle.css("bottom","-21px");
triangle.css("left", 1/2*target.css("width").split("px")[0]+"px");
break;
case "left":
//如果在触发对象的左侧显示
//popover的top为触发对象的top+1/2触发对象的height-1/2popover的height
//popover的left为触发对象的left-popover的width-1/2小三角的宽度
top = parseInt(scope.sourceObj.top)+1/2*parseInt(scope.sourceObj.height)-1/2*target.css("height").split("px")[0];
left = parseInt(scope.sourceObj.left) - target.css("width").split("px")[0]-10;
target.css("top", top+"px");
target.css("left", left+"px");
//小三角的方向是left
triangle.css("border-style","dashed dashed dashed solid");
triangle.css("border-color","transparent transparent transparent #df2b2b");
//小三角的top为1/2popover的height
//小三角的right为20
triangle.css("top",1/2*(target.css("height").split("px")[0]-20)+"px");
triangle.css("right", "-21px");
break;
case "right":
//如果在触发对象的右侧显示
//popover的top为触发对象的top+1/2触发对象的height-1/2popover的height
//popover的left为触发对象的left+触发对象的width+1/2小三角的宽度
top = parseInt(scope.sourceObj.top)+1/2*parseInt(scope.sourceObj.height)-1/2*target.css("height").split("px")[0];
left = parseInt(scope.sourceObj.left) + parseInt(scope.sourceObj.width)+10;
target.css("top", top+"px");
target.css("left", left+"px");
//小三角的方向是right
triangle.css("border-style","dashed solid dashed dashed");
triangle.css("border-color","transparent #df2b2b transparent transparent");
//小三角的top为1/2popover的height
//小三角的left为-20
triangle.css("top",1/2*(target.css("height").split("px")[0]-20)+"px");
triangle.css("left","-21px");
break;
default: break;
}
},
controller: function($scope){
}
};
});
自定义popover的css:
.popover-modal{
width: 200px;
border: 1px solid #827272;
background-color: #ffffff;
position: absolute;
border-radius: 4px;
}
.triangle{
position: absolute;
width:0;
height:0;
overflow:hidden;
font-size: 0;
line-height: 0;
border-width:10px;
}
-------------------------------------------------------------以下为使用自定义popover指令的例子----------------------------------------------------------------
html结构:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="./lib/css/bootstrap.min.css">
<link rel="stylesheet" href="./index.css">
<link rel="stylesheet" href="./popover/popover.css">
<script type="text/javascript" src="./lib/js/jquery.min.js"></script>
<script type="text/javascript" src="./lib/js/bootstrap.min.js"></script>
<script type="text/javascript" src="./lib/js/angular.min.js"></script>
<script>
var $context = document.location.href;
</script>
</head>
<body data-ng-app="index.module" data-ng-controller="indexController" style="position:relative;">
<button data-ng-mouseenter="showPopover()" data-ng-mouseout="showPopover()">点击弹窗</button>
<!-- popover指令 -->
<popover is-show="isShowPopover" show-location="showLocation"
source-obj="source"></popover>
<script type="text/javascript" src="./index.js"></script>
<script type="text/javascript" src="./popover/popover.js"></script>
</body>
</html>
js结构:
var appModal = angular.module("index.module",[
"popover.module"
]);
appModal.service("indexService",function(){
});
appModal.controller("indexController",["$scope","$document",
function($scope,$document){
$scope.showPopover = function(){
$scope.isShowPopover = !$scope.isShowPopover;
};
/**
* 获取要传入popover弹窗的属性
*/
$scope.init = function(){
$scope.isShowPopover = false; //默认是否显示popover
$scope.showLocation = "bottom"; //popover的位置:top,right,bottom,left
$scope.source = { //触发对象的left、top、width、height
"left": 0,
"top": 0,
"height": 0,
"width": 0
};
var sourceBtn = angular.element("button");
$scope.source.left = sourceBtn.css("left").split("px")[0];
$scope.source.top = sourceBtn.css("top").split("px")[0];
$scope.source.height = sourceBtn.css("height").split("px")[0];
$scope.source.width = sourceBtn.css("width").split("px")[0];
};
$document.ready($scope.init);
}]);
css结构:
button{
position: absolute;
left: 100px;
top: 100px;
}
项目布局: