第一个下拉菜单的问题
第一个下拉菜单的按钮是个背景图片吗?(因为素材里没有所以我认为是一个div假装的)
如果按钮用外面的div假装的话,点击这个按钮后怎么操控下拉菜单的显示呢?
这个问题的总结就是 : 外部生成的按钮怎么控制下拉菜单的内容显示隐藏呢?
另外我想问一下怎么生成一个自定义并触发呢事件呢?消息订阅用的是自定义事件来实现的吗?
87
收起
正在回答
2回答
首先,上面给你的代码并不是源码哦。而是帮你梳理的实现思路。如果同学仔细去看,你会发现里面有每一步骤的实现思路和事件的绑定与触发哈
2、外部按钮控制下拉菜单实现思路可以参考如下:

与实现下拉菜单很相似
3、自定义事件的绑定和触发可以使用addEventListener,比如:
element.addEventListener("click", function() {……});4、消息订阅也是可以用自定义事件实现的
希望可以帮到你!
樱桃小胖子
2019-06-09 10:29:29
从同学的描述上来看,同学是对本次作业没有实现思路么?这里帮你整理了一下大概的实现思路,可以参考:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div id="wrap"> <div> <div class="title">自定义select</div> <!-- 下拉列表容器 --> <div class="selector clearfix"> <!-- 下拉列表 --> <div class="selector-content" id="selector-content"></div> <div class="selector-arow">▼</div> <!-- 下拉列表内容 --> <div class="selector-items"> <!-- 搜索框 --> <input type="text" class="selector-search" placeholder="搜索" id="search"> <!-- 下拉列表项 --> <div class="result"> </div> </div> </div> </div> <div> <p id="out"></p> </div> <div style="text-align: center;margin-top: 60px;"> <div class="title">原生select</div> <select id="demo"> <option value="1" type="构建工具">Babel</option> <option value="2" type="构建工具">Webpack</option> <option value="3" type="构建工具">Rollup</option> <option value="4" type="前端框架">Vue</option> <option value="5" type="前端框架">Angular</option> <option value="6" type="前端框架">React</option> <option value="7" type="前端框架">Nerv</option> </select> </div> </div> <script src="js/index.js"></script> </body> </html>
js
(function(window,document){
//选择器方法
const qs = {
$(ele,parent = document){
return parent.querySelector(ele);
},
$all(ele,parent = document){
return parent.querySelectorAll(ele);
},
appendChild(parent,...child){
child.forEach(element=>{
parent.appendChild(element);
})
}
}
//定义构造函数
function Selector(option){
this._init(option);
this.getContent();
this.list();
this.bind();
}
//初始化
Selector.prototype._init = function ({content,items,search,result,out}){
this.content = qs.$(content);
this.items = qs.$(items);
this.searchBar = qs.$(search);
this.out = qs.$(out);
this.shown = false;
this.demoOptions={};
this.curliIndex = undefined;
this.shownHeight = '';
this.items.style.display = 'none';
this.items.style.height = 0;
this.content.innerHTML = '未选择';
}
//显示、隐藏功能
Selector.prototype.showhide = function(ele){
if(this.shown){
this.shownHeight = ele.style.height;
ele.style.height = 0;
setTimeout(()=>{
ele.style.display = 'none';
},500)
this.shown = false;
}else{
ele.style.display = 'block';
setTimeout(()=>{
ele.style.height = this.shownHeight || '200px';
})
this.shown = true;
}
}
//搜索框搜索功能
Selector.prototype.search = function(value){
let reg = new RegExp(value,'ig')
for (let i = 0;i<this.curLi.length;i++){
if(!value){
this.curLi[i].style.display = 'block';
}
else if(reg.test(this.curLi[i].innerText)){
this.curLi[i].style.display = 'block';
}else{
this.curLi[i].style.display = 'none';
}
}
if(this.ul.offsetHeight < 200){
this.items.style.height = this.ul.offsetHeight + 40 + 'px';
}else {
this.items.style.height = '200px';
}
}
//获取原生select内容
Selector.prototype.getContent = function(){
let options = qs.$all('option',qs.$('#demo'));
for (let i=0;i<options.length;i++){
if(!this.demoOptions.hasOwnProperty(options[i].getAttribute('type'))){
this.demoOptions[options[i].getAttribute('type')]=[];
this.demoOptions[options[i].getAttribute('type')].push(options[i].innerHTML);
}else{
this.demoOptions[options[i].getAttribute('type')].push(options[i].innerHTML);
}
}
}
//生成下拉列表选项
Selector.prototype.list = function(){
let ul = document.createElement('ul');
let ulInner = '';
for (i in this.demoOptions){
let div = `<div>${i}</div>`;
let li = '';
for (let j=0;j<this.demoOptions[i].length;j++){
li+=`
<li>${this.demoOptions[i][j]}</li>
`
}
ulInner += div + li;
}
ul.innerHTML = ulInner;
qs.appendChild(qs.$('.result'),ul);
}
//绑定事件
Selector.prototype.bind = function(){
//点击选择框显示隐藏事件
let sel = qs.$('.selector');
sel.addEventListener('click',(e)=>{
e.stopPropagation();
if(e.target.id === 'search'){return}
this.showhide(this.items);
});
//选择选项后显示文字事件
this.ul = qs.$('ul',qs.$('.result'));
this.curLi = qs.$all('li',this.ul);
let self = this;
this.curLi.forEach((curli,index)=>{
curli.addEventListener('click',function(e){
e.stopPropagation();
self.showhide(self.items);
let beforeVal = self.content.innerText;
let beforeIndex = self.curliIndex;
self.content.innerText = this.innerText;
self.curliIndex = index + 1;
self.out.innerHTML = `之前的值是 ${beforeVal} - ${beforeIndex}<br>
改变后的值是 ${self.content.innerText} - ${self.curliIndex}
`
for(i=0;i<self.curLi.length;i++){
self.curLi[i].className = '';
}
this.className = 'mousedown';
})
})
//点击外侧隐藏下拉列表
document.addEventListener('click',(e)=>{
e.stopPropagation();
if(this.shown){
this.showhide(this.items);
}
})
//搜索框输入监听事件
this.searchBar.addEventListener('keyup',()=>{
let value = this.searchBar.value;
this.search(value);
})
}
//全局变量
window.selector = Selector;
})(window,document)
//实例化
new selector({
items:'.selector-items',
content:'#selector-content',
search:'.selector-search',
out:'#out'
})先尝试着理解一下,编程最主要的是逻辑思考
祝学习愉快~
相似问题
登录后可查看更多问答,登录/注册
4.Vue与React高级框架开发
- 参与学习 人
- 提交作业 239 份
- 解答问题 10739 个
本阶段带你深入前端开发的肌理,通过ES6基础知识和前端主流高级框架的学习,助你快速构建企业级移动webAPP应用,进入职场的终极battle
了解课程
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星