浅谈Javascript虚拟列表(virtaul list)改造成虚拟表格(virtaul table)的技术

前端加载百万条数据列表,如果采用真实的DOM插入100万个div(或li)标签,肯定是非常卡顿的。这就不得不使用虚拟列表技术方案,但是虚拟列表技术方案网上有很详细的实现方法,今天我就来谈谈根据网上的方案,把虚拟列表改造成虚拟表格的过程。

我就直接列出代码:

index.html,里面需要引入hyperHTML-min.js,我也提供了。

<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>virtual table</title><style>.list-container {overflow: auto;border: 1px solid black;height: 500px;width: 700px;box-sizing: border-box;}.list-container-inner{}.list-container-inner .box{}.list-container-inner .box .layer1{display: table;width: 100%;height:100%;font-size:0;line-height: 0;margin: 0;padding: 0;}.list-container-inner .box .layer1 .row-box{overflow: hidden;}.list-container-inner .box .layer1 .row{box-sizing: border-box;height:calc(100% + 2px);position: relative;}.list-container-inner .box .layer1 .row .cell-box{box-sizing: border-box;position: absolute;height: 100%;overflow: hidden;}.list-container-inner .box .layer1 .cell{font-size:12px;line-height: 12px;}
/* 			.list-container-inner .box>div>div:first-child{border-left: 0px solid red;}.list-container-inner .box>div>div:last-child{border-right: 0px solid red;} */.list-container-inner .box .layer1>div>div:active{border: 0px solid red;}.wh100{width: calc(100% + 1px);padding-right: 1px;box-sizing: border-box;height: 100%;}</style><script src="./hyperHTML-min.js"></script></head><body><div id="root"></div><!-- 外部容器用来固定列表容器的高度,同时生成滚动条 --><div class="list-container"><!-- 内部容器用来装元素,高度是所有元素高度的和 --><div class="list-container-inner"><div class="box"><div class="layer1"></div><div class="layer2"></div></div></div></div><script>/** --------- 一些基本变量 -------- */const itemHeight = 60const columnWidth = 100const width = 700const height = 500const random = (min, max) => {return Math.floor(Math.random() * (max - min)) + min;}const getRandomColor = () => {let colors = ['red','blue','yellow','orange','brown','purple','pink','green','gray','mauve']return colors[random(0,10)]}/** --------- 生成数据 -------- */const getRandomHeight = () => {// 返回 [60, 150] 之间的随机数return Math.floor(Math.random() * (80 - itemHeight + 1) + itemHeight)}const getRandomWidth = () => {// 返回 [60, 150] 之间的随机数return Math.floor(Math.random() * (220 - columnWidth + 1) + columnWidth)}const columns = () => {const data = []for (let i = 0; i < 50; i++) {data.push({content:i,width:getRandomWidth(),color: getRandomColor()})}return data}const _columns = columns()const initData = () => {const data = []for (let i = 0; i < 500000; i++) {data.push({content: _columns,rowIndex:i,height: getRandomHeight(),color: i % 2 ? 'blue' : 'red'})}return data}const data = initData()const cacheWidthMap = {}const cacheHeightMap = {}const outerContainer = document.querySelector('.list-container')const scrollCallback = () => {//let contentWidth = 0let paddingLeft = 0let upperWidth = 0let startColIndexlet endColIndex//let contentHeight = 0let paddingTop = 0let upperHeight = 0let startIndexlet endIndexconst innerContainer = document.querySelector('.list-container-inner')const scrollTop = Math.max(outerContainer.scrollTop, 0)const scrollLeft = Math.max(outerContainer.scrollLeft, 0)for (let i = 0; i < (data[0] ? (data[0].content || []) : []).length; i++) {const cacheWidth = cacheWidthMap[i]const usedWidth = cacheWidth === undefined ? columnWidth : cacheWidthcontentWidth += usedWidth;if (contentWidth >= scrollLeft && startColIndex === undefined) {startColIndex = ipaddingLeft = contentWidth - usedWidth}if (contentWidth > scrollLeft + width && endColIndex === undefined) {endColIndex = iupperWidth = contentWidth}}// 遍历所有的元素,获取当前元素的高度、列表总高度、startIndex、endIndexfor (let i = 0; i < data.length; i++) {// 初始化的时候因为元素还没有渲染,无法获取元素的高度// 所以用元素的最小高度itemHeight来进行计算,保证渲染的元素个数能占满列表const cacheHeight = cacheHeightMap[i]const usedHeight = cacheHeight === undefined ? itemHeight : cacheHeightcontentHeight += usedHeightif (contentHeight >= scrollTop && startIndex === undefined) {startIndex = ipaddingTop = contentHeight - usedHeight}if (contentHeight > scrollTop + height && endIndex === undefined) {endIndex = i// console.log(endIndex,startIndex == endIndex, contentHeight, scrollTop + height) upperHeight = contentHeight}}if(endColIndex === undefined) {endColIndex = (data[0] ? (data[0].content || []) : []).length - 1upperWidth = contentWidth}// 应对列表所有元素没有占满整个容器的情况if (endIndex === undefined) {endIndex = data.length - 1upperHeight = contentHeight}const paddingRight = contentWidth - upperWidth// innerContainer.setAttribute('style', `padding-left: ${paddingLeft}px; padding-bottom: ${paddingRight}px`)// 未渲染的元素的高度由padding-top和padding-bottom代替,保证滚动条位置正确// 这里如果把设置pading的操作放在渲染元素之后,部分浏览器滚动到最后一个元素时会有问题const paddingBottom = contentHeight - upperHeightinnerContainer.setAttribute('style', `padding-left: ${paddingLeft}px; padding-right: ${paddingRight}px;padding-top: ${paddingTop}px; padding-bottom: ${paddingBottom}px`)// 从data取出要渲染的元素并渲染到容器中const viewData = data.slice(startIndex, endIndex + 1).map((item,index) => {let _item = {...item, content: item.content.slice(startColIndex, endColIndex + 1)}_item.content = _item.content.map((item,index) => {if(index==0) {item.left = 0} else {item.left = _item.content[index - 1].left + _item.content[index - 1].width}return item})return _item})// ${itemData.content.map(column => `<div class="cell-box" style="width:${column.width}px;left:${column.left}px;"><div class="wh100 cell" style="background:${getRandomColor()}">第${itemData.rowIndex}行,第${column.content}列</div></div>`)}innerContainer.querySelector('.box').style.width = (viewData[0] ? viewData[0].content : []).reduce(function(accumulator, column) {return accumulator + column.width;}, 0)+ 'px'innerContainer.querySelector('.box').style.height = viewData.map(item => item.height).reduce(function(accumulator, currentValue) {return accumulator + currentValue;}, 0) + 'px'function update(render, state) {render`${state.viewData.map(itemData => hyperHTML.wire(itemData)`<section class="row-box" style="height: ${itemData.height}px;background: ${itemData.color}"><div class="row">
${itemData.content.map(column => `<div class="cell-box" style="width:${column.width}px;left:${column.left}px;"><div class="wh100 cell" style="background:${getRandomColor()}">第${itemData.rowIndex}行,第${column.content}列</div></div>`)}</div></section>	`)}`;}const render = hyperHTML.bind(innerContainer.querySelector('.box .layer1'))update(render, {viewData:viewData})// 存储已经渲染出来的元素的高度,供后面使用const children = innerContainer.querySelector('.box .layer1').childrenconst columnChildren = innerContainer.querySelector('.box .layer1 .row').childrenlet widthFlag = startColIndexfor (const child of columnChildren) {cacheWidthMap[widthFlag] = child.clientHeightwidthFlag++}let flag = startIndexfor (const child of children) {cacheHeightMap[flag] = child.clientHeightflag++}}// 首屏渲染scrollCallback()// 监听外部容器的滚动事件outerContainer.addEventListener('scroll', scrollCallback)</script></body>
</html>

 hyperHTML-min.js

