深圳网站开发外包公司深圳游戏公司

diannao/2026/1/21 23:52:34/文章来源:
深圳网站开发外包公司,深圳游戏公司,Wordpress 收录提交,如何利用织梦cms做企业网站本文由尚妆前端开发工程师欲休撰写 本文发表于尚妆博客#xff0c;欢迎订阅#xff01; 移动端开发在某些场景中有着特殊需求#xff0c;如为了提高用户体验和加快响应速度#xff0c;常常在部分工程采用SPA架构。传统的单页应用基于url的hash值进行路由#xff0c;这种实… 本文由尚妆前端开发工程师欲休撰写 本文发表于尚妆博客欢迎订阅 移动端开发在某些场景中有着特殊需求如为了提高用户体验和加快响应速度常常在部分工程采用SPA架构。传统的单页应用基于url的hash值进行路由这种实现不存在兼容性问题但是缺点也有--针对不支持onhashchange属性的IE6-7需要设置定时器不断检查hash值改变性能上并不是很友好。 而如今在移动端开发中HTML5规范给我们提供了一个History接口使用该接口可以自由操纵历史记录。本文并不详细介绍History接口而是探究History接口如何影响浏览器历史堆栈并且利用这个规律应用到具体的实际业务中提出两种历史记录保存策略使路由逻辑更清晰让SPA更容易。 History API回顾 HTML5 History API包括2个方法history.pushState()和history.replaceState()和1个事件window.onpopstate。 pushState history.pushState(stateObject, title, url)包括三个参数。 第一个参数用于存储该url对应的状态对象该对象可在onpopstate事件中获取也可在history对象中获取。 第二个参数是标题目前浏览器并未实现。 第三个参数则是设定的url。一般设置为相对路径如果设置为绝对路径时需要保证同源。 pushState函数向浏览器的历史堆栈压入一个url为设定值的记录并改变历史堆栈的当前指针至栈顶。 在这里笔者使用历史堆栈和当前指针用以说明浏览器对历史记录的管理策略。文档中并没有使用这样的词汇笔者为了更形象的介绍接口对浏览器历史记录的影响使用这样的描述如有不当之处请及时指出不过目前以这套模型为基础的逻辑实现中并未出现悖论。 replaceState 该接口与pushState参数相同含义也相同。唯一的区别在于replaceState是替换浏览器历史堆栈的当前历史记录为设定的url。需要注意的是replaceState不会改动浏览器历史堆栈的当前指针。 onpopstate 该事件是window的属性。该事件会在调用浏览器的前进、后退以及执行history.forward、history.back、和history.go触发因为这些操作有一个共性即修改了历史堆栈的当前指针。在不改变document的前提下一旦当前指针改变则会触发onpopstate事件。 History API与业务实践 最常见的单页应用场景列表页、商品详情页以及其内部的其他链接入口如图片页、评论页及其推荐其他商品详情页。以上提到的已经涉及到了4个单独业务逻辑页面推荐的商品可复用商品详情页逻辑分别是列表、详情、图片详情和评论。将这4个页面合并到一个页面中这就是最简单的SPA。为了用户的良好体验必须设计合理的交互逻辑最直观的就是浏览器或手机app、微信公众号的后退和前进必须合乎业务逻辑特点。因此这就涉及到了History API的使用也牵扯到浏览器的历史记录管理。 上图为具体的逻辑示意图。在列表页点击其中一个商品这里是商品1进入详情页。详情页包括了该商品的轮播图、商品的图片详情入口、评论入口和推荐的其他商品入口。接下来进行如下操作进入图片详情页后退至详情页再进入评论页后退至商品1详情页再由推荐商品入口进入商品9详情页同样在商品9详情页进入图片详情页和评论页再后退至商品9详情页由推荐商品入口进入商品34详情页再进行类似操作。最后保证在商品34图片详情页或评论页可以顺利后退至最初的商品列表页。 上文中加粗的“后退”意味着使用浏览器后退按钮或者使用手机自带的返回再或者使用页面上提供的后退按钮。 这样一个很细小的需求但是一旦真正放手去做却不是那么容易。仅仅根据History API的2个函数和1个事件去盲目的尝试实现这属于盲人摸象鲁棒性不高。不清楚浏览器的历史记录管理策略不了解当前页面的历史记录数量此种情况若要实现上述场景就有些麻烦。所以在具体动手写业务代码之前需要搞懂History的pushState和replaceState具体如何影响历史记录栈。 探究浏览器历史记录策略与History API的关系 由于浏览器并未针对每个页面的历史记录提供具体访问的接口因此所有的测试都是黑盒。但是在移动端的中大都是webkit内核其webcore的具体实现也都相近因此该节得出的结论完全可以在移动端使用。 尽管无法访问当前页的历史记录栈但是浏览器却提供了history.length属性它标明了当前历史记录栈的个数。该值会帮助我们更好地分析History API对历史记录栈的影响。 上图为测试实例。其中白色箭头意味着点击该链接并执行pushState操作即操作1黑色箭头则执行浏览器后退红色的圆点为历史记录栈中的当前指针而每个项则为历史记录栈历史记录的个数则为其子项的数量。 初始在第一个搜索列表页执行操作1后历史堆栈数量增加当前指针上移一位至26788.html同理在执行3次操作1历史堆栈递增3个当前指针仍在栈顶即78099.html此后进行浏览器后退历史堆栈数量不变当前指针下移一位至8819.html在此处再执行操作1栈顶元素改变当前指针移至栈顶历史堆栈数量不变继续执行操作1栈顶元素改变指针移至栈顶历史堆栈数量加一执行浏览器后退栈顶元素不变指针下移一位至8128.html历史堆栈数量不变执行浏览器后退栈顶元素不变指针下移一位至8819.html历史堆栈数量不变执行浏览器后退栈顶元素不变指针下移一位至8128.html历史堆栈数量不变执行浏览器后退栈顶元素不变指针下移一位至26788.html历史堆栈数量不变执行操作1栈顶元素变为9721.html指针上移至栈顶历史堆栈数量变为3执行操作1栈顶元素变为8387.html指针上移至栈顶历史堆栈数量变为4执行浏览器后退栈顶元素不变指针下移一位至9721.html历史堆栈数量不变执行浏览器后退栈顶元素不变指针下移一位至26788.html历史堆栈数量不变执行浏览器后退栈顶元素不变指针下移一位至search.html历史堆栈数量不变执行操作1栈顶元素变为xxx.html指针上移至栈顶历史堆栈数量变为2... 至此实验结束。虽然这里仅仅列出了这一个测试用例但是其实笔者做了更多更复杂的测试并且平台涉及了pc和移动端的浏览器、微信和原生webview结果都一样。这一系列测试说明了很多问题总结之一句话则是 **浏览器针对每个页面维护一个History栈。执行pushState函数可压入设定的url至栈顶同时修改当前指针当执行back操作时history栈大小并不会改变history.length不变仅仅移动当前指针的位置若当前指针在history栈的中间位置非栈顶此时执行pushState会改变history栈的大小。总结pushState的规律可发现当前指针在history栈顶部时执行pushState会增加history栈大小若current指针不在栈顶则会在当前指针所在位置添加项。执行back操作并不修改history栈大小因此可以通过back和forward在当前大小的history栈中自由移动。** 掌握这个规律就知道如何维护历史记录就知道在什么状态下需要pushState。回到最初的需求产品经理规定从商品34的评论页按后退按钮可以到达最初的列表页但是他并没有详细规定如何后退。在这里就会有2中实现方式 每一次后退会回到上次的访问地方。如在商品34的评论页会后退至商品34的详情页再后退则会回到商品9的详情页直至回到列表页。总共维护三层历史记录第一层栈底为列表页第二层为详情页第三层栈顶为评论页或图片详情页。在该种实现下由商品34的评论页第一次后退至商品34的详情页第二次后退至列表页。针对第一种其实实现最为简单因为这完全是由浏览器默认控制历史记录堆栈而我们只需在合适的时机调用pushState将url插入到堆栈然后在onpopstate处理函数中监听对应的时间即可 window.addEventListener(popstate, function (e) {console.log(popstate)// 后退前进至商品详情页异步加载数据并渲染if(e.state e.state.indexOf(/shop/sku/) ! -1){ajaxDetail(e.state,true);}else// 后退前进至评论页异步加载数据渲染if(e.state e.state.indexOf(/shop/comment/commentList.html) ! -1){ajaxComment(e.state,true);}else// 后退前进至图片详情页异步加载数据渲染if(e.state e.state.indexOf(/shop/item/pictext/) ! -1){ajaxPic(e.state,true);}else// 后退前进至列表页隐藏浮层if(e.state e.state.indexOf(/search/) ! -1){// 隐藏spa的浮层$(.spa-container).css(zIndex,-1);}}); 针对第二种实现则是本文的重点。毕竟由浏览器默认维护的历史堆栈在某些业务场景中并不匹配因此需要开发者自己维护一个历史记录栈。在本次实现中由于总共涉及4张页面的显示因此我们设定了3层历史堆栈这很好理解。 为了构建这样的历史记录栈在主页面即列表页中需要额外添加两条历史记录。这是由于默认打开列表页时当前页面的url已加入历史记录栈中 function push(state){history.pushState(state, null, location.pathname location.search);}// abc用于标示初始列表页history.replaceState(abc,null,location.pathname location.search)// 压入两条历史记录push();push(); 这样打开列表页后就会创建3个历史记录并且这3个历史记录的url都为列表页的url这与后面的操作并无影响。 在列表页中打开详情页需要做额外的处理。由于按照我们设计的历史记录栈第二层应该为详情页而此时在初始化后历史记录栈的当前指针已指向栈顶元素因此需要将当前指针下移一位。这里就需要history.back来完成。 $(.item-list).on(click,a,handler);// 异步加载详情数据 var handler function(e,isScrollXClick){var a this;ajaxDetail($(a).attr(href),isScrollXClick);return false; };var isScrollXClick;/*** params: url 请求路径 isScrollXClick: 是否点击推荐商品**/var ajaxDetail function(url,isScrollXClick){$.ajax({url: /api url,success: function(data){......if(!isScrollXClick){console.log(I am back!)// 在代码中进行back or forward并不会立即出发popstate事件以v8引擎为例在执行back之后// 的大概18us之后会触发事件而此时如果立即通过replaceState修改url则会造成失败修改的是// history stack栈顶的url.// 这里通过异步执行replaceState兼容history.back();}// 异步触发setTimeout(function(){history.replaceState(url, null, url);})// 针对推荐栏的商品循环绑定事件此处用事件代理优化$(#J_PDSlider).on(click,a,function(e){isScrollXClick 1;handler.call(this,e,isScrollXClick);return false;});},error: function(xhr, type){alert(Ajax error!)}})}; 在此处实现通过isScrollXClick变量判断是否点击的是推荐商品如果不是则需要执行back操作下移指针。此时指针是指在第二层但是浏览器和第二层历史记录的url仍为初始化设定的url因此需要修改在这里异步修改当前url。 之所以异步执行replaceState是由于webkit触发popState事件决定的。在代码中执行history.back 或者history.forward并不会立即返回也不会立即触发popState事件。由于没有阅读webkit的源码因此无从推测执行back或者forward后具体需要额外做什么操作它们之间有着10us级别的间隔因此此处必须使用setTimeout实现异步改变url。 在具体开发过程中这个问题困扰着笔者好几天终于在一次调试过程中发现浏览器url的变动才联想到可能是由事件触发的时间差导致。 对于图片详情和评论的逻辑处理则和上文类似无需多言。 最后一次后退需要回到列表页而在初始化阶段我们给列表页设置了state为“abc”特殊的标示该路由因此在popState事件处理中我们就可以根据该项回到初始页 window.addEventListener(popstate, function (e) {if(e.state e.state.indexOf(/shop/sku/) ! -1){ajaxDetail(e.state,true);}else if(e.state e.state.indexOf(abc) ! -1){// 隐藏spa的浮层$(.spa-container).css(zIndex,-1);push();push();}}); 如果回到初始页隐藏浮层同时在执行2次push操作。根据上节发现的规律在初始页执行2次push操作会在当前指针位置重新添加2个历史记录当前指针指向栈顶元素历史记录栈的数量不变仍为3。这样就完成了简单的由开发者自定义维护历史堆栈的spa系统。 回顾 之所以会写这篇文章完全是出于偶然由于实际项目的各种需求我们不应该仅仅将眼光停留在使用API的层面上。另外在开发过程中遇到难以解决的问题需要提出各种合理的设想并用详实的实验证明在得到相对应的结论后需要利用该结论去例证其他场景这样才能确保解决方案的可靠性。目前网络上或者书籍中并未提供任何手动维护历史记录堆栈的方法也未明确指出History API与浏览器历史记录之间如何影响因此本文对于旨在利用History API实现spa的开发者而言还是有些指导意义的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/89473.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

