滚动监听 after选择器

来源:http://www.chinese-glasses.com 作者:Web前端 人气:52 发布时间:2020-04-29
摘要:时间: 2019-09-15阅读: 126标签: 菜单业务需求 一、如何实现滚动到一定位置将内容固定在页面顶部 数据结构中含有图片、名称、children的树形结构,需要展示出每一级的图片名称和图片,

时间: 2019-09-15阅读: 126标签: 菜单业务需求

一、如何实现滚动到一定位置将内容固定在页面顶部

数据结构中含有图片、名称、children的树形结构,需要展示出每一级的图片名称和图片,找了些树形图的插件,都没有展示大的图片的,一般都是小图标,就自己试着写一个包含图的简单的插件。

图片 1图片 2

树形图的结构

 window.onscroll=function(){
     //滚动的距离,距离顶部的距离
     var topScroll =document.body.scrollTop||document.documentElement.scrollTop;
     //获取到导航栏id
     var bignav  = document.getElementById("pop_title");
     //当滚动距离大于150px时执行 固定位置 距离
     if(topScroll > 150){  
         bignav.style.position = 'fixed';
         bignav.style.top = -120+ 'px';
         bignav.style.left = 0 + 'px';
     }else{
         //当滚动距离小于150让导航栏恢复原状
         bignav.style.position = 'static';
     }
}
ul li  span /span a div name1/div /a ul li  span /span a div name2/div /a /li /ul /li/ul

滚动监听

主要是用ul和li展示,竖线是用ul的before伪元素写的样式,短横线是li的before伪元素写的样式,要解决的问题是竖线和横线的位置,LI中含有图片和不含有图片LI的class不同,同时li内部的ul的class 也不同,因为含有图片和不含图片设置的样式不一样。整个HTML结构采用递归的方式。

window.onscroll为滚轮监听,

事件交互

document.body.scrollTop||document.documentElement.scrollTop 写两个是为了兼容不同浏览器。

初始状态是全部展开,点击展开的图标(-)会隐藏同级的UL元素,并改变图标为(+)

固定位置的top要设为负值,原因不明,若为0则会跟上方有空隙。

$("#tree-box").on("click", ".icon", function() { $(this).siblings("ul").toggle(); if ($(this).hasClass("glyphicon-minus")) { $(this).removeClass("glyphicon-minus").addClass("glyphicon-plus") } else if ($(this).hasClass("glyphicon-plus")) { $(this).removeClass("glyphicon-plus").addClass("glyphicon-minus") }})

左右位置虽然是0也要设,不然若为不是100%宽度的内容会出现左右跳动。

如果数据结构是含有PID的,需要先转换成children的数据结构