/*! (c) Andrea Giammarchi (ISC) */var hyperHTML=function(N){"use strict";var t={};try{t.WeakMap=WeakMap}catch(e){t.WeakMap=function(t,e){var n=e.defineProperty,r=e.hasOwnProperty,i=a.prototype;return i.delete=function(e){return this.has(e)&&delete e[this._]},i.get=function(e){return this.has(e)?e[this._]:void 0},i.has=function(e){return r.call(e,this._)},i.set=function(e,t){return n(e,this._,{configurable:!0,value:t}),this},a;function a(e){n(this,"_",{value:"_@ungap/weakmap"+t++}),e&&e.forEach(o,this)}function o(e){this.set(e[0],e[1])}}(Math.random(),Object)}var s=t.WeakMap,i={};try{i.WeakSet=WeakSet}catch(e){!function(e,t){var n=r.prototype;function r(){t(this,"_",{value:"_@ungap/weakmap"+e++})}n.add=function(e){return this.has(e)||t(e,this._,{value:!0,configurable:!0}),this},n.has=function(e){return this.hasOwnProperty.call(e,this._)},n.delete=function(e){return this.has(e)&&delete e[this._]},i.WeakSet=r}(Math.random(),Object.defineProperty)}function m(e,t,n,r,i,a){for(var o=("selectedIndex"in t),u=o;r<i;){var c,l=e(n[r],1);t.insertBefore(l,a),o&&u&&l.selected&&(u=!u,c=t.selectedIndex,t.selectedIndex=c<0?r:f.call(t.querySelectorAll("option"),l)),r++}}function y(e,t){return e==t}function b(e){return e}function w(e,t,n,r,i,a,o){var u=a-i;if(u<1)return-1;for(;u<=n-t;){for(var c=t,l=i;c<n&&l<a&&o(e[c],r[l]);)c++,l++;if(l===a)return t;t=c+1}return-1}function x(e,t,n,r,i){return n<r?e(t[n],0):0<n?e(t[n-1],-0).nextSibling:i}function E(e,t,n,r){for(;n<r;)a(e(t[n++],-1))}function C(e,t,n,r,i,a,o,u,c,l,s,f,h){!function(e,t,n,r,i,a,o,u,c){for(var l=[],s=e.length,f=o,h=0;h<s;)switch(e[h++]){case 0:i++,f++;break;case 1:l.push(r[i]),m(t,n,r,i++,i,f<u?t(a[f],0):c);break;case-1:f++}for(h=0;h<s;)switch(e[h++]){case 0:o++;break;case-1:-1<l.indexOf(a[o])?o++:E(t,a,o++,o)}}(function(e,t,n,r,i,a,o){var u,c,l,s,f,h,d=n+a,v=[];e:for(m=0;m<=d;m++){if(50<m)return null;for(h=m-1,s=m?v[m-1]:[0,0],f=v[m]=[],u=-m;u<=m;u+=2){for(c=(l=u===-m||u!==m&&s[h+u-1]<s[h+u+1]?s[h+u+1]:s[h+u-1]+1)-u;l<a&&c<n&&o(r[i+l],e[t+c]);)l++,c++;if(l===a&&c===n)break e;f[m+u]=l}}for(var p=Array(m/2+d/2),g=p.length-1,m=v.length-1;0<=m;m--){for(;0<l&&0<c&&o(r[i+l-1],e[t+c-1]);)p[g--]=0,l--,c--;if(!m)break;h=m-1,s=m?v[m-1]:[0,0],(u=l-c)===-m||u!==m&&s[h+u-1]<s[h+u+1]?(c--,p[g--]=1):(l--,p[g--]=-1)}return p}(n,r,a,o,u,l,f)||function(e,t,n,r,i,a,o,u){var c=0,l=r<u?r:u,s=Array(l++),f=Array(l);f[0]=-1;for(var h=1;h<l;h++)f[h]=o;for(var d=i.slice(a,o),v=t;v<n;v++){var p,g=d.indexOf(e[v]);-1<g&&(-1<(c=k(f,l,p=g+a))&&(f[c]=p,s[c]={newi:v,oldi:p,prev:s[c-1]}))}for(c=--l,--o;f[c]>o;)--c;l=u+r-c;var m=Array(l),y=s[c];for(--n;y;){for(var b=y.newi,w=y.oldi;b<n;)m[--l]=1,--n;for(;w<o;)m[--l]=-1,--o;m[--l]=0,--n,--o,y=y.prev}for(;t<=n;)m[--l]=1,--n;for(;a<=o;)m[--l]=-1,--o;return m}(n,r,i,a,o,u,c,l),e,t,n,r,o,u,s,h)}var e=i.WeakSet,f=[].indexOf,k=function(e,t,n){for(var r=1,i=t;r<i;){var a=(r+i)/2>>>0;n<e[a]?i=a:r=1+a}return r},a=function(e){return(e.remove||function(){var e=this.parentNode;e&&e.removeChild(this)}).call(e)};function l(e,t,n,r){for(var i=(r=r||{}).compare||y,a=r.node||b,o=null==r.before?null:a(r.before,0),u=t.length,c=u,l=0,s=n.length,f=0;l<c&&f<s&&i(t[l],n[f]);)l++,f++;for(;l<c&&f<s&&i(t[c-1],n[s-1]);)c--,s--;var h=l===c,d=f===s;if(h&&d)return n;if(h&&f<s)return m(a,e,n,f,s,x(a,t,l,u,o)),n;if(d&&l<c)return E(a,t,l,c),n;var v=c-l,p=s-f,g=-1;if(v<p){if(-1<(g=w(n,f,s,t,l,c,i)))return m(a,e,n,f,g,a(t[l],0)),m(a,e,n,g+v,s,x(a,t,c,u,o)),n}else if(p<v&&-1<(g=w(t,l,c,n,f,s,i)))return E(a,t,l,g),E(a,t,g+p,c),n;return v<2||p<2?(m(a,e,n,f,s,a(t[l],0)),E(a,t,l,c)):v==p&&function(e,t,n,r,i,a){for(;r<i&&a(n[r],e[t-1]);)r++,t--;return 0===t}(n,s,t,l,c,i)?m(a,e,n,f,s,x(a,t,c,u,o)):C(a,e,n,f,s,p,t,l,c,v,u,i,o),n}var n,r={};function o(e,t){t=t||{};var n=N.createEvent("CustomEvent");return n.initCustomEvent(e,!!t.bubbles,!!t.cancelable,t.detail),n}r.CustomEvent="function"==typeof CustomEvent?CustomEvent:(o[n="prototype"]=new o("").constructor[n],o);var u=r.CustomEvent,c={};try{c.Map=Map}catch(e){c.Map=function(){var n=0,i=[],a=[];return{delete:function(e){var t=r(e);return t&&(i.splice(n,1),a.splice(n,1)),t},forEach:function(n,r){i.forEach(function(e,t){n.call(r,a[t],e,this)},this)},get:function(e){return r(e)?a[n]:void 0},has:r,set:function(e,t){return a[r(e)?n:i.push(e)-1]=t,this}};function r(e){return-1<(n=i.indexOf(e))}}}var h=c.Map;function d(){return this}function v(e,t){var n="_"+e+"$";return{get:function(){return this[n]||p(this,n,t.call(this,e))},set:function(e){p(this,n,e)}}}var p=function(e,t,n){return Object.defineProperty(e,t,{configurable:!0,value:"function"==typeof n?function(){return e._wire$=n.apply(this,arguments)}:n})[t]};Object.defineProperties(d.prototype,{ELEMENT_NODE:{value:1},nodeType:{value:-1}});var g,A,S,O,T,M,_={},j={},L=[],P=j.hasOwnProperty,D=0,W={attributes:_,define:function(e,t){e.indexOf("-")<0?(e in j||(D=L.push(e)),j[e]=t):_[e]=t},invoke:function(e,t){for(var n=0;n<D;n++){var r=L[n];if(P.call(e,r))return j[r](e[r],t)}}},$=Array.isArray||(A=(g={}.toString).call([]),function(e){return g.call(e)===A}),R=(S=N,O="fragment",M="content"in H(T="template")?function(e){var t=H(T);return t.innerHTML=e,t.content}:function(e){var t,n=H(O),r=H(T);return F(n,/^[^\S]*?<(col(?:group)?|t(?:head|body|foot|r|d|h))/i.test(e)?(t=RegExp.$1,r.innerHTML="<table>"+e+"</table>",r.querySelectorAll(t)):(r.innerHTML=e,r.childNodes)),n},function(e,t){return("svg"===t?function(e){var t=H(O),n=H("div");return n.innerHTML='<svg xmlns="http://www.w3.org/2000/svg">'+e+"</svg>",F(t,n.firstChild.childNodes),t}:M)(e)});function F(e,t){for(var n=t.length;n--;)e.appendChild(t[0])}function H(e){return e===O?S.createDocumentFragment():S.createElementNS("http://www.w3.org/1999/xhtml",e)}var I,z,V,Z,G,q,B,J,K,Q,U=(z="appendChild",V="cloneNode",Z="createTextNode",q=(G="importNode")in(I=N),(B=I.createDocumentFragment())[z](I[Z]("g")),B[z](I[Z]("")),(q?I[G](B,!0):B[V](!0)).childNodes.length<2?function e(t,n){for(var r=t[V](),i=t.childNodes||[],a=i.length,o=0;n&&o<a;o++)r[z](e(i[o],n));return r}:q?I[G]:function(e,t){return e[V](!!t)}),X="".trim||function(){return String(this).replace(/^\s+|\s+/g,"")},Y="-"+Math.random().toFixed(6)+"%",ee=!1;try{J=N.createElement("template"),Q="tabindex",(K="content")in J&&(J.innerHTML="<p "+Q+'="'+Y+'"></p>',J[K].childNodes[0].getAttribute(Q)==Y)||(Y="_dt: "+Y.slice(1,-1)+";",ee=!0)}catch(e){}var te="\x3c!--"+Y+"--\x3e",ne=8,re=1,ie=3,ae=/^(?:style|textarea)$/i,oe=/^(?:area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr)$/i;var ue=" \\f\\n\\r\\t",ce="[^"+ue+"\\/>\"'=]+",le="["+ue+"]+"+ce,se="<([A-Za-z]+[A-Za-z0-9:._-]*)((?:",fe="(?:\\s*=\\s*(?:'[^']*?'|\"[^\"]*?\"|<[^>]*?>|"+ce.replace("\\/","")+"))?)",he=new RegExp(se+le+fe+"+)(["+ue+"]*/?>)","g"),de=new RegExp(se+le+fe+"*)(["+ue+"]*/>)","g"),ve=new RegExp("("+le+"\\s*=\\s*)(['\"]?)"+te+"\\2","gi");function pe(e,t,n,r){return"<"+t+n.replace(ve,ge)+r}function ge(e,t,n){return t+(n||'"')+Y+(n||'"')}function me(e,t,n){return oe.test(t)?e:"<"+t+n+"></"+t+">"}var ye=ee?function(e,t){var n=t.join(" ");return t.slice.call(e,0).sort(function(e,t){return n.indexOf(e.name)<=n.indexOf(t.name)?-1:1})}:function(e,t){return t.slice.call(e,0)};function be(e,t,n,r){for(var i=e.childNodes,a=i.length,o=0;o<a;){var u=i[o];switch(u.nodeType){case re:var c=r.concat(o);!function(e,t,n,r){var i,a=e.attributes,o=[],u=[],c=ye(a,n),l=c.length,s=0;for(;s<l;){var f=c[s++],h=f.value===Y;if(h||1<(i=f.value.split(te)).length){var d=f.name;if(o.indexOf(d)<0){o.push(d);var v=n.shift().replace(h?/^(?:|[\S\s]*?\s)(\S+?)\s*=\s*('|")?$/:new RegExp("^(?:|[\\S\\s]*?\\s)("+d+")\\s*=\\s*('|\")[\\S\\s]*","i"),"$1"),p=a[v]||a[v.toLowerCase()];if(h)t.push(we(p,r,v,null));else{for(var g=i.length-2;g--;)n.shift();t.push(we(p,r,v,i))}}u.push(f)}}l=u.length;var m=(s=0)<l&&ee&&!("ownerSVGElement"in e);for(;s<l;){var y=u[s++];m&&(y.value=""),e.removeAttribute(y.name)}var b=e.nodeName;if(/^script$/i.test(b)){var w=N.createElement(b);for(l=a.length,s=0;s<l;)w.setAttributeNode(a[s++].cloneNode(!0));w.textContent=e.textContent,e.parentNode.replaceChild(w,e)}}(u,t,n,c),be(u,t,n,c);break;case ne:var l=u.textContent;if(l===Y)n.shift(),t.push(ae.test(e.nodeName)?Ne(e,r):{type:"any",node:u,path:r.concat(o)});else switch(l.slice(0,2)){case"/*":if("*/"!==l.slice(-2))break;case"馃懟":e.removeChild(u),o--,a--}break;case ie:ae.test(e.nodeName)&&X.call(u.textContent)===te&&(n.shift(),t.push(Ne(e,r)))}o++}}function we(e,t,n,r){return{type:"attr",node:e,path:t,name:n,sparse:r}}function Ne(e,t){return{type:"text",node:e,path:t}}var xe,Ee=(xe=new s,{get:function(e){return xe.get(e)},set:function(e,t){return xe.set(e,t),t}});function Ce(o,f){var e=(o.convert||function(e){return e.join(te).replace(de,me).replace(he,pe)})(f),t=o.transform;t&&(e=t(e));var n=R(e,o.type);Se(n);var u=[];return be(n,u,f.slice(0),[]),{content:n,updates:function(c){for(var l=[],s=u.length,e=0,t=0;e<s;){var n=u[e++],r=function(e,t){for(var n=t.length,r=0;r<n;)e=e.childNodes[t[r++]];return e}(c,n.path);switch(n.type){case"any":l.push({fn:o.any(r,[]),sparse:!1});break;case"attr":var i=n.sparse,a=o.attribute(r,n.name,n.node);null===i?l.push({fn:a,sparse:!1}):(t+=i.length-2,l.push({fn:a,sparse:!0,values:i}));break;case"text":l.push({fn:o.text(r),sparse:!1}),r.textContent=""}}return s+=t,function(){var e=arguments.length;if(s!==e-1)throw new Error(e-1+" values instead of "+s+"\n"+f.join("${value}"));for(var t=1,n=1;t<e;){var r=l[t-n];if(r.sparse){var i=r.values,a=i[0],o=1,u=i.length;for(n+=u-2;o<u;)a+=arguments[t++]+i[o++];r.fn(a)}else r.fn(arguments[t++])}return c}}}}var ke=[];function Ae(i){var a=ke,o=Se;return function(e){var t,n,r;return a!==e&&(t=i,n=a=e,r=Ee.get(n)||Ee.set(n,Ce(t,n)),o=r.updates(U.call(N,r.content,!0))),o.apply(null,arguments)}}function Se(e){for(var t=e.childNodes,n=t.length;n--;){var r=t[n];1!==r.nodeType&&0===X.call(r.textContent).length&&e.removeChild(r)}}var Oe,Te,Me=(Oe=/acit|ex(?:s|g|n|p|$)|rph|ows|mnc|ntw|ine[ch]|zoo|^ord/i,Te=/([^A-Z])([A-Z]+)/g,function(e,t){return"ownerSVGElement"in e?function(e,t){var n;return(n=t?t.cloneNode(!0):(e.setAttribute("style","--hyper:style;"),e.getAttributeNode("style"))).value="",e.setAttributeNode(n),je(n,!0)}(e,t):je(e.style,!1)});function _e(e,t,n){return t+"-"+n.toLowerCase()}function je(a,o){var u,c;return function(e){var t,n,r,i;switch(typeof e){case"object":if(e){if("object"===u){if(!o&&c!==e)for(n in c)n in e||(a[n]="")}else o?a.value="":a.cssText="";for(n in t=o?{}:a,e)r="number"!=typeof(i=e[n])||Oe.test(n)?i:i+"px",!o&&/^--/.test(n)?t.setProperty(n,r):t[n]=r;u="object",o?a.value=function(e){var t,n=[];for(t in e)n.push(t.replace(Te,_e),":",e[t],";");return n.join("")}(c=t):c=e;break}default:c!=e&&(u="string",c=e,o?a.value=e||"":a.cssText=e||"")}}}var Le,Pe,De=(Le=[].slice,(Pe=We.prototype).ELEMENT_NODE=1,Pe.nodeType=111,Pe.remove=function(e){var t,n=this.childNodes,r=this.firstChild,i=this.lastChild;return this._=null,e&&2===n.length?i.parentNode.removeChild(i):((t=this.ownerDocument.createRange()).setStartBefore(e?n[1]:r),t.setEndAfter(i),t.deleteContents()),r},Pe.valueOf=function(e){var t=this._,n=null==t;if(n&&(t=this._=this.ownerDocument.createDocumentFragment()),n||e)for(var r=this.childNodes,i=0,a=r.length;i<a;i++)t.appendChild(r[i]);return t},We);function We(e){var t=this.childNodes=Le.call(e,0);this.firstChild=t[0],this.lastChild=t[t.length-1],this.ownerDocument=t[0].ownerDocument,this._=null}function $e(e){return{html:e}}function Re(e,t){switch(e.nodeType){case Ke:return 1/t<0?t?e.remove(!0):e.lastChild:t?e.valueOf(!0):e.firstChild;case Je:return Re(e.render(),t);default:return e}}function Fe(e,t){t(e.placeholder),"text"in e?Promise.resolve(e.text).then(String).then(t):"any"in e?Promise.resolve(e.any).then(t):"html"in e?Promise.resolve(e.html).then($e).then(t):Promise.resolve(W.invoke(e,t)).then(t)}function He(e){return null!=e&&"then"in e}var Ie,ze,Ve,Ze,Ge,qe="ownerSVGElement",Be="connected",Je=d.prototype.nodeType,Ke=De.prototype.nodeType,Qe=(ze=(Ie={Event:u,WeakSet:e}).Event,Ve=Ie.WeakSet,Ze=!0,Ge=null,function(e){return Ze&&(Ze=!Ze,Ge=new Ve,function(t){var i=new Ve,a=new Ve;try{new MutationObserver(u).observe(t,{subtree:!0,childList:!0})}catch(e){var n=0,r=[],o=function(e){r.push(e),clearTimeout(n),n=setTimeout(function(){u(r.splice(n=0,r.length))},0)};t.addEventListener("DOMNodeRemoved",function(e){o({addedNodes:[],removedNodes:[e.target]})},!0),t.addEventListener("DOMNodeInserted",function(e){o({addedNodes:[e.target],removedNodes:[]})},!0)}function u(e){for(var t,n=e.length,r=0;r<n;r++)c((t=e[r]).removedNodes,"disconnected",a,i),c(t.addedNodes,"connected",i,a)}function c(e,t,n,r){for(var i,a=new ze(t),o=e.length,u=0;u<o;1===(i=e[u++]).nodeType&&function e(t,n,r,i,a){Ge.has(t)&&!i.has(t)&&(a.delete(t),i.add(t),t.dispatchEvent(n));for(var o=t.children||[],u=o.length,c=0;c<u;e(o[c++],n,r,i,a));}(i,a,t,n,r));}}(e.ownerDocument)),Ge.add(e),e}),Ue=/^(?:form|list)$/i,Xe=[].slice;function Ye(e){return this.type=e,Ae(this)}var et=!(Ye.prototype={attribute:function(n,r,e){var i,t=qe in n;if("style"===r)return Me(n,e,t);if("."===r.slice(0,1))return l=n,s=r.slice(1),t?function(t){try{l[s]=t}catch(e){l.setAttribute(s,t)}}:function(e){l[s]=e};if("?"===r.slice(0,1))return o=n,u=r.slice(1),function(e){c!==!!e&&((c=!!e)?o.setAttribute(u,""):o.removeAttribute(u))};if(/^on/.test(r)){var a=r.slice(2);return a===Be||"disconnected"===a?Qe(n):r.toLowerCase()in n&&(a=a.toLowerCase()),function(e){i!==e&&(i&&n.removeEventListener(a,i,!1),(i=e)&&n.addEventListener(a,e,!1))}}if("data"===r||!t&&r in n&&!Ue.test(r))return function(e){i!==e&&(i=e,n[r]!==e&&null==e?(n[r]="",n.removeAttribute(r)):n[r]=e)};if(r in W.attributes)return function(e){var t=W.attributes[r](n,e);i!==t&&(null==(i=t)?n.removeAttribute(r):n.setAttribute(r,t))};var o,u,c,l,s,f=!1,h=e.cloneNode(!0);return function(e){i!==e&&(i=e,h.value!==e&&(null==e?(f&&(f=!1,n.removeAttributeNode(h)),h.value=e):(h.value=e,f||(f=!0,n.setAttributeNode(h)))))}},any:function(r,i){var a,o={node:Re,before:r},u=qe in r?"svg":"html",c=!1;return function e(t){switch(typeof t){case"string":case"number":case"boolean":c?a!==t&&(a=t,i[0].textContent=t):(c=!0,a=t,i=l(r.parentNode,i,[(n=t,r.ownerDocument.createTextNode(n))],o));break;case"function":e(t(r));break;case"object":case"undefined":if(null==t){c=!1,i=l(r.parentNode,i,[],o);break}default:if(c=!1,$(a=t))if(0===t.length)i.length&&(i=l(r.parentNode,i,[],o));else switch(typeof t[0]){case"string":case"number":case"boolean":e({html:t});break;case"object":if($(t[0])&&(t=t.concat.apply([],t)),He(t[0])){Promise.all(t).then(e);break}default:i=l(r.parentNode,i,t,o)}else"ELEMENT_NODE"in t?i=l(r.parentNode,i,11===t.nodeType?Xe.call(t.childNodes):[t],o):He(t)?t.then(e):"placeholder"in t?Fe(t,e):"text"in t?e(String(t.text)):"any"in t?e(t.any):"html"in t?i=l(r.parentNode,i,Xe.call(R([].concat(t.html).join(""),u).childNodes),o):"length"in t?e(Xe.call(t)):e(W.invoke(t,e))}var n}},text:function(r){var i;return function e(t){var n;i!==t&&("object"==(n=typeof(i=t))&&t?He(t)?t.then(e):"placeholder"in t?Fe(t,e):"text"in t?e(String(t.text)):"any"in t?e(t.any):"html"in t?e([].concat(t.html).join("")):"length"in t?e(Xe.call(t).join("")):e(W.invoke(t,e)):"function"==n?e(t(r)):r.textContent=null==t?"":t)}}}),tt=function(e){var t,r,i,a,n=(t=(N.defaultView.navigator||{}).userAgent,/(Firefox|Safari)\/(\d+)/.test(t)&&!/(Chrom[eium]+|Android)\/(\d+)/.test(t)),o=!("raw"in e)||e.propertyIsEnumerable("raw")||!Object.isFrozen(e.raw);return n||o?(r={},i=function(e){for(var t=".",n=0;n<e.length;n++)t+=e[n].length+"."+e[n];return r[t]||(r[t]=e)},tt=o?i:(a=new s,function(e){return a.get(e)||(n=i(t=e),a.set(t,n),n);var t,n})):et=!0,nt(e)};function nt(e){return et?e:tt(e)}function rt(e){for(var t=arguments.length,n=[nt(e)],r=1;r<t;)n.push(arguments[r++]);return n}var it=new s,at=function(t){var n,r,i;return function(){var e=rt.apply(null,arguments);return i!==e[0]?(i=e[0],r=new Ye(t),n=ut(r.apply(r,e))):r.apply(r,e),n}},ot=function(e,t){var n=t.indexOf(":"),r=it.get(e),i=t;return-1<n&&(i=t.slice(n+1),t=t.slice(0,n)||"html"),r||it.set(e,r={}),r[i]||(r[i]=at(t))},ut=function(e){var t=e.childNodes,n=t.length;return 1===n?t[0]:n?new De(t):e},ct=new s;function lt(){var e=ct.get(this),t=rt.apply(null,arguments);return e&&e.template===t[0]?e.tagger.apply(null,t):function(e){var t=new Ye(qe in this?"svg":"html");ct.set(this,{tagger:t,template:e}),this.textContent="",this.appendChild(t.apply(null,arguments))}.apply(this,t),this}var st,ft,ht,dt,vt=W.define,pt=Ye.prototype;function gt(e){return arguments.length<2?null==e?at("html"):"string"==typeof e?gt.wire(null,e):"raw"in e?at("html")(e):"nodeType"in e?gt.bind(e):ot(e,"html"):("raw"in e?at("html"):gt.wire).apply(null,arguments)}return gt.Component=d,gt.bind=function(e){return lt.bind(e)},gt.define=vt,gt.diff=l,(gt.hyper=gt).observe=Qe,gt.tagger=pt,gt.wire=function(e,t){return null==e?at(t||"html"):ot(e,t||"html")},gt._={WeakMap:s,WeakSet:e},st=at,ft=new s,ht=Object.create,dt=function(e,t){var n={w:null,p:null};return t.set(e,n),n},Object.defineProperties(d,{for:{configurable:!0,value:function(e,t){return function(e,t,n,r){var i,a,o,u=t.get(e)||dt(e,t);switch(typeof r){case"object":case"function":var c=u.w||(u.w=new s);return c.get(r)||(i=c,a=r,o=new e(n),i.set(a,o),o);default:var l=u.p||(u.p=ht(null));return l[r]||(l[r]=new e(n))}}(this,ft.get(e)||(n=e,r=new h,ft.set(n,r),r),e,null==t?"default":t);var n,r}}}),Object.defineProperties(d.prototype,{handleEvent:{value:function(e){var t=e.currentTarget;this["getAttribute"in t&&t.getAttribute("data-call")||"on"+e.type](e)}},html:v("html",st),svg:v("svg",st),state:v("state",function(){return this.defaultState}),defaultState:{get:function(){return{}}},dispatch:{value:function(e,t){var n=this._wire$;if(n){var r=new u(e,{bubbles:!0,cancelable:!0,detail:t});return r.component=this,(n.dispatchEvent?n:n.firstChild).dispatchEvent(r)}return!1}},setState:{value:function(e,t){var n=this.state,r="function"==typeof e?e.call(this,n):e;for(var i in r)n[i]=r[i];return!1!==t&&this.render(),this}}}),gt}(document);

