angular组件实现bootstrap的popover气泡弹窗

自定义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;
}

项目布局:

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

明致成

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值