封装一个通用的PopupWindow

上篇文章是关于建造者设计模式的,今天顺便封装一个通用的 PopupWindow 来实践一下, 同时也方便以后使用 PopupWindow,本文将从下面几个方面来介绍 PopupWindow 及其封装,具体如下: 概述常用方法基本使用封装 PopupWindow使用封装后的PopupWindow显示效果概述PopupWindow 表示一个弹窗,类似于 AlertDialog,相较 AlertDialog 来说 PopupWindow 使用起来更灵活,可有任意指定要显示的位置,当然能够灵活的使用必然在某一层面有所牺牲,如 PopupWindow 相较 AlertDialog 没有默认的布局,每次都得专门创建弹窗的布局,这一点来说 AlertDialog 就比较方便了,所以在开发中没有最好的解决方案,要根据具体的需求选择最合适的解决方案。 常用设置PopupWindow 的创建,具体如下: //构造方法 public PopupWindow (Context context) public PopupWindow(View contentView) public PopupWindow(View contentView, int width, int height) public PopupWindow(View contentView, int width, int height, boolean focusable) PopupWindow 的常用属性设置,具体如下: //设置View(必须) window.setContentView(contentView); //设置宽(必须) window.setWidth(WindowManager.LayoutParams.MATCH_PARENT); //设置高(必须) window.setHeight(WindowManager.LayoutParams.WRAP_CONTENT); //设置背景 window.setBackgroundDrawable(new ColorDrawable(Color.GRAY)); //设置PopupWindow之外的触摸事件 window.setOutsideTouchable(true); //设置PopupWindow消失的监听器 window.setOnDismissListener(this); //设置PopupWindow上的触摸事件 window.setTouchable(true); //设置PopupWindow弹出动画 window.setAnimationStyle(R.style.PopupWindowTranslateTheme);PopupWindow 的显示有两种设置方式,一种是基于坐标,另一种是基于某个 View ,具体如下: ...

June 1, 2019 · 3 min · jiezi

BOM编程-cookie的赋值过期时间path路径封装以及与Storage的区别

cookie 不是window下面的属性,它是document下面的属性,cookie有一套专门的取值与赋值方法,与localStorage,sessionStorage不同特性cookie在document下面cookie可以设置一个时间自动去清除缓存,cookie如果不设置清除时间,则关闭浏览器自动清除。cookie它可以跨页面,但是不可以跨path路径(子路径可以取到父级路径的) ,前提是同域赋值新建一个文件夹,在文件夹下新建一个html页面 cookie3.html 和一个名为path2的文件夹在path2文件夹下新建 cookie4.html先看一下cookie: 赋值 // 普通赋值document.cookie = 'userName=Aihh' // 带过期时间 10s后清除cookievar d = new Date();d.setTime(Date.now() + 10*1000);document.cookie = 'userName=Aihh;Expires=' + d.toUTCString(); // 带访问路径document.cookie="age=18;path=/path2";注意: 设置过期时间使用的是0时区的时间,而我们北京时间是+8区的时间,所以这个时候要调用 toUTCString() 转换为标准时区的时间;path=/path2 设置只有在路径path2下面的网页才能访问(前提是同域),如果是 path=/ 则说明是根路径,任何同域页面都可以访问。赋值后打开 Application 查看 cookie 普通赋值 带过期时间,设置10s后过期 带路径,设置只有在路径path2下面的网页才能访问(前提是同域) 这个时候发现在 cookie3.html 找不到这个cookie 再打开path2下面的 cookie4.html ,就会看到这个cookie 封装cookie 属性和值是用 = 连接,属性之间用 ; 分隔,根据这个特点进行封装var CookieHelper = { addCookie: function (cookieName, cookieValue, exMinutes, cookiePath) { // 第三/四个参数,按需传参 var str = cookieName + "=" + cookieValue; if (arguments.length == 3) { let d = new Date(); d.setTime(Date.now() + exMinutes*60*1000); // 过期单位这里设置为分钟 str += ";Expires=" + d.toUTCString(); } if (arguments.length == 4) { str += ";path=" + cookiePath; } document.cookie = str; }, getCookie: function (cookieName) { var cookieArr = document.cookie.split(";"); for (let i in cookieArr) { var arr = cookieArr[i].split("="); if (arr[0].trim() == cookieName) { return arr[1]; } } }, removeCookie: function (cookieName) { document.cookie = cookieName + "= ;Expires=" + (new Date()).toUTCString(); }}与 localStorage,sessionStorage 的区别localStorage,sessionStorage在window下面, cookie在document下面localStorage要手动清除,sessionStorage关闭浏览器自动清除,而cookie可以设置一个时间自动去清除,cookie如果不设置清除时间,则关闭浏览器自动清除。localStorage可以跨同域页面,sessionStorage只能跨父子页面(通过 open() 打开的页面),cookie它可以跨页面,但是不可以跨path路径(子路径可以取到父级路径的) 。他们都不能跨域