太原网站建设电话网络营销软件网站

交换机的用途是非常广泛的,可以这样说,只要是需要联网的地方,基本上都会和交换机相关。我们一般把交换机的使用大致为商用和工业级,商用基本上在公司、单位的办公使用比较常见,今天飞畅科技着重为大家介绍一下工业级交…

自己做电影网站怎么赚钱seo工作室

torch.nn.Sequential torch.nn.Sequential是一个容器,利用此容器可以快速简单的搭建一个简单的神经网络。这里以搭建一个三层神经网络为例。 首先该容器的参数分别是上一层到下一层的权重、激活函数,以此循环。 这里torch提供快速生成网络权重的方法&am…

给别人做网站用做假酒验证北京seo关键词排名

目录 Collection集合 迭代器遍历 增强for遍历 Lambda表达式遍历 List集合 遍历 数据结构 栈 队列 数组 链表 前言: 学习JAVA的第十三天 Collection集合 Collection的遍历方式: 迭代器(不依赖索引)遍…

榆林做网站多少钱怎做卖东西的网站

目录 参数复制文件然后进行同时复制操作 给定内容生成文件,并制定权限验证 关于覆盖先查看当前内容覆盖并备份查看文件权限 还有有没有备份查看文件内容 参数 这个模块用于将文件复制到远程主机,同时支持给定内容生成文件和修改权限等。   其相关选项…

