angular自定义组件popbox练习日志(一)
来源:互联网 发布:手机淘宝源码 编辑:程序博客网 时间:2024/05/20 20:58
angular用了有一段时间了,基本的使用问题已经很熟练了,但是angular组件的缺乏让开发的时候比较头疼,没有合适的组件只能妥协,使用基本的使用方法去实现本来已经设计好的比较好的交互体验,这样的结果就是交互体验打了折扣。
言归正传,这次的自定义组件的目标是弹出框,之所以要研究弹出框是因为弹出框应该算是比较有代表性的组件之一,需要处理的问题包含定位、数据传递、DOM操作、事件处理等等,把这个搞定了,基本做其它的各类组件开发可以上手了。
终极目标达到类似下面的效果,要求:弹出框内容可定义,组件位置与事件触发源位置关联。
下面开工
阶段目标:
本篇要解决的问题是弹出相应的层,并解决定位问题、大小问题、内容填充的自定义、鼠标背景事件(鼠标在其它地方点击的时候自动关闭弹出框)问题。
step1:定义内个ng-template
//定义popbox的父容器 <script type="text/ng-template" id="popbox.html"> <div class='popbox'> </div> </script> //定义内容模板,随便放了点东西 <script type="text/ng-template" id="labels.html"> <h3>labels</h3> </script> //定义另外一个内容模板,用来测试popbox自定义内容填充 <script type="text/ng-template" id="labels1.html"> <h3>另外一个labels</h3> </script>
step2:定义一个factory,用来计算事件源的位置坐标(从一个网站“偷”来的,部分代码反混淆了)
angular.module("ui.bootstrap.position", []).factory("$position", ["$document", "$window", function ($document, $window) { function getStyle(element, styleName) { return element.currentStyle ? element.currentStyle[styleName] : $window.getComputedStyle ? $window.getComputedStyle(element)[styleName] : element.style[styleName]; } function isStatic(element) { return "static" === (getStyle(element, "position") || "static") } var e = function (b) { for (var c = $document[0], e = b.offsetParent || c; e && e !== c && isStatic(e) ;) e = e.offsetParent; return e || c }; return { position: function (element) { var offset = this.offset(element), parentOffset = { top: 0, left: 0 }, f = e(element[0]); f != $document[0] && (parentOffset = this.offset(angular.element(f)), parentOffset.top += f.clientTop - f.scrollTop, parentOffset.left += f.clientLeft - f.scrollLeft); var g = element[0].getBoundingClientRect(); return { width: g.width || element.prop("offsetWidth"), height: g.height || element.prop("offsetHeight"), top: offset.top - parentOffset.top, left: offset.left - parentOffset.left } }, offset: function (c) { var d = c[0].getBoundingClientRect(); return { width: d.width || c.prop("offsetWidth"), height: d.height || c.prop("offsetHeight"), top: d.top + ($window.pageYOffset || $document[0].documentElement.scrollTop), left: d.left + ($window.pageXOffset || $document[0].documentElement.scrollLeft) } }, positionElements: function (a, b, c, d) { var e, f, g, h, i = c.split("-"), j = i[0], k = i[1] || "center"; e = d ? this.offset(a) : this.position(a), f = b.prop("offsetWidth"), g = b.prop("offsetHeight"); var l = { center: function () { return e.left + e.width / 2 - f / 2 }, left: function () { return e.left }, right: function () { return e.left + e.width } }, m = { center: function () { return e.top + e.height / 2 - g / 2 }, top: function () { return e.top }, bottom: function () { return e.top + e.height } }; switch (j) { case "right": h = { top: m[k](), left: l[j]() }; break; case "left": h = { top: m[k](), left: e.left - f }; break; case "bottom": h = { top: m[j](), left: l[k]() }; break; default: h = { top: e.top - g, left: l[k]() } } return h } } }]);
step3:定义$popbox 使用provider,
angular.module("ui.bootstrap.popbox", []).provider("$popbox", function () { this.$get = ["$document", "$templateCache", "$compile", "$rootScope", "$position", function ( $document, $templateCache, $compile, $rootScope, $position) { function popbox(options) { var _this = this; this.options = angular.extend({}, options); var bodyEl = $document.find("body"); var dom = angular.element($templateCache.get("popbox.html")); dom.append($templateCache.get(this.options.templateUrl)); this.elmentEL = dom; this.handleBackDropClick = function ($event) { for (var element = $event.target, notpopbox = true; element;) { if ($(element).hasClass("popbox")) { notpopbox = !1; break } element = element.parentNode } if (notpopbox) _this.close(); }; this.close = function () { _this.elmentEL.remove(); }; this.open = function ($event, $scope) { $(".popbox").each(function () { $(this).scope().popbox.close() }) var sourcePosition = $position.position($($event.target)); this.elmentEL.css("top", sourcePosition.top + sourcePosition.height + "px"); this.elmentEL.css("left", sourcePosition.left + "px"); this.elmentEL.css("width", _this.options.width + "px"); this.elmentEL.css("height", _this.options.height + "px"); bodyEl.append(this.elmentEL); $compile(this.elmentEL)($scope); $document.bind("mousedown", this.handleBackDropClick); }; } return { popbox: function (options) { return new popbox(options) } }; }]; });
step4:定义module依赖关系,初始化app对象
angular.module("ui.bootstrap", ["ui.bootstrap.position", "ui.bootstrap.popbox"]); //定义了上面一行后,app初始化时只需要定义依赖ui.bootstrap就可以了。 var app = angular.module('app', ['ngRoute', 'ngResource', "chart.js", "ui.bootstrap"]);
step5:定义controll
app.controller("dashbordCtl", function ($scope, $http, $location, $popbox) { $scope.js_openlabel = function ($event) { $popbox.popbox({ templateUrl: "labels.html", width: 100, height: 300 }).open($event, $scope); } $scope.js_openlabel1 = function ($event) { $popbox.popbox({ templateUrl: "labels1.html", width: 200, height: 400 }).open($event, $scope); } //这里定义了两个方法用来打开弹出框,注意两个方法中使用templateUrl是不一样的。 });
step6:html标签
<body ng-controller="dashbordCtl"> <h4>测试popbox</h4> 给按钮几个left <button ng-click="js_openlabel($event)">popbox</button> <br /> <br /> <br /> <button ng-click="js_openlabel1($event)">popbox</button></body>
ok下面可以看效果了。
0 0
- angular自定义组件popbox练习日志(一)
- 日志(一)--组件
- Angular 2 中的组件(一)
- 自定义组件(一)
- 一,Angular自定义指令
- VCL:自定义组件(一)
- Android自定义组件(一)
- angular随记(一)自定义指令
- angular中自定义组件实现双向绑定
- Python 日志组件学习(一)
- 自定义View练习(一)饼状图
- 自定义View练习一
- 自定义ViewGroup练习一
- Android自定义组件(一)(二)
- 自定义使用Adapter的组件(一)
- (一)NotBoringActionBar之自定义组件ParallaxImageView
- android中自定义组合组件(一)
- angular-directive(组件化)
- Android SDK自定义更新
- 【16】GridView——网格视图
- 《Effective C++》学习笔记——条款38
- hadoop2.x源码编译
- flume agent arvo传数据
- angular自定义组件popbox练习日志(一)
- BZOJ-3670 动物园 KMP+奇怪的东西
- libgdx [Actor]
- javascript字符串截取
- 设置nginx,访问根目录
- cocos2d-x LUA项目设置记录
- C++注意点(第一部分)
- 几个好用的makefile 几乎可以不用修改
- ios-UI控件精讲之【4】-UIScrollView