생성: function(elem) {
var data = [],
i = 0,
length,
option,
options,
value,
text,
obj,
lis,
ul,
_default,
icon,
selectedText,
selectedValue,
div,
wrapper,
위치,
왼쪽,
위쪽,
cssText;
options = elem.getElementsByTagName('option')
length = options.length
for(; i < length; i ) {
option = options[i]
값 = 옵션.값
텍스트 = 옵션.innerText || option.textContent
obj = {
값: 값,
텍스트: 텍스트
}
if(option.selected) {
selectedValue = 값
selectedText = text
obj['selected'] = true
}
data.push(obj)
}
lis = this.render(this.tmpl, data)
ul = '
'
//
div = document.createElement('div')
div.style.display = 'none'
div.className = 'select-wrapper'
//已选元素
_default = document.createElement('div')
_default.className = 'select-default unselectable'
_default.unselectable = 'on'
//让div元素能够获取焦点
_default.setAttribute('tabindex', '1')
_default.setAttribute('data-value', selectedValue)
_default.setAttribute('hidefocus', true)
_default.innerHTML = selectedText
div.appendChild(_default)
//选择icon
icon = document.createElement('span')
icon.className = 'select-icon'
div.appendChild(icon)
//下拉列表
wrapper = document.createElement('div')
wrapper.className = 'select-list hide'
wrapper.innerHTML = ul
//생성 새로운 元素
div.appendChild(래퍼)
//插入到select 元素后면
elem.parentNode.insertBefore(div, null)
//获取select元素왼쪽 상단值
//先设置select显示,取完left, top值后중새隐藏
elem.style.display = 'block'
//事件绑정
this.sysEvent(div)
position = squid.position(elem)
elem.style.display = '없음'
왼쪽 = position.left
top = position.top
cssText = '왼쪽: '왼쪽'px; 상단: ' 상단 'px; 디스플레이: 블록;'
div.style.cssText = cssText
}
create 방법을 선택하세요.个클래스为선택 -래퍼의 모토 페이지, 페이지가 있는 클래스는 select-default의 모토 유형에 사용되는 클래스 선택 아이콘, 클래스의 선택 아이콘의 모토 탭 사용 또는 클래스 선택 목록의 div 모토 페이지에서 사용 가능합니다.了一个ul 元素里面是从系统select拷贝의 옵션에 있는 文本과 值分别存放에서 li 元素的文本과 data-value 속성입니다.及键盘上下选择下拉元素回车选中下拉오징어 위치 방법 사용 于获取系统select 켤레상호수 offset得到top,left值然后分别减去offsetParent获取的오프셋 상단, 왼쪽.细节地方的实现,比如说:点击 확장开下拉显示上次已选择的元素,具体实现该功能的是initSelectedmethod如下
var curText = elem.innerText || elem.textContent,
curValue = elem.getAttribute('data-value'),
wrapper = elem.nextSibling.nextSibling,
n = Wrapper.firstChild.firstChild,
text,
값,
dir,
min = 0,
max,
hidden = false;
for(; n; n = n.nextSibling) {
text = n.innerText || n.textContent
value = n.getAttribute('data-value')
if(curText === text && curValue === value) {
//显示已选中元素
if( squid.isHidden(wrapper)) {
wrapper.style.display = 'block'
hidden = true
}
max = Wrapper.scrollHeight
if(n.offsetTop > (max / 2)) {
if(wrapper.clientHeight 래퍼.scrollTop === max)
dir = 'up'
else
dir = 'down'
}else{
if(wrapper.scrollTop === min)
dir = 'down'
else
dir = 'up'
}
this.inView(n, 래퍼, dir)
if(hidden)
wrapper.style.display = 'none'
this.activate(n)
break
}
}
}
이 방법은 사용자가 선택한 콘텐츠를 저장하는 데 사용되는 select-default 클래스를 사용하여 div 요소를 수신합니다. 구체적인 구현 방법은 먼저 모든 옵션을 순회하여 선택한 클래스가 있는 li 요소를 얻은 다음 표시하는 것입니다. 현재 activate 메소드를 통해 선택되어 있습니다. 여기서 계산해야 할 것이 있습니다. 즉, 드롭다운 목록이 확장될 때마다 선택한 요소를 페이지의 보이는 영역까지 스크롤해야 합니다. 드롭다운 목록에는 내용이 많을 수 있지만 드롭다운 목록의 외부 선택 목록에는 최대 높이가 있으므로 최대 높이를 초과하면 계산이 스크롤 막대가 나타납니다. 기본적으로 수행되지 않는 경우 선택한 요소는 스크롤 막대 아래 또는 스크롤 막대 위의 스크롤 막대 아래에 있을 수 있으므로 컨테이너 스크롤 막대의 위치를 재설정하려면 계산이 필요합니다. 구체적으로, 선택한 콘텐츠가 스크롤 막대 위 또는 아래에 표시되는지 여부는 선택한 요소의 offsetTop 값이 외부 컨테이너 선택 목록의 실제 높이의 절반보다 큰지 여부에 따라 선택한 요소를 시각적 영역에 표시하는 방법입니다. inView 메소드입니다. inView 메소드는 다음과 같습니다
inView: 함수 (elem, Wrapper, dir ) {
var scrollTop = Wrapper.scrollTop,
//선택한 요소 offsetTop
offsetTop = elem.offsetTop,
top
if(dir = == 'up' ) {
if(offsetTop === 0) {
//위로 스크롤 막대
wrapper.scrollTop = offsetTop
}else if(offsetTop < scrollTop) {
top = offsetTop - scrollTop
//스크롤 막대는 상위 값으로 스크롤됩니다.
this.scrollInView(wrapper, top)
}
}else{
var clientHeight = 래퍼. clientHeight;
if(offsetTop elem.offsetHeight === Wrapper.scrollHeight) {
wrapper.scrollTop = Wrapper.scrollHeight - Wrapper.clientHeight
}else if(offsetTop elem.offsetHeight > clientHeight scrollTop) {
top = (offsetTop elem.offsetHeight) - (scrollTop clientHeight)
this.scrollInView(wrapper, top)
}
}
}
inView 메소드는 위로 스크롤할지 여부를 결정해야 합니다. 여전히 아래로 스크롤하는 동안, scrollInView 메소드 코드는 단순히 드롭다운 목록 외부 컨테이너의 scrollTop을 지정된 값으로 설정하는 것입니다. 메소드는 다음과 같이 구현됩니다.
scrollInView: 함수 (elem, top) {
setTimeout(function() {
elem.scrollTop = top
}, 10)
}
이 메소드는 setTimeout 및 자바스크립트 실행 큐에 지연이 추가되는데, 가장 큰 문제는 IE8에서 확장된 드롭다운 목록의 스크롤 막대가 코드에서 설정한 scrollTop을 무시하고 결국 맨 위로 스크롤된다는 점입니다(성능 측면에서 볼 때, scrollTop 설정도 적용될 수 있는 것 같지만 결국에는 스크롤 막대가 맨 위로 재설정됩니다. IE8에서 왜 이런 문제가 발생하는지 모르겠습니다.) 선택한 요소를 시각적 영역 내에 표시할 수 없습니다. 다른 브라우저에서는 문제가 발생하지 않습니다.
전체 구현 세부 사항은 대략 이 정도입니다. 키보드의 위쪽 및 아래쪽 키를 누르고 Enter 키를 눌러 드롭다운 목록을 닫는 논리는 매우 간단합니다.
발생한 문제
키보드 키다운, 키업, 키누름 이벤트에 응답하기 위해 div가 포커스를 갖도록 하는 방법, Google(Google은 특별한 상황에서는 사용하기 쉽지 않습니다. 기능) 일부 정보를 검색한 후 마침내 div 요소가 집중을 얻고 사용자 작업에 응답할 수 있도록 div 요소에 대한 tabindex 속성을 설정해야 한다는 것을 발견했습니다. 브라우저는 기본적으로 두 번 클릭하거나 너무 자주 클릭하여 현재 영역을 선택하므로 이 기본 작업을 취소하고 사용자에게 좋은 경험을 제공하려면 선택 불가능한 속성을 div 요소에 추가해야 합니다. IE 브라우저에만 적용됩니다. 선택 불가능한 클래스 이름을 추가하면 다른 브라우저에서 이 문제를 피할 수 있습니다. 다른 문제는 논리적 제어 및 일부 위치 계산이며 여기서는 논의하지 않습니다.
사용 방법 먼저 페이지 템플릿에서 jselect로 바꾸려는 요소를 숨기거나 처리하지 않습니다. 기본적으로 jselect는 페이지의 모든 선택 항목을 가져와서 바꿉니다. jselect가 이를 대체하는 것을 원하지 않으면 select 요소
에 사용자 정의 속성 data-enabled="true"를 추가해야 합니다. 물론 data-enabled="false"를 추가하면 이 사용자 정의 속성이 없는 것처럼 jselect로 대체됩니다. 사용 중에 레이아웃 구조가 더 복잡한 페이지에서는 다른 문제가 발생할 수 있습니다. 제가 테스트한 페이지 구조는 매우 간단하기 때문에 테스트하지 않았을 수 있습니다.
jselect를 사용하려면 먼저 squid.js를 도입한 다음 jselect-1.0.js, jselect-1.0.css 파일을 가져와야 합니다. jselect를 호출해야 하는 경우 다음 호출 방법을 통해 jselect를 초기화합니다. Swing.jselect();
참고: jselect 소스 코드와 데모는
여기에서 다운로드할 수 있습니다.