April 30, 2019 · 1 min · jiezi

读完这篇文章,就能拥有炫同事一脸的超能力:JavaScript 魔幻代理

前言什么是代理?上小学的时候,李小红来你家叫你出去玩,第一个回应的不是你自己,是你妈:“王小明在家写作业,今天不出去!”上中学的时候,赵二虎带着小弟们放学在校门口等着揍你,走在前面的不是你自己,是二虎他爸:“考试没及格还学会装黑社会了!”拎起二虎就是一顿胖揍。上了大学,躺在宿舍里的床上,好饿。出门买饭并交代好不要葱蒜多放辣最后还直接端到床上的不是你自己,是快递小哥。这些都是代理。什么是 JavaScript 代理?用官方的洋文来说,是 Proxy:The Proxy object is used to define custom behavior for fundamental operations (e.g. property lookup, assignment, enumeration, function invocation, etc).通过 Proxy 我们可以拦截并改变一个对象的几乎所有的根本操作,包括但不限于属性查找、赋值、枚举、函数调用等等。在生活中,通过代理我们可以自动屏蔽小红的邀请、自动赶走二虎的威胁、自动买好干净的饭端到床上。在 JavaScript 世界里,代理也可以帮你做类似的事情,接下来让我们一起琢磨一番。初识代理:Hello World以小学经历为例子,心里是喜欢小红的,于是我们定义:const me = { name: ‘小明’, like: ‘小红’ }这个时候如果调用 console.log(me.like),结果必然是 小红。然而生活并不是这样,作为一个未成年人,总是有各种的代理人围绕在你身边,比如这样:const meWithProxy = new Proxy(me, { get(target, prop) { if (prop === ’like’) { return ‘学习’; } return target[prop]; }});这个时候如果调用 console.log(me.like) 依然是 小红 ,因为真心不会说谎。但当我们调用 console.log(meWithProxy.like) 的时候,就会可耻的输出 学习 ,告诉大家说我们喜欢的是 学习 。小试牛刀:不要停止我的音乐刚才我们简单了解了代理能够拦截对象属性的获取,可以隐藏真实的属性值而返回代理想要返回的结果,那么对于对象属性的赋值呢?让我们一起来看看。假设你正在听音乐:const me = { name: ‘小明’, musicPlaying: true }此时如果我们执行 me.musicPlaying = false 这样就轻而易举地停止了你的音乐,那么如果我们挂上代理人:const meWithProxy = new Proxy(me, { set(target, prop, value) { if (prop === ‘musicPlaying’ && value !== true) { throw Error(‘任何妄图停止音乐的行为都是耍流氓!’); } target[prop] = value; }});这时候如果我们执行 me.musicPlaying = false,就会被毫不留情地掀了桌子:> meWithProxy.musicPlaying = falseError: 任何妄图停止音乐的行为都是耍流氓! at Object.set (repl:4:13)>释放魔法:封装全宇宙所有 RESTful API现在我们已经知道通过 Proxy 可以拦截属性的读写操作,那然后呢?没什么用?仅仅是拦截属性的读写操作,的确没有太大的发挥空间,或许可以方便的做一些属性赋值校验工作等等。但是,或许你还没有意识到一个惊人的秘密:Proxy 在拦截属性读写操作时,并不在乎属性是否真的存在!那么,也就是说:利用 Proxy,我们可以拦截并不存在的属性的读取。再进一步思考:利用 Proxy,我们可以在属性读取的那一瞬间,动态构造返回结果。然而,属性并不局限于字符串、布尔值,属性可以是对象、函数、任何东西。至此,你想到了什么?没想到?不要紧!根据刚才的分析,让我们一起通过下面 17 行代码,来封装全宇宙所有的 RESTful API !import axios from ‘axios’;const api = new Proxy({}, { get(target, prop) { const method = /^[a-z]+/.exec(prop)[0]; const path = ‘/’ + prop .substring(method.length) .replace(/([a-z])([A-Z])/g, ‘$1/$2’) .replace(/$/g, ‘/$/’) .toLowerCase(); return (…args) => { // <—— 返回动态构造的函数! const url = path.replace(/$/g, () => args.shift()); const options = args.shift() || {}; console.log(‘Requesting: ‘, method, url, options); return axios({ method, url, …options }); } }});定义了 api 这个代理之后,我们就可以像下面这样调用:api.get()// GET /api.getUsers()// 获取所有用户// GET /usersapi.getUsers$Books(42)// 获取 ID 为 42 的用户的所有书籍// GET /users/42/booksapi.getUsers$Books(42, { params: { page: 2 } })// 获取 ID 为 42 的用户的所有书籍的第二页// GET /users/42/books?page=2api.postUsers({ data: { name: ‘小明’ } })// 创建名字为 小明 的用户// POST /users Payload { name: ‘小明’ }以上所有的函数都在你调用的那一瞬间,通过代理人的魔法之手动态生成,供我们随意取用。简洁、优雅,哇~ 真是太棒啦!终极魔幻:通读代理人的魔法秘笈到此,我们仅仅使用 Proxy 改造了对象的属性获取、赋值操作,而对于 Proxy 来说,只是冰山一角。Proxy 的基本语法如下:new Proxy(target, handler)其中 target 是即将被代理的对象(比如:想要出门找小红玩耍的 me),handler 就是代理的魔法之手,用来拦截、改造 target 的行为。对于 handler 对象,我们刚才仅仅用到了 get、set 函数,而实际上一共有 13 种可代理的操作:handler.getPrototypeOf()在读取代理对象的原型时触发该操作,比如在执行 Object.getPrototypeOf(proxy) 时。handler.setPrototypeOf()在设置代理对象的原型时触发该操作,比如在执行 Object.setPrototypeOf(proxy, null) 时。handler.isExtensible()在判断一个代理对象是否是可扩展时触发该操作,比如在执行 Object.isExtensible(proxy) 时。handler.preventExtensions()在让一个代理对象不可扩展时触发该操作,比如在执行 Object.preventExtensions(proxy) 时。handler.getOwnPropertyDescriptor()在获取代理对象某个属性的属性描述时触发该操作,比如在执行 Object.getOwnPropertyDescriptor(proxy, “foo”) 时。handler.defineProperty()在定义代理对象某个属性时的属性描述时触发该操作,比如在执行 Object.defineProperty(proxy, “foo”, {}) 时。handler.has()在判断代理对象是否拥有某个属性时触发该操作,比如在执行 “foo” in proxy 时。handler.get()在读取代理对象的某个属性时触发该操作,比如在执行 proxy.foo 时。handler.set()在给代理对象的某个属性赋值时触发该操作,比如在执行 proxy.foo = 1 时。handler.deleteProperty()在删除代理对象的某个属性时触发该操作,比如在执行 delete proxy.foo 时。handler.ownKeys()在获取代理对象的所有属性键时触发该操作,比如在执行 Object.getOwnPropertyNames(proxy) 时。handler.apply()在调用一个目标对象为函数的代理对象时触发该操作,比如在执行 proxy() 时。handler.construct()在给一个目标对象为构造函数的代理对象构造实例时触发该操作,比如在执行new proxy() 时。对于以上 13 种可代理的操作,还需要读者自行研究并实践方可踏上终极魔幻之旅。同学,我看好你。参考链接:Proxy - JavaScript | MDNHow to use JavaScript Proxies for Fun and Profit – DailyJS – Medium文 / 王小明本文已由作者授权发布,版权属于创宇前端。欢迎注明出处转载本文。本文链接:https://knownsec-fed.com/2018…想要订阅更多来自知道创宇开发一线的分享,请搜索关注我们的微信公众号:乐趣区。欢迎留言讨论,我们会尽可能回复。欢迎点赞、收藏、留言评论、转发分享和打赏支持我们。打赏将被完全转交给文章作者。感谢您的阅读。 ...

September 20, 2018 · 2 min · jiezi