前记: 在工作中,如果自己发现了bug,千万不要幻想着能够蒙混过关,别人不会发现,一定要赶在别人发现之前,自己解决掉它!!不然的结果就是,明天上线,今天提出了这个bug,要求修复,然后自己晚上挑灯修改!!~~~~(>_<)~~~~
先说一下遇到的问题:
想要实现的效果是,在A页面中通过在a的href链接(href = 'B.html#b'),链到B页面的b锚点处。
在普通页面是可以正常实现的,所谓的普通页面指的是 页面一次性渲染,不存在js动态加载elements,破坏DOM树的行为。
现在的问题是,锚点b在页面B的中间位置,在b下面有个table ,里面的元素是动态添加的,也就是说:
(1)在从A跳到B的过程中,B页面加载html完成以后,DOM树渲染完成,但是还未执行js脚本时,锚点已计算好了!
(锚点本来就属于css领域,所以是先加载html 和 css页面渲染。写到这里又想去回顾一下页面加载,渲染的顺序到底是怎样的了! )
(2)接下来,js阻塞式加载执行,动态添加elements,重新渲染了DOM树结构。导致锚点发生了偏移,从而看到的页面定位不对了,往下滚动了!
(由于不知道锚点的实现计算原理到底是怎样,所以只能描述一下看到的现象)
目前的解决方案是:
使用js,读取传过来的hash值:#target,手动的滚动到目标位置;
var hash = window.location.hash; if ( hash === '#target' ) { window.location.hash = ''; //防止刷新时,又回到锚点处 window.scrollTo(0, 675); }
疑虑:目前由于锚点位于页面的中部,同时锚点的上半个部分的高度是固定的,虽然有动态填充部分,但是高度值不变,所以,可以将滚动到的高度值定死;但是如果以后页面的上半部分有高度变化的话,滚动位置将不准确了!(就是测试环境和线上环境会略有不同,因为线上会有公共头部,推送公告信息!)
再来剖析一下锚点的实现原理:
写在前面的几句话:
'无滚动则无定位';
'滚动条地目标是滚至锚点元素的顶部,与上边缘重合'
首先介绍锚点定位的几种常见方法:
(1)id定位 ,使用id + #id跳转,可以实现将锚点元素绑定到任意元素上
(2)name定位 , 只能针对a标签来定位,对其他标签不能起到定位作用。
(3)万能的js定位,获取元素位置,使用scrollInToView(); //准确的说,这种方法不属于锚点定位
关于scrollIntoView()方法,在原生DOM下好用,但是jquery不支持;
用在我这里,也会滚到目标位置的下面。
不管是上述方法中的哪种方法,当页面(准确的说应该是父元素)的滚动条没有或不足时,不发生任何滚动或滚动底部(尽全力了!)
由于js的万能性,此处不予讨论;以下讨论锚点定位的实现:
锚点定位的本质是: 修改容器的滚动高度; 也就说父容器无滚动,则锚点定位就会失效。
锚点的应用:
1.与overflow:hidden结合,实现:无js完全用css实现选项卡轮转切换效果 (这种效果,可以在js挂掉的时候救场,保持图片的滚动功能)
注:overflow:hidden就是隐藏超出的部分,不出现滚动条;
css3中的:target伪类 + 锚点
URL 带有后面跟有锚名称 #,指向文档内某个具体的元素。这个被链接的元素就是目标元素(target element)。
:target 选择器可用于选取当前活动的目标元素,改变样式;
如果页面足够高的话,会有样式的改变 同时伴随着 页面的滚动。
(伪类的:target的支持情况是:IE6-8是不支持的,其余都支持!未来css强大的征兆!)
参考文章:
http://www.zhangxinxu.com/wordpress/2013/08/url-anchor-html-%E9%94%9A%E7%82%B9%E5%AE%9A%E4%BD%8D%E6%9C%BA%E5%88%B6-%E5%BA%94%E7%94%A8-%E9%97%AE%E9%A2%98/
http://bbs.blueidea.com/thread-2952396-1-1.html
http://www.zhangxinxu.com/wordpress/2010/07/%E9%94%9A%E7%82%B9%E8%B7%B3%E8%BD%AC%E5%8F%8Ajquery%E4%B8%8B%E7%9B%B8%E5%85%B3%E6%93%8D%E4%BD%9C%E4%B8%8E%E6%8F%92%E4%BB%B6/