• sortablejs、vuedraggable实现拖拽排序,在android、iOS、chrome模拟移动设备的情况下,拖拽元素有SVG存在时,可能会卡住,不触发end事件


    背景

    在做一个拖动应用图片排序的场景下,androidiOSchrome模拟移动设备 的情况,应用图片用的是svg,大概率会出现ghost元素不消失,也不触发end事件的诡异情况。
    注意
    PC端使用chrome 调试模式下,不开启模拟移动设备不会出现这种情况,开启来模拟移动设备也会出现。

    使用的是vue + vuedraggable实现。效果如下图:

    解决办法

    svg元素设置一个css样式,即可;

    svg {
        pointer-events: none;
    }
    

    原因分析

    根据上面出现,没有触发end事件,查看sortablejs源代码,可以看到sortablejs是通过监听类似:touchend,mouseup,pointerup类似这样的事件,认为拖动结束,从而完成后续动作,移除ghost元素,并触发end事件。
    分析步骤:

    1. 在chrome 调试下监听上面的三个touchend,mouseup,pointerup,发现只要出现上面的情况,这些事件都不会触发。从而可以判断是原来浏览器没有触发事件
    2. 在页面是移除图标,再此拖动,发现可以正常拖动排序。从而判断问题出现在图标上,图标使用的svg。
    3. 看浏览器性能面板,是不是拖动svg会造成大量渲染,从而导致浏览器卡顿,从而没有触发上面的事件,经过实验,并不是这个原因
    4. 猜测鼠标移动svg上,因为svg本身就具有动画的效果,是不是和外面的事件冲突,阻挡了事件触发,实验在svg上用绝对定位放了一个空白的元素,发现问题解决。在这个思路上继续找相关的答案,找到css属性 pointer-events

    pointer-events

    【 CSS 属性指定在什么情况下 (如果有) 某个特定的图形元素可以成为鼠标事件的 target" 】。具体参考 pointer-events MDN的说明

    语法:
    pointer-events属性被指定为从下面的值列表中选择的一个关键字。

    1. auto
      与pointer-events属性未指定时的表现效果相同,对于SVG内容,该值与visiblePainted效果相同
    2. none
      元素永远不会成为鼠标事件的target。但是,当其后代元素的pointer-events属性指定其他值时,鼠标事件可以指向后代元素,在这种情况下,鼠标事件将在捕获或冒泡阶段触发父元素的事件侦听器。
    3. visiblePainted
      只适用于SVG。元素只有在以下情况才会成为鼠标事件的目标:
      visibility属性值为visible,且鼠标指针在元素内部,且fill属性指定了none之外的值
      visibility属性值为visible,鼠标指针在元素边界上,且stroke属性指定了none之外的值
    4. visibleFill
      只适用于SVG。只有在元素visibility属性值为visible,且鼠标指针在元素内部时,元素才会成为鼠标事件的目标,fill属性的值不影响事件处理。
    5. visibleStroke
      只适用于SVG。只有在元素visibility属性值为visible,且鼠标指针在元素边界时,元素才会成为鼠标事件的目标,stroke属性的值不影响事件处理。
    6. visible
      只适用于SVG。只有在元素visibility属性值为visible,且鼠标指针在元素内部或边界时,元素才会成为鼠标事件的目标,fill和stroke属性的值不影响事件处理。
    7. painted
      只适用于SVG。元素只有在以下情况才会成为鼠标事件的目标:
      鼠标指针在元素内部,且fill属性指定了none之外的值
      鼠标指针在元素边界上,且stroke属性指定了none之外的值
      visibility属性的值不影响事件处理。
    8. fill
      只适用于SVG。只有鼠标指针在元素内部时,元素才会成为鼠标事件的目标,fill和visibility属性的值不影响事件处理。
    9. stroke
      只适用于SVG。只有鼠标指针在元素边界上时,元素才会成为鼠标事件的目标,stroke和visibility属性的值不影响事件处理。
    10. all
      只适用于SVG。只有鼠标指针在元素内部或边界时,元素才会成为鼠标事件的目标,fill、stroke和visibility属性的值不影响事件处理。

    根据上面的属性说明,可以看到默认的情况下,svg:visiblePainted,我们使用的svg是从sketch 软件导出的,里面确实包含fill, stroke属性,最终我们选择粗暴的方式,设置为 “none” 解决。

    示例svg

    <?xml version="1.0" encoding="UTF-8"?>
    <svg width="60px" height="60px" viewBox="0 0 60 60" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
        <!-- Generator: Sketch 63.1 (92452) - https://sketch.com -->
        <title>形状结合</title>
        <desc>Created with Sketch.</desc>
        <g id="工作台" stroke="none" stroke-width="1" fill-rule="evenodd">
            <g id="3-1工作台" transform="translate(-626.000000, -568.000000)">
                <g id="编组-36" transform="translate(43.000000, 549.000000)">
                    <g id="编组-20" transform="translate(3.000000, 0.000000)">
                        <g id="youjian" transform="translate(562.000000, 1.000000)">
                            <g id="编组-21">
                                <g id="youjian" transform="translate(18.000000, 18.000000)">
                                    <path d="M4.99995326,20.244 L28.3583213,31.4139931 C28.8205574,31.6350244 29.3264899,31.6819953 29.7962042,31.5752545 C30.3767838,31.8438191 31.0647942,31.8560532 31.6763236,31.563633 L31.6763236,31.563633 L55.0339533,20.394 L55.0346,45.252 C55.0346,49.8911919 51.2737919,53.652 46.6346,53.652 L13.4,53.652 C8.7608081,53.652 5,49.8911919 5,45.252 L4.99995326,20.244 Z M46.6346,6 C51.2737919,6 55.0346,9.7608081 55.0346,14.4 L55.0349184,17.0342857 C54.4239245,16.6890913 53.664156,16.6447522 52.9957553,16.964367 L52.9957553,16.964367 L30.1739533,27.8765471 L7.03888956,16.8147272 C6.37077757,16.4952504 5.61137681,16.5394132 5.00051835,16.8841987 L5,14.4 C5,9.7608081 8.7608081,6 13.4,6 L46.6346,6 Z" id="形状结合"></path>
                                </g>
                            </g>
                        </g>
                    </g>
                </g>
            </g>
        </g>
    </svg>
    
  • 相关阅读:
    App唤起微信小程序和回调
    微信小程序 — 自定义picker选择器弹窗内容+textarea穿透bug
    微信小程序的场景值scene
    微信小程序textarea层级过高(盖住其他元素)
    微信小程序如何修改本地缓存key中的单个数据
    微信小程序---查看更多的显示与隐藏
    微信小程序文字超过行后隐藏并且显示省略号
    Flutter 页面下拉刷新和上拉加载
    json转换成dart类 JSON to Dart
    Flutter 保持页面状态
  • 原文地址:https://www.cnblogs.com/xakoy/p/13503186.html
Copyright © 2020-2023  润新知