<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
ul {
list-style: none;
}
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-thumb {
background-color: #c1c1c1;
-webkit-border-radius: 6px;
border-radius: 6px;
}
::-webkit-scrollbar-track-piece {
background-color: #f4f6fa;
}
::-webkit-scrollbar-button {
display: none;
}
.self-dropdown-box {
display: inline-block;
width: 200px;
position: relative;
font-size: 14px;
color: #666;
margin: 20px 10px;
}
.self-dropdown-box .self-dropdown-title {
height: 30px;
border: 1px solid #ccc;
cursor: pointer;
border-radius: 2px;
padding: 0 12px;
line-height: 28px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
user-select: none;
position: relative;
padding-right: 24px;
}
.self-dropdown-box .self-dropdown-title .self-dorpdown-icon {
position: absolute;
right: 12px;
top: 12px;
width: 0;
height: 0;
border: 4px solid transparent;
border-top-color: #000;
transform: rotate(0deg);
transform-origin: 50% 30%;
transition: all 0.5s;
}
.self-dropdown-box.showPanel .self-dropdown-title .self-dorpdown-icon {
transform: rotate(180deg);
transform-origin: 50% 30%;
}
.self-dropdown-box .self-dropdown-panel {
position: absolute;
left: 0;
top: 31px;
width: 200px;
max-height: 200px;
overflow: auto;
border: 1px solid #ccc;
box-sizing: border-box;
border-radius: 0 0 2px 2px;
display: none;
z-index: 99;
}
.self-dropdown-box .self-dropdown-panel li {
padding: 6px 12px;
cursor: pointer;
transition: background-color .3s;
word-break: break-all;
}
.self-dropdown-box .self-dropdown-panel li:hover {
background: #f2f5fa;
}
</style>
</head>
<body ng-controller="testDropdown">
<div class="drop-test">
<drop-down selectval="dropdownSelectVal" dropdowndata="dropdownListObj.dropdownList" valChange="changeSelect()">
</drop-down>
<drop-down selectval="dropdownSelectVal2" dropdowndata="dropdownListObj2.dropdownList"
valChange="changeSelect()">
</drop-down>
</div>
</body>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
<script>
// 创建主模块
var myApp = angular.module('myApp', []);
// 创建controller
myApp.controller('testDropdown', ['$scope', '$timeout', function ($scope, $timeout) {
$scope.dropdownListObj = {
dropdownList: []
};
$timeout(function () {
// 模拟数据加载
$scope.dropdownListObj.dropdownList = ['数据1', '数据2', '数据3', '数据4', '数据5', '数据6', '数据7',
'数据8'
];
}, 1000);
$scope.dropdownSelectVal = '';
$scope.changeSelect = function () {
console.log($scope.dropdownSelectVal);
}
// 创建两个组件测试是否互相影响
$scope.dropdownSelectVal2 = '';
$scope.dropdownListObj2 = {
dropdownList: ['我们是第二组数据1,我的长度特别长长长长长长长长长长长长', '我们是第二组数据2', '我们是第二组数据3', '我们是第二组数据4',
'我们是第二组数据5', '我们是第二组数据6'
]
};
}]);
// 下拉框组件自定义指令
myApp.directive('dropDown', [function ($timeout) {
return {
restrict: 'E', // 指令采用元素展示
replace: true, // 模板内容对指令进行替换
transclude: true, // 开启 ng-transclude ,及将xxx 指令中间内容插入到模板有ng-transclude标识的元素中
scope: { // 与controller的交互,需要重点关注
selectval: '=', // 默认值, '=' 代表双向相应,及指令与controller交互方式
dropdowndata: '=', // 下拉面板数据
valChange: '&', // 选项变化时事件, 代表调用 controller 的方法
placeholder: '@', // 代表单向获取数据,
},
templateUrl: './dropdownTpl.html', // HTML模板
link: function ($scope, $element,
$attrs) { // scope 代表上述衍生的作用域,$element 代表绑定的元素,$attrs 代表绑定元素的属性
$scope.showPanel = false;
$scope.toggle = function () {
$scope.showPanel = !$scope.showPanel;
if ($scope.showPanel) {
$($element).find('.self-dropdown-panel').slideDown();
} else {
$($element).find('.self-dropdown-panel').slideUp();
}
};
$scope.clickitem = function (data) {
$scope.selectval = data;
$scope.showPanel = !$scope.showPanel;
if ($scope.showPanel) {
$($element).find('.self-dropdown-panel').slideDown();
} else {
$($element).find('.self-dropdown-panel').slideUp();
}
};
$scope.$watch('selectval', function (value) {
$scope.valChange();
});
// 点击空白部分让下拉面板收起
document.addEventListener('click', function (e) {
if ($element[0].contains(e.target)) {
return false;
}
$scope.showPanel = false;
// 解决双向数据绑定不生效
if (!$scope.$$phase) {
$scope.$apply();
}
$($element).find('.self-dropdown-panel').slideUp();
});
}
};
}]);
</script>
</html>
dropdownTpl.html 代码如下:
<div class="self-dropdown-box" ng-class="{'showPanel': showPanel }">
<div class="self-dropdown-title" ng-click="toggle()">
<span title="{{selectval}}" ng-bind="selectval"></span>
<span class="self-dorpdown-icon"></span>
</div>
<ul class="self-dropdown-panel">
<li ng-repeat="data in dropdowndata" ng-click="clickitem(data)">{{data}}</li>
</ul>
</div>