angular js 实现鼠标移入出现弹窗,并可以复制和上拉滑动弹窗内容

239 阅读1分钟

记录一下这个是因为,本来是写后端代码,但是要写前端的一些交互,搞这个搞了好久,不容易,记录一下。

最终实现的效果如下图:

自定义有下拉滚动条的效果

image.png

并且浮窗中的内容是可以进行复制的。

没有下拉滚动条的效果

image.png

这种浮窗中的内容则复制不了。

实现代码

原理

原理是使用angularjs 的自定义指令,将自定义的指令应用到需要提示框的元素上面,然后将弹窗添加到 body 上,添加上样式,然后显示。

js 和 html 代码
  • html 代码
<td class="content-name content-break text-l textOmission" style="max-width: 200px;"  id="url-{{$index}}" suspension-tip="{{data['url']}}" open-scroll="true">{{data['url']}}</td>
  • js 代码
.directive('suspensionTip', ['$rootScope', function($rootScope) {
    return {
        restrict: 'A',
        scope: {
            contentWidth: '=?', // 宽度
            addTop:'=?',  // 配置是否需要添加一个高度
            addLeft:'=?', // 配置离左边的距离
            openScroll:'=?' // 是否需要下拉滚动
        },
        link: function(scope, element, attrs) {

            var showTooltipTimeOut = undefined;
            scope.isRemoveTip = true;
            scope.isLeaveText = false;
            element.hover(
                function() {
                    showTooltip();
                },
                function() {
                    if (!attrs.openScroll){
                        $('#'+scope.tooltipId).remove();
                    }else{
                        showTooltipTimeOut = setTimeout(function() {
                            if (scope.isRemoveTip && !scope.isLeaveText){
                                $('#'+scope.tooltipId).remove();
                            }
                        }, 500);
                    }
                }
            );

            function showTooltip() {
                scope.tooltipContent = attrs.suspensionTip.toString();
                if (scope.tooltipContent === '' || scope.tooltipContent === undefined) {
                    return;
                }
                scope.tooltipId = attrs.id + "-tooltip";
                if (attrs.openScroll){
                    if ($rootScope.beforeElementId != undefined && $rootScope.beforeElementId != scope.tooltipId) {
                        $('#' + $rootScope.beforeElementId).remove();
                    }
                    $rootScope.saveBeforeId = function (id) {
                        $rootScope.beforeElementId = id;
                    }
                    $rootScope.saveBeforeId(scope.tooltipId);
                }
                scope.tooltipReport = $('<div class="tooltipReport" id="' + scope.tooltipId + '"><span>' + scope.tooltipContent + '</span></div>');
                // 获取当前元素的屏幕位置
                let elementOffset = element.offset();
                let elementWidth = element.outerWidth();
                let elementTop = elementOffset.top;
                let elementLeft = elementOffset.left;

                let contentWidth = attrs.contentWidth != undefined ? attrs.contentWidth : 250;
                let tooltipLeft = elementLeft + (elementWidth / 2) - contentWidth/2;

                elementTop = elementTop + (attrs.addTop !=undefined ? parseInt(attrs.addTop) : 0);
                tooltipLeft = tooltipLeft + (attrs.addLeft !=undefined ? parseInt(attrs.addLeft) : 0);

                // 设置悬浮框的样式和位置
                scope.tooltipReport.css({
                    'padding': '10px 15px',
                    'position': 'absolute',
                    'z-index': '99999',
                    'width': contentWidth+'px',
                    'left': tooltipLeft + 'px',
                    'top': elementTop + 'px',
                    'transform': 'translateY(calc(-100% - 12px))',
                    'font-size': '14px',
                    'font-weight': '500',
                    'color': '#333333',
                    'background': '#FFFFFF',
                    'box-shadow': '0px 4px 20px 0px rgba(0,0,0,0.15)',
                    'border-radius': '4px',
                    'opacity': '1',
                    'border': '1px solid #D7D8DE',
                    'text-align':'center',
                    'max-height':attrs.openScroll? '250px' :'100px',
                    'white-space': 'pre-wrap',
                    'word-wrap':'break-word',
                    'word-break':'break-all',
                    'overflow': attrs.openScroll?'visible':'auto',
                    'overflow-x': 'hidden',
                });
                // 将悬浮框添加到页面中
                $('body').append(scope.tooltipReport);
                if (attrs.openScroll){
                    $('#'+scope.tooltipId).hover(
                        function() {
                            scope.isRemoveTip = false;
                            if (showTooltipTimeOut != undefined)
                                clearTimeout(showTooltipTimeOut);
                        },
                        function() {
                            scope.isRemoveTip = true;
                            $('#'+scope.tooltipId).remove();
                        }
                    );
                    // showTooltipTimeOut = setTimeout(function() {
                    //     $('#'+scope.tooltipId).remove();
                    // }, 500);
                }
            }
        }
    };
}])

使用的时候将这个指令,添加到module上。如:

angular.module('backOffice.report', ['app.service']).controller('reportCtrl', ['$scope', '$rootScope', '$window', '$sce', '$http', '$translate', '$location', 'localStorageService', 'httpService', '$timeout', '$compile', '$filter', '$stateParams', 'redirectService', 'ModalService', 'sharedProperties', function ($scope, $rootScope, $window, $sce, $http, $translate, $location, localStorageService, httpService, $timeout, $compile, $filter, $stateParams, redirectService, ModalService, sharedProperties) {

...
}
]).directive();

css 的样式:

.textOmission {
    text-overflow: ellipsis;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.content-name { 
    text-align: left; 
    font-size: 14px;
    font-family: Arial-Regular, Arial;
    font-weight: 400;
    line-height: 16px;
    text-align: center
 }
.content-break {
    word-break: break-all;
}
.text-l {
    text-align: left !important;
}