dropdown定位问题

问题描述

最近做项目的时候,有这么一个问题:用了brix组件dropdown做了一个下拉框,而这个下拉框有一个默认值,想让下拉框展开的时候直接定位到当前所选值,即:

希望原来的
dropdown定位问题_第1张图片
变为
dropdown定位问题_第2张图片
 

其html组织结构为:


dropdown定位问题_第3张图片
 

ul中的各个选项为js手动生成。

 

一、最初的想法

直接在js中给默认的开始值添加选中样式,再用js将下拉框定位到所选中值。具体是:在'.dropdown-hd'上加click事件,当展开dropdown的时候获取被选中项的scrollTop值,然后将ul的scrollTop设置为被选中项的scrollTop值。


dropdown定位问题_第4张图片
 

未果,下拉框的位置还是丝毫不动。

二、求助网络

发现理解scrollTop有误,网上答案为:


dropdown定位问题_第5张图片
 

也就是说组件初始化时内层元素上边界和外层元素上边界重合,没有任何内容超过外层元素的上边界,此时被选中项的scrollTop值为0,无法起作用。

 

再查scrollTop的时候,发现总是把scrollTop和offsetTop联系在一起,故又看了一下offsetTop,发现这个属性挺符合要求的,因为offsetTop获取对象相对于版面或由offsetTop属性指定的父坐标的计算顶端位置。故改为:


dropdown定位问题_第6张图片
 

但是发现还是不行,定位不准确,结果如下所示。


dropdown定位问题_第7张图片
 

三、求助同事

非常感谢我旁边的外号哥GG和牙套姐MM,他们向我伸出了援助之手。牙套姐MM听了我的思路之后,皱起了眉头,觉得我这种做法是不对的,不应该人为的给这个组件默认值添加选中样式,再定位,而应该从组件入手,应用组件默认的选中item方法。所以又开始了探索组件的道路。

(1)组件自身方法select

组件有选中item的方法select,直接运用select方法让组件自动去完成。而我终于也知道了如何从brix中获取一个组件了,Brix.pagelet.getBrick("dropdown-start");其中参数为组件的id,通过这个可以获取一个组件,Brix.pagelet.getBricks("dropdown");其中参数为组件的name,可以获取组件名为参数的一系列组件。真的,非常感谢牙套姐的热心帮助,要不然我真不知道是这样获取已经初始化的组件的。

因为有两个组件名为dropdown的组件,不知道是先初始化哪一个,所以给这两个组件都加上了id,然后:



 

 

发现确实是选中了默认值,但是郁闷的是组件并没有定位到默认值的地方。

(2)监听组件事件selected

(1)无果后,牙套姐MM建议监听组件选中事件selected,使组件选中选项后立马定位到该位置。于是,


dropdown定位问题_第8张图片
 

发现还是不行,定位不准确,结果为:


dropdown定位问题_第9张图片
 

(3)是不是监听错了事件?

牙套姐MM说,可能选中完选项之后,整个下拉框就缩起来不可见了,所以监听selected方法根本无法准确的得到这些数值并设置。

于是,我们又想到应该监听组件刚展开下拉框的事件focus,于是:


dropdown定位问题_第10张图片
 

结果如下:


dropdown定位问题_第11张图片
 

顿时欣喜若狂,尼玛,终于好了,都忍不住向天狂笑啦!!!但是,发现又有了新的问题,我再自己任意选择其他选项时,悲剧发生了,如下:


dropdown定位问题_第12张图片
 

唉,一个问题的解决伴随着其他问题的出现啊……怎么会这样?这定位也太不准了吧?

(4)抛弃kissy的offsetTop方法,使用原生的javascript方法

牙套姐MM就说,可能kissy的scrollTop方法和offsetTop有问题,因为是kissy封装的方法,可能不准确,于是抛弃了kissy的offsetTop方法:


dropdown定位问题_第13张图片
 

发现,终于OK了,没问题了,这个问题终于得到了解决。

(5)探索kissy的offset方法

追根溯源,为什么kissy中的offset不准呢?于是查看Kissy源代码:


dropdown定位问题_第14张图片
 
dropdown定位问题_第15张图片
 
dropdown定位问题_第16张图片
 

 

从源码中可以看出,kissy的offset是这样计算的,当relativeWin没有指定或者是window的时候,element的offsetTop指的是当前对象到page最顶端的距离,当指定的relativeWin不是window的时候,element的offsetTop指的是当前对象到浏览器client顶端的距离。所以不管我们是不是



 中指定了相对父元素,只要这个父元素不是window,那么offset计算的就是当前对象到浏览器client顶端的距离,而非当前元素到这个相对父元素层顶端的距离,与原生的javascript不一致。

你可能感兴趣的:(dropdown,javascript,kissy)