上面这种方法高度是自己定死的。

 var json = [ { id: 1, pid: 0, text: '1(XX公司)' }, { id: 2, pid: 4, text: '2.1.1(开发部a-1组)' }, { id: 3, pid: 0, text: '2(开发部)' }, { id: 4, pid: 3, text: '2.1(开发部a)' }, { id: 5, pid: 0, text: '3(人事部)' }, { id: 6, pid: 5, text: '3.1(人事部A)' }, { id: 7, pid: 0, text: '4(设计部)' }, { id: 8, pid: 7, text: '4.1(设计部A)' }, { id: 9, pid: 4, text: '2.1.2(开发部a-2组)' }, { id: 11, pid: 2, text: '2.1.1.1(开发部a-1组1小组)' }, { id: 12, pid: 2, text: '2.1.1.2(开发部a-1组2小组)' }, { id: 13, pid: 5, text: '3.2(人事部A)' }, { id: 19, pid: 5, text: '3.3(人事部B)' } ]; function translateData(data, idStr, pidStr, chindrenStr) { var result = [], temp = {}, id = idStr, pid = pidStr, children = chindrenStr, i = 0, j = 0, len = data.length; // 重新把数组中的对象重新放到一个新的对象中,新的对象是以id 的值为键 for (; i  len; i++) { // 建立temp对象,由于对象是引用类型,修改temp或者data都会引起另一方改变 temp[data[i][id]] = data[i]; // temp[a[i][id]] = JSON.parse(JSON.stringify(data[i])); 这种情况data和temp是独立的 } // aVal 存储数组中的对象,获取新对象中key为pid 的对象,如果存在 for (; j  len; j++) { var dataVal = data[j], tempObj = temp[dataVal[pid]]; if (tempObj) { // 如果tempObj[children]不存在,把tempObj[children]设为数组 !tempObj[children]  (tempObj[children] = []); tempObj[children].push(dataVal); } else { // 如果不存在就把dataVal放到结果中 result.push(dataVal); } } console.log(data) return result; } document.getElementById("content").innerHTML = JSON.stringify(translateData(json, 'id', 'pid', 'chindren'), null, 2)

下面介绍获取元素高度的方法。

完整的代码

图片 3图片 4

 style type="text/css" * { padding: 0; margin: 0; } #box { margin: 20px; } .item-group { list-style: none; margin-left: 20px; position: relative; } .item-group:before { content: ""; display: inline-block; position: absolute; top: -10px; bottom: 15px; left: 0; border-left: 1px solid #67b2dd; z-index: 10; } .item-group-innerpic { list-style: none; margin-left: 20px; position: relative; } .item-group-innerpic:before { content: ""; display: inline-block; position: absolute; top: -48px; bottom: 15px; left: 0; border-left: 1px solid #67b2dd; z-index: 10; } .tree-item { position: relative; line-height: 30px; } .tree-item:before { display: inline-block; content: ""; position: absolute; top: 14px; width: 18px; height: 0; border-top: 1px dotted #67b2dd; } .tree-item1 { position: relative; line-height: 30px; } .tree-item1:before { display: inline-block; content: ""; position: absolute; top: 48px; width: 18px; height: 0; border-top: 1px dotted #67b2dd; } .item-group li span { margin-left: 20px; color: #0994ce; margin-right: -15px; } .item-group li a { margin-left: 20px;display:inline-block; } .item-group li img { width:100px; height: 100px;margin-right:10px; } .item-group li .item-name { display: inline-block } /style

 div  /div script src="../js/jQuery-2.1.4.min.js"/script script var data = [{ title: 'biaoti1', img: '../imgs/green.png', children: [{ title: 'biaoti1-1', img: '../imgs/1.jpg', children: [{ title: 'biaoti1-1-1' }, ] }, { title: 'biaoti1-2', children: [{ title: 'biaoti1-2-1', children: [{ title: 'biaoti1-2-1-1' }, { title: 'biaoti1-2-1-2', children: [{ title: 'biaoti1-2-1-1-1' }, { title: 'biaoti1-2-1-1-2' } ] } ] }, { title: 'biaoti1-2-2' } ] }, { title: 'biaoti1-3' } ] }, { title: 'biaoti2', children: [{ title: 'biaoti2-1' }, { title: 'biaoti2-2' } ] }, { title: 'biaoti3', children: [{ title: 'biaoti3-1' }, { title: 'biaoti3-2' } ] }, { title: 'biaoti4' } ]; var width = 50; var ulClass = "item-group" //封装函数,方便调用 function render(arr, ulClass) { //设置HTML为ul标签对的前半部分,用以将以下内容包括在ul中 var html = 'ulhljs-string"'"'; //设置循环,遍历数组中的每一项,最长不超过数组的长度,依次遍历 for (var i = 0; i  arr.length; i++) { //设置第一级ul中的li结构 lispan每个标题/span/li // console.log(arr[i]) //判断数组arr【i】的下方是否还有结构 if (!arr[i].children) { if (arr[i].img) { html += 'lispan/spanaimg src="' + arr[i].img + '" alt="图片 5"/div' + arr[i].title + '/div/a'; } else { html += 'lispan/spanadiv' + arr[i].title + '/div/a'; } } else { if (arr[i].img) { html += 'lispan/spanaimg src="' + arr[i].img + '" alt="图片 6"/div' + arr[i].title + '/div/a'; html += render(arr[i].children, "item-group-innerpic") } else { html += 'lispan/spanadiv' + arr[i].title + '/div/a'; html += render(arr[i].children, "item-group") } //如果有,就增加结构 } //设置第一级li的后标签 html += '/li' } //设置第一级ul的后标签 html += '/ul' return html; } //调用函数,传参数组data,将其赋值给第一级ul的父级结构box,生成动态菜单var treebox = document.getElementById("tree-box") treebox.innerHTML = render(data, ulClass); $("#tree-box").on("click", ".icon", function() { $(this).siblings("ul").toggle(); if ($(this).hasClass("glyphicon-minus")) { $(this).removeClass("glyphicon-minus").addClass("glyphicon-plus") } else if ($(this).hasClass("glyphicon-plus")) { $(this).removeClass("glyphicon-plus").addClass("glyphicon-minus") } //console.log(this) }) /script
window.onload = function(){
    //获取导航框架
    var navContainer = document.getElementById("introductFra"); 
    //获取导航ul
    var navBox = document.getElementById("introBox");  
    //获取导航下内容大框架
    var text = document.getElementById("contantFra"); 
    //获取li
    var navBoxChild = navBox.children;  
    //获取内容里每个大块的框架
    var textChild = text.children;  
    //获取导航距顶端距离
    var num = navContainer.offsetTop;  
    //获取导航高度
    var a = navContainer.offsetHeight;  
    window.onscroll = function(){  
        var scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;  
        //滚动告诉超过导航位置
        if(scrollTop >= num){  
            //导航增加fixed属性
            navContainer.className = "introductFra fixed";  
            //下面板块内容向下空出一个导航的距离
            text.style.paddingTop = a +"px";  
            navContainer.style.zIndex = "999";
        }else{  
            //恢复原属性
            navContainer.className = "introductFra";  
            text.style.paddingTop = "";  
        }  
        //当导航与相应文档接触的时候自动切换   
        for(var i=0;i<navBoxChild.length;i++){  
            if( scrollTop +100 >= textChild[i].offsetTop){  
                //循环给每个li样式设为空
                for(var j=0;j<navBoxChild.length;j++){  
                    navBoxChild[j].className = "";  
                }  
                //选中的设为带标志的
                navBoxChild[i].className = "introCur";  
           }  
        }  
    }; 
}
        //当导航与相应文档接触的时候自动切换   
        for(var i=0;i<navBoxChild.length;i++){  
            if( scrollTop +100 >= textChild[i].offsetTop){  
                for(var j=0;j<navBoxChild.length;j++){  
                    navBoxChild[j].className = "";  
                }  
                navBoxChild[i].className = "introCur";  
           }  
        }  
    }; 
}

View Code

效果如下

图片 7

offsetTop 为元素距离页面最开始的距离。

offsetHeight为元素高度

这样省去了调整位置的麻烦。

并且设置fixed的属性为一个class,直接更改li的class名,增加这个属性。

这个代码下面展示了导航如何自动选中为哪个版块

先循环给每个li都设为不带选中的class

当滚动的高度加导航的高度大于版块内容距离上面的高度时,

也就是导航移动到版块上方时,这个版块对应的li的class名改为带选中的。

其中选中的class  Css代码如下,用到了after选择器。

图片 8图片 9

.introCur::after{
    content: '';
    display: block;
    width: 66px;
    height: 3px;
    position: absolute;
    bottom: 0;
    left: 50%;
    margin-left: -33px;
    background: #333;
}

选中的样式

二、after 和 before 伪类元素

必须跟content属性

::before和::after下特有的content,用于在css渲染中向元素逻辑上的头部或尾部添加内容。

本文由10bet发布于Web前端,转载请注明出处:滚动监听 after选择器

关键词:

最火资讯