You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Chrome扩展中jQuery UI实现li拖拽排序功能失效该如何修复

问题原因
  • Chrome扩展默认开启内容安全策略(CSP):默认禁止加载远程CDN资源,也禁止执行内联JavaScript代码,原代码同时使用了远程jQuery、jQuery UI CDN和内联初始化脚本,违反CSP规则导致脚本未正常加载或执行。
  • 原代码存在语法错误:初始化sortable的script块缺少闭合的</script>标签,普通HTML环境下浏览器有容错机制可以正常运行,但Chrome扩展的解析规则更严格,会直接导致脚本执行失败。
  • 若使用Manifest V3版本开发扩展,V3版本完全禁止unsafe-eval权限,部分版本jQuery UI的sortable功能依赖eval逻辑,也会触发限制导致功能失效。
  • 潜在隐患:代码中多个元素重复使用相同ID(id="one"、id="two"),可能引发DOM操作异常。
修复方案
  1. 资源本地化:将jQuery、jQuery UI的源码下载到扩展本地目录,替换远程CDN引用,改为引用本地文件路径,示例:
<script src="./js/jquery-3.6.0.min.js"></script>
<script src="./js/jquery-ui-1.13.0.min.js"></script>
  1. 抽离内联脚本:将原内联的sortable初始化代码抽为单独的JS文件(如sortable-init.js),再通过script标签引入本地文件:
<script src="./js/sortable-init.js"></script>

sortable-init.js内容:

$(function() {
    $( "#sortable" ).sortable();
    $("#sortable").disableSelection();
});
  1. 调整Manifest配置:
  • 若为Manifest V2版本,在manifest.json中添加CSP配置:
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'none'"
  • 若为Manifest V3版本,因无法使用unsafe-eval,不建议继续使用jQuery UI方案,直接使用下方原生替代方案更稳妥。
  1. 修复重复ID问题:将重复的ID改为class或者唯一ID,避免潜在DOM异常。
替代方案

无需依赖任何第三方库,直接用原生HTML5 Drag & Drop API实现拖拽排序,完全不会触发CSP限制,示例代码如下:

HTML部分(无需大改,可保留原有结构)

<ul id="sortable">
    <li class="ui-state-default">
        <div class="divtext">
            <i class="far fa-play-circle" style="font-size:30px;"></i>
            <div class="divtext0">"[Code]"</div>
        </div>
    </li>
    <li class="ui-state-default">
        <div class="divtext">
            <i class="far fa-play-circle" style="font-size:30px;"></i>
            <div class="divtext0">"[Code]"</div>
        </div>
    </li>
</ul>

JS部分(单独存为本地JS文件引入)

const sortableList = document.getElementById('sortable')
let draggingNode = null

// 绑定所有列表项拖拽事件
sortableList.querySelectorAll('li').forEach(item => {
  item.draggable = true
  // 拖拽开始
  item.addEventListener('dragstart', () => {
    draggingNode = item
    setTimeout(() => item.classList.add('dragging'), 0)
  })
  // 拖拽结束
  item.addEventListener('dragend', () => {
    item.classList.remove('dragging')
    draggingNode = null
  })
})

// 监听列表拖拽经过事件
sortableList.addEventListener('dragover', e => {
  e.preventDefault()
  const validSiblings = [...sortableList.querySelectorAll('li:not(.dragging)')]
  // 找到当前拖拽位置的下一个兄弟元素
  const nextNode = validSiblings.find(sibling => {
    return e.clientY <= sibling.offsetTop + sibling.offsetHeight / 2
  })
  sortableList.insertBefore(draggingNode, nextNode)
})

可选样式补充

.dragging {
  opacity: 0.5;
  background: #f0f0f0;
}
li {
  cursor: move;
}

内容的提问来源于stack exchange,提问作者최은서

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 06:06:03