自定义指令

242 阅读4分钟
https://gitee.com/lolicode/scui
https://github.com/chuzhixin/vue-admin-better?utm_source=gold_browser_extension
https://docs.developer.amazonservices.com/en_US/fba_inbound/FBAInbound_CreateInboundShipmentPlan.html

https://zhile.io/2020/11/18/jetbrains-eval-reset.html
https://cloud.tencent.com/document/product/1464/58556
1.  inset:

    0px

    ;

1.  object-fit: contain;
setTimeout(() => {
  // 插入十万条数据
  const total = 100000;
  // 一次插入的数据
  const once = 20;
  // 插入数据需要的次数
  const loopCount = Math.ceil(total / once);
  let countOfRender = 0;
  const ul = document.querySelector('ul');
  // 添加数据的方法
  function add() {
    const fragment = document.createDocumentFragment();
    for(let i = 0; i < once; i++) {
      const li = document.createElement('li');
      li.innerText = Math.floor(Math.random() * total);
      fragment.appendChild(li);
    }
    ul.appendChild(fragment);
    countOfRender += 1;
    loop();
  }
  function loop() {
    if(countOfRender < loopCount) {
      window.requestAnimationFrame(add);
    }
  }
  loop();
}, 0)

原理: 渲染大数据时,合理使用createDocumentFragment和requestAnimationFrame,将操作切分为一小段一小段执行。

documentFragment:

    是一个虚拟的Dom列表,可以储存待处理的xml片段(el元素),因为他不在真实的Dom结构中,所以对它所做的操作不会触发浏览器的回流,只会在他插入dom的时候触发一次而已。

    上面把多个动态生成的div插入到了虚拟节点里,在最后完成之后只做了一次插入,这样就只会触发一次回流。
但是在数量太多的时候,哪怕是一次插入,也会因为浏览器渲染不过来导致失去响应,这时候就需要增加一定的时间间隔,可以使用setTimeout,也可以使用一个api------requestAnimationFrame

requestAnimationFrame()

    1.方法是为了动画 专门使用的api,在通常的动画中会定义一个定时器来几秒几秒的发生变化,但是为了性能和更加方便,它提供了这个可以在1秒钟运行大约60次(≈16.7ms)回调的api。
而且会把这一刻所有的dom操作缓存起来,在一次回流重绘中完成操作,它的每次调用并不是指定时间的,而是跟紧浏览器的刷新频率,所以可以做到:在浏览器的刷新频率时进行回流,保证性能效率。
当页面不是激活状态的情况下,这个函数将会停止回调,进行暂停来节省cpu操作。激活时再继续。
在元素隐藏时不会进行重绘回流。

    2.它的返回值为一个long的标识符,和settimeout一样,可以调用cancelAnimationFrame() 传入这个标识符来取消这个回调。
使用这个可以在浏览器下一次’刷新’的时候运行指定的回调,在这里来插入这多个节点。
使用这样可以大批量插入很多数据 页面也不会失去响应卡住,可以保证比较好的性能

   var arr = box,
                        arrLength = arr.length,
                        totalPage = Math.ceil(arrLength / 30),//总页数
                        pageObj = {},
                        remainder = arrLength % 30;//余数;
                    for (var i = 1; i <= totalPage; i++) {
                        var size = 30,
                            start = (i - 1) * size;

                        if (i === 1) {
                            pageObj[1] = arr.slice(0, size);
                        } else {
                            if (i === totalPage && remainder) {
                                pageObj[i] = arr.slice(start, start + remainder);
                            } else {
                                pageObj[i] = arr.slice(start, i * size);
                            }
                        }
                    }
 // 变量scrollTop为当前页面的滚动条纵坐标位置
    let scrollTop =
      document.documentElement.scrollTop || document.body.scrollTop;
    // 变量 windowHeight 是可视区的高度
    let windowHeight =
      document.documentElement.clientHeight || document.body.clientHeight;
    // 变量 scrollHeight 是滚动条的总高度
    let scrollHeight =
      document.documentElement.scrollHeight || document.body.scrollHeight;


	// 到底的条件
    if (
      scrollTop + windowHeight == scrollHeight
    ) {
	//到底后要进行的操作
    }
    
    document.body.clientWidth ==> BODY对象宽度\

document.body.clientHeight ==> BODY对象高度
document.documentElement.clientWidth ==> 可见区域宽度
document.documentElement.clientHeight ==> 可见区域高度

www.jianshu.com/p/83f45d238…

https://gitee.com/raingad/im-chat-front?_from=gitee_search
Vue.directive('focus', {
    insertedfunction (el) {
        // 聚焦元素
        el.children[0]?.focus()
    }
});

install(Vue) {
    Object.keys(directives).forEach((key) => {
        Vue.directive(key, directives[key])
    })
let findEle = (parent, type)=>{
    return parent.tagName.toLowerCase() === type ? parent : parent.querySelector(type)
}

//校验只能输入小数点后一位
const inputDecimal = {
    //只调用移除,指令第一次绑定到元素时调用,在这里可以进行一次性的初始化设置
    bind: function(el, binding, vnode){
      let $inp = findEle(el, 'input');
         el.$inp = $inp;

         $inp.handle = function(){
             let val = $inp.value;
           $inp.value = Utils.decimalVerification(val);
         }
         $inp.addEventListener('input', $inp.handle);
    },

    //当传入的值更新时触发
    componentUpdated(el, {value}){},

    //指令与元素解绑时候,移除事件绑定
    unbind: function (el){
        el.$inp.removeEventListener('input', el.$inp.handle);
    }
}

在有些情况下,我们需要程序逻辑自动触发元素的事件,例如js提供了click()form提供了reset(),submit()等方法!在jquery中提供了trigger()方法帮助我们自动触发事件,原理是什么呢?接下来让我们一探究竟!

document.body.onclick=function(){
    alert("hello")
}
var event = document.createEvent('MouseEvents');
// initEvent接受3个参数:
// 事件类型,是否冒泡,是否阻止浏览器的默认行为
event.initEvent("click", false, true);
//触发document上绑定的click事件
document.body.dispatchEvent(event);

自定义事件
document.body.addEventListener("veb",function(e){
         alert(e.eventType)
})
var event = document.createEvent('HTMLEvents');
// initEvent接受3个参数:
// 事件类型,是否冒泡,是否阻止浏览器的默认行为
event.initEvent("veb", false, true);
//通过eventType传递事件信息
event.eventType="I love Veblen"
//触发document上绑定的click事件
document.body.dispatchEvent(event);
注入xss
var script = document.createElement("script");  
        script.innerHTML = '$(window).scrollTop = 1000; $(window).trigger("DOMMouseScroll").trigger("scroll");'  
        document.head.appendChild(script)

image.png