zoukankan      html  css  js  c++  java
  • vue中解决拖拽改变存在iframe的div大小时卡顿问题

    写在最前

    针对于在vue中实现拖拽改变两左右个div大小的方式,请查看上一篇文章《vue中实现拖动调整左右两侧div的宽度》。此文章主要针对于实际应用中需要拖拽改变大小的组件中使用iframe框架时存在明显卡顿的问题,比如这样,右侧div中使用了一个iframe组件,导致实际操作中出现两个问题,一个是拖不动,另外一个是无法根据鼠标移动,快速响应,甚至在监听鼠标的按下和松开事件上都有明显的卡顿问题。如果去除右侧iframe框架,则没有问题。

    有iframe情况

     

    无iframe情况

    问题原因&解决思路

    问题原因我不知道,不过这个博客给了我解决思路《解决jqueryUI的拖拽,如果元素中含有iframe,拖动卡的问题》,还有以下说法,他们的解决思路一样的。因此我猜想是鼠标的监听造成的影响,在我们拖拽的时候,因为拖拽过快,很容易出现鼠标移动超过拖拽范围的情况,此时的鼠标可能已经在iframe上方,从而会同时加载iframe中的内容,导致出现卡顿。

    总之,解决的思路就是在拖动的时候,在iframe上方添加一个透明的遮罩层,然后在停止拖拽的时候让其消失。这样问题就可以完美解决了。

    解决方式共有两节,一节包含我解决过程中遇到的问题,一节是直接的解决方式,如果想直接查看解决方式的,请直接跳转至 解决方式 那一节

     解决方式(含解决过程中遇到的问题)

    HTML组件部分源代码

    这是实现拖拽的组件代码,如果不了解我原本使用的实现方式,请参考《vue中实现拖动调整左右两侧div的宽度

    <div class="box" ref="box">
                <div class="left" ref="left">
    
                </div>
                <div class="resize" ref="resize" title="收缩侧边栏"></div>
                <div class="mid" ref="mid">
                    <!--在此处添加遮罩层-->
                    <iframe id="iFrame1" name="iFrame1" width="100%" height="100%" frameborder="0" scrolling="auto"
                            :src="iframeUrl">
                    </iframe>
                </div>
            </div>

    添加遮罩层

    在以上标注的地方,添加如下代码

    <div class="iframeDiv"></div>

    再添加遮罩层的css样式即可,此时最好测试点击一下,是不是原来的ifame部分已经不能点击,而且拖拽起来已经不再卡顿了

     /* 添加透明遮罩层 */ 
    .iframeDiv {
            width: 100%;
            height: 100%;
            position: absolute;
            z-index: 1111;
            filter: alpha(opacity=0);
            opacity: 0;
            background: transparent;
            margin-top: 30px;
            /*display: none;*/
        }

    实现遮罩层在拖拽时出现

    我的解决办法是直接在拖拽区域添加监听鼠标的按下和松开事件,按下后遮罩层出现,松开后消失,因此修改resize部分,添加onmouseup&mousedown,分别传入参数,用于修改iframeDiv的css样式中的display属性值

      <div class="resize" ref="resize" @mousedown="changeIframeDivStyle('')" @onmouseup="changeIframeDivStyle('none')" >
      ⋮
      </div>

    然后添加changeIframeDivStyle 方法,因为getElementByClassName返回的是个数组集合,但是我又确认自己页面只有一个iframeDiv,所以选择了iframe[0],如果想使用getElementById也可以

     changeIframeDivStyle(display) {
                    var iframeDiv = document.getElementsByClassName('iframeDiv');
                    iframeDiv[0].style.display = display;
                },  

    到此基本就算完成大半了,mousedown为鼠标按下事件,按下后设置display为空,即遮罩层出现,onmouseup为鼠标松开事件,松开后遮罩层消失,达到不影响用户操作查看iframe中内容的目的

    页面初始化时遮罩层设置问题

    按照实际来讲,初始化进入页面时,我们就不应该留有遮罩层,所以按照我的想法来讲,就是直接在css中修改样式,但是如上所见,我把它注释掉了,至于为什么,先卖个关子,大家修改后尝试一下,看看拖拽时卡顿不卡顿

    display: none;

    在我本以为这样就可以解决问题时,我发现,首次进入页面,直接进行拖拽,依旧会存在卡顿,但是拖拽过一次之后,就不会再有问题了。这个问题,,我又不知道为什么了,于是,既然它需要拖拽一次之后才不会卡顿,那我就直接注释掉了css中这个display样式,反而在 mounted中添加方法,这样反而成功了,虽然搞不明白两者的差距,但是问题总算是解决了,如果有知道原因的朋友,可以在评论中分享出来,供大家学习学习。

    this.changeIframeDivStyle('none');

    解决方式

    在iframe上添加透明遮罩层样式

    <div class="box" ref="box">
                <div class="left" ref="left">
    
                </div>
                <div class="resize" ref="resize" title="收缩侧边栏"></div>
                <div class="mid" ref="mid">
                    <!--在此处添加遮罩层-->
                <div class="iframeDiv"></div>
                    <iframe id="iFrame1" name="iFrame1" width="100%" height="100%" frameborder="0" scrolling="auto"
                            :src="iframeUrl">
                    </iframe>
                </div>
            </div>        

    添加CSS样式

      .iframeDiv {
            width: 100%;
            height: 100%;
            position: absolute;
            z-index: 1111;
            filter: alpha(opacity=0);
            opacity: 0;
            background: transparent;
            margin-top: 30px;
            /*display: none;*/
        }

    添加鼠标的监听事件

    在拖拽区添加鼠标的按下事件和松开事件

      <div class="resize" ref="resize" @mousedown="changeIframeDivStyle('')" @onmouseup="changeIframeDivStyle('none')" >
      ⋮
      </div>

    添加方法

     changeIframeDivStyle(display) {
                    var iframeDiv = document.getElementsByClassName('iframeDiv');
                    iframeDiv[0].style.display = display;
                },

    设置页面初始化加载

    this.changeIframeDivStyle('none');

    完成

    结语

    没有结语

  • 相关阅读:
    ajax原理及封装
    javascript 递归调用
    CSS的五种定位方式
    vue中iframe结合window.postMessage实现父子页面间的通信
    vue将文件流的形式的图形验证码转换成图片
    路由跳转打开新窗口,传递的参数不显示在地址栏
    js判断是否是ie浏览器、360浏览器兼容模式、QQ浏览器兼容模式、搜狗浏览器兼容模式,弹出提示使用别的浏览器打开
    vue项目中使用iframe嵌入静态页面,动态获取静态页面的高度赋值给iframe的高度
    vue项目中使用iview组件中的table插件实现表头文字居中,内容文字居左
    vue前端开发实现微信支付和支付宝支付
  • 原文地址:https://www.cnblogs.com/ingrid/p/12766466.html
Copyright © 2011-2022 走看看