深圳燃气公司官网北京seo地址

##用nodejs 写爬虫 关键模块:cheerio、http,request。 consonl.log() 出来的数据 首先安装相关的模块: //我用了某宝的镜像安装 原来是 npm,-g 可以根据自己情况是全局按装还是局域安装 cnpm install -g jquerycnpm install -g cheerioc…

大型网站 中小型网站失效网站建设费支出

写在前面 如果你的身边有一个随时待命、聪明绝顶的AI小助手,能够听懂你的话,理解你的需求,用温暖的声音回应你,会是一种什么体验? 今天,带大家一起搭建一个语音对话机器人,拥有一个专属的个人…

成都专业制作网站公司免费h5在线制作

问:gcc中的-I.是什么意思。。。。看到了有的是gcc -I. -I/usr/xxxxx..那个-I.是什么意思呢 最佳答案 答:-Ixxx 的意思是除了默认的头文件搜索路径(比如/usr/include等)外,同时还在路径xxx下搜索需要被引用的头文件。 所以你的gcc …

深圳微商城网站设计宣传片制作标准参数

rk3588s: 旋转编码器input输入事件适配 基于Android 12 kernel-5.10版本 参考文档: https://blog.csdn.net/szembed/article/details/131551950 Linux 输入设备调试详解(零基础开发)Rotary_Encoder旋转编码器驱动 通用GPIO为例 挂载input输…