原理 我就不过多赘述,主要就是说以下优点和缺点:

1、在27万条数据以内,背景填充没有问题。超过27万的div的背景不能正确填充div绘制的范围,导致看上去上下间有问题,有一条白色的水平线条。曾做过如下方法解决:

 a 、我已经把font-size改为0了,不能解决。

b、把padding-top padding-bottom 改为 真实的元素占位,不能解决。因为我以为这情况回事padding导致。

c、也把div从 position static 改为 absolute 定位来解决,发现也与这个无关。

d、设置过background相关的参数,不能解决。

通过审查解决,是背景不能填充,确定是背景的问题。如果是在firfox,低于27万就出现这种问题了。

上图是垂直方向的问题,水平方向也会这种问题,我就不截图了。

2、超过27万以后的数据在chrome浏览器中,当滚动时候,出现渲染不准确问题,比如说border都设置为1px,但是看上去并不一致,outline也一样。而且有时候应该隐藏outline的时候,还是出现一些颜色在边上,不知道是不是显卡问题,但是浏览器渲染div又不用显卡。

3、这种方案,从百万数据中找到 屏幕可视数据的算法是非常棒的!经过有以上问题,但是性能非常好,别说100万,200万也就秒渲染,只是渲染后有一些问题。

4、padding填充内部实现内部内容高度的增高大约只支持到 55.92w条左右,超过这个数,将无法显示,因为chrome浏览器似乎支持的最大padding-bottom的值是33551640px,所以如果有需要超过这个值的需求,padding撑起内部内容高度实现滚动条是不可取的,必须自定义滚动条支持超过55.9万条的数据。