正能量网站入口免费安全产品展示的手机网站

使用Turbo C和Turbo Pascal开始学习编程貌似也是一代人的集体记忆。这方面我也没什么忌讳,毕竟Borland Turbo C在九十年代末的PC上面还是一个运行效率不错的开发工具。然而启蒙老师的水平限制,那个时候所学习的编写和调试技术都不过关,一个超…

中国最好的域名注册网站微信小程序第三方开发

Hibernate中的标识符为实体的主键属性建模。 它有助于我们唯一地标识JPA实体。 每个实体都必须定义一个标识符。 同样,它可以是简单的也可以是复合的。 我们可以通过几种方式定义一个Hibernate标识符。 在本教程中,我们将学习如何做。 简单&#xff08…

虹口专业做网站微信支付申请网站建设未完成

文章来源&#xff1a;包子博客MySql 优化的 30 条建议1、应尽量避免在 where 子句中使用!或<>操作符&#xff0c;否则将引擎放弃使用索引而进行全表扫描。2、对查询进行优化&#xff0c;应尽量避免全表扫描&#xff0c;首先应考虑在 where 及 order by 涉及的列上建立索引…

深圳做网站网络营销公司接推广app任务的平台

进程的调度时机与进程的切换操作系统原理中介绍了大量进程调度算法&#xff0c;这些算法从实现的角度看仅仅是从运行队列中选择一个新进程&#xff0c;选择的过程中运用了不同的策略而已。对于理解操作系统的工作机制&#xff0c;反而是进程的调度时机与进程的切换机制更为关键…