总结,如果实际需求中碰不到超过10万条的数据,这种方式处理10万条的数据,还是很优秀的,但是我想要他支持百万,可超过27万就出现了不可解决的问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/765667.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ChatGPT:提升论文写作能力

ChatGPT无限次数:点击直达 ChatGPT&#xff1a;开启智能对话&#xff0c;提升论文写作能力 ChatGPT是一款强大的人工智能对话引擎&#xff0c;它不仅可以帮助用户进行智能对话&#xff0c;还能在论文写作中发挥重要作用。本文将探讨如何利用ChatGPT提升论文写作能力&#xff0c…

Educational Codeforces Round 163 (Rated for Div. 2)(A,B,C,D,E)

比赛链接 好忙好忙好忙&#xff0c;慢慢补老比赛的题解了。 这场没啥算法&#xff0c;全是思维。有也是BFS&#xff0c;屎。 A. Special Characters 题意&#xff1a; 您将得到一个整数 n n n 。 您的任务是构建一串大写的拉丁字母。此字符串中必须正好有 n n n 个特殊字…

Docker - 哲学 默认网络和 自定义网络 与 linux 网络类型 和 overlay2

默认网络&#xff1a;不指定 --nerwork 不指定 网络 run 一个容器时&#xff0c;会直接使用默认的网络桥接器 &#xff08;docker0&#xff09; 自定义网络&#xff1a;指定 --nerwork 让这两台容器互相通信 的前提 - 共享同一个网络 关于 ip addr 显示 ens160 储存驱动 ov…

入门linux之Ubuntu学习

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言1、介绍Ubuntu2、虚拟机目录解析3、常用指令ls&#xff1a;罗列当前目录文件信息对ls -l 的结果解析1.第一个字符2.每三个字符&#xff08;第一个字符后&#x…

jmeter超高并发报错解决方法

1、比如jmeter设置并发量为5000&#xff0c;运行后报错socket closed。原因是客户端与服务端做了三次握手之后&#xff0c;后面不需要握手了&#xff0c;但是jmeter没有这个功能&#xff0c;5000个并发每次发接口请求都是独立的&#xff0c;jmeter端口处理不了这么大量的请求&a…

【嵌入式DIY实例】-DIY 灌水机

DIY 灌水机 文章目录 DIY 灌水机1、硬件准备2、YF-S201 霍尔效应水流量传感器介绍3、4x4矩阵键盘4、硬件接线5、代码实现在这个项目中,我们将使用流量传感器和 Arduino 构建一个水灌装机。用户使用 44 键盘输入液体总量。泵在收到用户输入后抽取准确数量的水。当准确数量完成后…

v-for=“item in arr“ 的理解

在 Vue.js 中&#xff0c;v-for 是一个指令&#xff0c;用于在模板中渲染一个列表的数据。v-for"item in arr" 这个语法中&#xff0c;item 和 arr 分别代表以下含义&#xff1a; item: item 是当前迭代到的数组元素或对象的别名。在每次迭代中&#xff0c;item 会被…