信誉好的网站开发东莞seo整站优化火速

最近项目中有一个网络判断的需求&#xff0c;因为终端只能连接wifi&#xff0c;wifi即使连接上也可能会出现不能连接网络的问题&#xff0c;所以需要进行网络连接的判断。ping的相关知识使用ping检验网络是否可以连接ping就是检测客户端是否可以上网。那么我们就上代码该段代码…

微信网站建设定制住房公积金个人提取

1 问题 glide加载图片地址的时候&#xff0c;可能这个地址没有图片&#xff0c;那么我们需要对这种异常情况进行处理&#xff0c;当然我们也需要把这个图片进行圆形化 2 代码解决 Glide.with(mContext).load(iconPath).error(new ColorDrawable()).listener(new RequestListen…

汕头拿家做网站广州软件园软件开发公司

简介 XXL-JOB是一个分布式任务调度平台&#xff0c;其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线&#xff0c;开箱即用。 源码github地址 源码gitee地址 中文文档地址 中央仓库地址 <!-- http://repo1.maven.org/ma…

网站备案没了自己建一个简单的网站

高校心理教育辅导系统目录 目录 基于Springboot的高校心理教育辅导系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、学生功能模块的实现 &#xff08;1&#xff09;学生登录界面 &#xff08;2&#xff09;留言反馈界面 &#xff08;3&#xff09;试卷列表界…

本省网站建设建议微信营销的优势

转载自http://blog.csdn.net/lu597203933/article/details/14104505 灰度直方图 这次我从最基本的直方图讲起&#xff0c;一维直方图&#xff0c;至于二维等高维直方图&#xff0c;仅作为了解&#xff0c;后面有时间另开blog详解。 1&#xff1a;首先我们给出一幅图 其中的数据…

微信网站开发流程戚墅堰网站建设

多重纹理和纹理组合器 本文主要介绍OpenGL中两种技术的使用方法&#xff1a;多重纹理技术和纹理组合器技术&#xff0c;最终根据参考【2】中的代码&#xff0c;实现了两个简单的演示DEMO&#xff0c;其中使用到了《八叉树颜色量化、BMP、TGA文件解析》篇章中提供的图像解析类。…

找活做的网站wordpress首页白屏

1、什么是视图视图是虚拟的表&#xff0c;是一个存储的查询&#xff0c;虽然不需要实际的物理存储&#xff0c;但是也被看作是一个数据库对象&#xff1b;它与包含数据的表不一样&#xff0c;它不包含任何列或数据&#xff0c;它只是包含使用时动态检索数据的查询&#xff0c;并…

中英文网站建设企业网站未收录

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…