Android视角看鸿蒙第八课(module.json5中的各字段含义之abilities)下

Android视角看鸿蒙第八课(module.json5中的各字段含义之abilities&#xff09;下 导读 上篇文章开始学习abilities下的各字段含义&#xff0c;因为篇幅原因只学习了name、srcEntry、description、icon和label字段的含义和用法&#xff0c; 这篇文章继续学习和了解其他字段。 …

GPT4.0

GPT4.0 支持官网所有功能以及所有第三方GPTS&#xff0c;完全同步官网。无需魔法&#xff0c;填写授权码直达官网。全天超18小时维护&#xff0c;无需担心不稳定。没有永久卡&#xff0c;3.5免费提供&#xff0c;4.0可以按需下单即可&#xff0c;不存在跑路。 需要的联系

格瑞纳电子邀您参观2024杭州快递物流展

2024长三角快递物流供应链与技术装备展览会 2024.7.8-10 杭州国际博览中心 参展企业介绍 北京格瑞纳电子产品有限公司是一家立足于专业科学技术领域集产品代理、培训咨询和个性化增值服务的高科技公司&#xff0c;于2009年成立于北京&#xff0c;立足于复杂系统仿真领域&…

皓学IT:WEB06_ EL表达式JSTL标签库

一、EL表达式 1.1.特点 是一个由java开发的工具包 用于从特定域对象中读取并写入到响应体开发任务&#xff0c;不能向域对象中写入。 EL工具包自动存在Tomcat的lib中&#xff08;el-api.jar&#xff09;&#xff0c;开发是可以直接使用&#xff0c;无需其他额外的包。 标准…

seleniumUI自动化实例(登录CSDN页面)

今天分享一个CSDN登录模块的登录场景 1.配置文件 CSDNconf.py&#xff1a; from selenium import webdriver options webdriver.ChromeOptions() options.binary_location r"D:\Program Files\360\360se6\Application\360se.exe" # 360浏览器安装地址 driver w…

电脑审计系统知多少

域智盾的电脑审计系统是一款功能强大的软件&#xff0c;主要用于监控和审计电脑的使用情况。通过安装该系统&#xff0c;组织能够全面了解员工的电脑活动。 首先&#xff0c;该系统能够详细记录用户的上网记录&#xff0c;包括访问的网站、浏览的网页内容等。这使得管理员可以监…

剑指offer面试题42 翻转字符顺序 VS 左旋字符串

考察点 字符串遍历知识点 题目 分析 类似这种题目只能观察元素特点找出规律确定算法了&#xff0c;像第一道题目翻转单词顺序&#xff0c;我们可以很容易的得到翻转每个字符后的的字符串&#xff0c;再仔细观察一下紧接着以空格为间隔分别翻转俩边的字符串就可以解这道题目了…

鸿蒙Harmony应用开发—ArkTS-@Provide装饰器和@Consume装饰器:与后代组件双向同步

Provide和Consume&#xff0c;应用于与后代组件的双向数据同步&#xff0c;应用于状态数据在多个层级之间传递的场景。不同于上文提到的父子组件之间通过命名参数机制传递&#xff0c;Provide和Consume摆脱参数传递机制的束缚&#xff0c;实现跨层级传递。 其中Provide装饰的变…

YOLOv8 如何实现多主干特征融合方式 | GhostNet+ShuffleNet / SwinTransformer+ShuffleNet

文章目录 前言模块添加方法双特征提取例子`GhostNet+ShuffleNet` 双主干结构图代码`Swin+ShuffleNet` 双主干结构图代码参数量与计算量1. 什么是YOLO-Magic框架?2. 如何加入这个框架?3. 加入后如何使用框架?4. GitHub组织是什么?

LeetCode-热题100:39.组合总和

题目描述 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 &#xff0c;并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个 数字可以 无限制重复被…

使用 Python 读取 Word 文件

使用 Python 读取 Word 文件 0. 引言安装必要的库 1. 读取和提取 Word 文件中的文本2. 提取 Word 文件中的图片 0. 引言 要使用 Python 读取 Word 文件并识别其中的对象&#xff08;如图片&#xff09;和文本&#xff0c;你可以使用 python-docx 库来处理文本&#xff0c;和 d…

大数定律与中心极限定理

大数定律与中心极限定理 大数定律切比雪夫不等式依概率收敛切比雪夫大数定律辛钦大数定律伯努利大数定律 中心极限定理列维-林德伯格中心极限定理&#xff08;Lindeberg-Levy central limit theorem&#xff09;棣莫弗-拉普拉斯中心极限定理&#xff08;De Moivre-Laplace cent…

【运放】LM358和LM324

&#x1f6a9; WRITE IN FRONT &#x1f6a9; &#x1f50e; 介绍&#xff1a;"謓泽"正在路上朝着"攻城狮"方向"前进四" &#x1f50e;&#x1f3c5; 荣誉&#xff1a;2021|2022年度博客之星物联网与嵌入式开发TOP5|TOP4、2021|2222年获评…