在iframe中获取选中的数据/iframe中鼠标事件

这篇博客介绍了在Vue项目中如何处理iframe内的鼠标事件,特别是获取选中的文本和图片数据。作者通过监听iframe的onload事件,然后在iframe内容中添加鼠标up事件,实现了获取选中文本和图片的功能。同时,通过自定义oncontextmenu右键事件,结合vue-contextmenujs组件创建了一个右键菜单,允许用户进行反馈操作。代码示例详细展示了这一过程。

在iframe中获取选中的数据/iframe中鼠标事件


我现在的vue项目有个需求是,点击手册时,在显示的手册内容中进行内容的选中,并进行右键生成反馈

在iframe中获取选中的数据

刚写的时候是在iframe标签上写了鼠标的事件,导致没有任何事件没有任何反应,也是查了百度才知道,因为iframe是独立的标签,外部是无法对iframe内部进行操作的,所以我是用了addEventListener方法对内部生成事件,从而进行数据的获取。

  // 初始化iframe
  document.getElementById('iframe').onload = function () {
       let iframe = document.getElementById('iframe').contentWindow
       // 通过id获取内容,这个内容其实是一个标签,标签里面才是iframe在页面显示的内容(其实就是html)
       // 获取 id 为 styler-id1的元素,为其添加鼠标事件,用于获取鼠标选中的文本或者图片
       iframe.document.getElementById('styler-id1').addEventListener('mouseup', () => {
       // 获取文字
       _this.words = iframe.getSelection().toString()
       // 获取图片
          if (iframe.getSelection().getRangeAt(0).commonAncestorContainer.getElementsByTagName('img')) {
              let ImgArray = new Array()
              ImgArray = iframe.getSelection().getRangeAt(0).commonAncestorContainer.getElementsByTagName('img')
	          for (let i in ImgArray) {
	             if (ImgArray[i].currentSrc) {
	             	 // fileImg 是在data中的一个数组,用于存放选中的图片
	                  _this.fileImg.push(ImgArray[i].currentSrc)
	             }
	           }
            }
        })
	    // 自定义鼠标右键事件
	    iframe.oncontextmenu = function (event) {
	       _this.onContextmenu(event, _this.words, _this.fileImg)
	       return false //组织浏览器右键
	    }
  }

iframe中鼠标事件

因为是右键一键生成反馈,所以要使用鼠标右键事件方法 oncontextmenu。因为是vue项目,我们的框架使用的是elementUI,所以右键操作我是安装了Vue 原生右键菜单组件(vue-contextmenujs

下图是我自己根据需求修改成的右键菜单
在这里插入图片描述

这是右键菜单里面的内容,按钮事件可以自定义。
在上面的代码中iframe右键事件中调用下面的vue原生右键事件,并传入参数进行页面跳转从进行数据的显示。

	// 右键菜单
   onContextmenu(event, words, fileImg) {
        this.$contextmenu({
          items: [
            {
              label: '返回',
              icon: 'el-icon-back',
              onClick: () => {
                this.message = '返回(B)'
                console.log('返回(B)')
              },
            },
            {
              label: '反馈',
              icon: 'el-icon-service',
              onClick: () => {},
            },
          ],
          event,
          x: event,  //x轴坐标
          y: 0,		 //y轴坐标
          customClass: 'class-a',
          zIndex: 3,
          minWidth: 120,
        })
        return false
      },
    },

来个代码汇总吧,有这种问题的小伙伴们可以很方便的使用

	  // 初始化iframe
	  document.getElementById('iframe').onload = function () {
	       let iframe = document.getElementById('iframe').contentWindow
	       // 通过id获取内容,这个内容其实是一个标签,标签里面才是iframe在页面显示的内容(其实就是html)
	       // 获取 id 为 styler-id1的元素,为其添加鼠标事件,用于获取鼠标选中的文本或者图片
	       iframe.document.getElementById('styler-id1').addEventListener('mouseup', () => {
	       // 获取文字
	       _this.words = iframe.getSelection().toString()
	       // 获取图片
	          if (iframe.getSelection().getRangeAt(0).commonAncestorContainer.getElementsByTagName('img')) {
	              let ImgArray = new Array()
	              ImgArray = iframe.getSelection().getRangeAt(0).commonAncestorContainer.getElementsByTagName('img')
		          for (let i in ImgArray) {
		             if (ImgArray[i].currentSrc) {
		             	 // fileImg 是在data中的一个数组,用于存放选中的图片
		                  _this.fileImg.push(ImgArray[i].currentSrc)
		             }
		           }
	            }
	        })
		    // 自定义鼠标右键事件
		    iframe.oncontextmenu = function (event) {
		       _this.onContextmenu(event, _this.words, _this.fileImg)
		       return false //组织浏览器右键
		    }
	  },
 	  // 右键菜单
	  onContextmenu(event, words, fileImg) {
        this.$contextmenu({
          items: [
            {
              label: '返回',
              icon: 'el-icon-back',
              onClick: () => {
                this.message = '返回(B)'
                console.log('返回(B)')
              },
            },
            {
              label: '反馈',
              icon: 'el-icon-service',
              onClick: () => {},
            },
          ],
          event,
          x: event,  //x轴坐标
          y: 0,		 //y轴坐标
          customClass: 'class-a',
          zIndex: 3,
          minWidth: 120,
        })
        return false
      },
    },

我这是根据自己的项目情况写的,具体细节大家可以根据自己项目问题情况进行修改,如果大家有更好的方法可以分享一哈。谢谢大家的支持,下次更新见!

<think>我们正在处理一个关于Flask和CKEditorField的问题。用户希望在使用CKEditorField时能够获取点击事件。根据提供的引用,我们知道CKEditorField是Flask-WTF表单中的一个字段,由flask-ckeditor提供支持。 在Web开发中,获取富文本编辑器(如CKEditor)的点击事件通常需要在前端JavaScript中处理,因为CKEditor是在浏览器中运行的。因此,我们需要在CKEditor实例上绑定事件监听器。 然而,用户的问题是在Flask中如何实现,这意味着我们需要在Flask应用的前端部分(即模板)中添加JavaScript代码来监听CKEditor的点击事件。 步骤: 1. 确保在表单中正确使用了CKEditorField,这样在渲染表单时,会生成CKEditor的文本区域。 2. 在模板中,我们需要包含CKEditor的JavaScript文件(如果还没有的话)。 3. 使用JavaScript来监听CKEditor实例的事件。 根据引用[2],我们知道Flask-CKEditor已经提供了一些配置,但这里我们需要的是事件绑定。 具体实现: 在模板中,我们可以使用CKEditor的API来监听事件。CKEditor提供了丰富的API,其中就包括事件处理。 例如,我们可以监听`instanceCreated`事件,该事件在CKEditor实例创建时触发,然后在该实例上绑定点击事件。 示例代码(在模板中): 首先,确保表单字段被渲染。然后,添加JavaScript代码: ```html <!-- 假设我们已经引入了CKEditor的JS文件,因为Flask-CKEditor应该已经帮我们做了 --> <!-- 在表单渲染的地方 --> <form method="POST"> {{ form.hidden_tag() }} {{ form.content.label }}{{ form.content() }} <!-- 假设content是CKEditorField字段 --> <input type="submit"> </form> <!-- 引入CKEditor的JS(如果还没有自动引入的话) --> {{ ckeditor.load() }} <script> // 当CKEditor实例创建时,绑定事件 CKEDITOR.on('instanceCreated', function(event) { var editor = event.editor; // 监听点击事件 editor.on('click', function(e) { console.log('Editor clicked!', e); // 在这里可以处理点击事件 }); }); </script> ``` 但是,请注意,CKEditor的编辑器区域实际上是一个内嵌的文档(iframe),所以直接绑定点击事件可能不是那么简单。CKEditor提供了自己的事件系统。上述代码中的`click`事件是CKEditor提供的一个事件,它会在编辑器的内容被点击时触发。 另外,我们也可以使用CKEditor的`contentDom`事件,确保在编辑器内容DOM加载完成后绑定事件: ```javascript editor.on('contentDom', function() { var editable = editor.editable(); editable.attachListener(editable, 'click', function(evt) { console.log('Clicked on the editable area', evt); }); }); ``` 但是,更简单的方式是直接使用CKEditor提供的事件,如`click`事件(注意:CKEditor的点击事件是经过封装的,它提供了更多关于编辑器的信息)。 因此,我们可以采用第一种方式:在`instanceCreated`事件中为每个编辑器实例绑定`click`事件。 注意:如果页面中有多个CKEditor实例,上述代码会为每个实例都绑定点击事件。 在Flask应用中,我们通常会在表单模板中做这些操作。 另外,如果用户希望将点击事件的信息发送回后端,那么可能需要使用AJAX。但问题只是要求获取点击事件,所以我们先在前端捕获它。 总结:在Flask中,我们无法直接在后端的CKEditorField上绑定事件,因为事件发生在浏览器。我们需要在模板中使用JavaScript来监听CKEditor实例的事件。 因此,回答用户的问题:你需要在前端使用JavaScript来监听CKEditor的点击事件,具体方法如上所示。 根据指令,我们还需要生成相关问题。 相关问题: 1. 如何在CKEditor中监听其他事件(如改变事件、选择事件)? 2. 如何将CKEditor中的点击事件信息发送到Flask后端? 3. 在CKEditor中,如何获取点击事件的具体位置(比如光标位置)? 4. 如何为CKEditor定制一个点击事件处理函数(比如插入特定内容)?</think>在 Flask 中使用 `CKEditorField` 获取点击事件,需要通过 JavaScript 在前端实现监听,因为 CKEditor 的交互发生在浏览器端。以下是具体实现步骤: ### 解决方案 1. **在模板中添加 JavaScript 事件监听** 在渲染 CKEditor 的 HTML 模板中,添加以下代码: ```html <script> document.addEventListener("DOMContentLoaded", function() { // 监听 CKEditor 实例创建完成事件 CKEDITOR.on('instanceReady', function(ev) { const editor = ev.editor; // 监听编辑器点击事件 editor.on('click', function(e) { console.log("CKEditor 被点击", e); // 可在此处添加自定义逻辑 }); // 监听内容区域点击事件(更精确) editor.on('contentDom', function() { editor.editable().on('click', function(event) { console.log("内容区域被点击", event); // 获取光标位置 const selection = editor.getSelection(); console.log("当前光标位置:", selection.getRanges()); }); }); }); }); </script> ``` 2. **确保正确加载 CKEditor** 在 Flask 模板中加载 CKEditor 资源: ```html {{ ckeditor.load() }} <!-- 加载 CKEditor 核心 JS --> {{ ckeditor.config(name='your_field_name') }} <!-- 初始化编辑器 --> ``` ### 关键点说明 1. **事件类型选择**: - `instanceReady`:确保编辑器完全加载后再绑定事件 - `contentDom`:针对编辑内容区域的精确事件监听 - `click`:捕获鼠标点击事件 2. **获取编辑器实例**: ```javascript // 通过 ID 直接获取实例 const editor = CKEDITOR.instances.your_field_id; ``` 3. **事件对象信息**: 事件对象 `e` 包含: - `e.data.$`:原生 DOM 事件对象 - `e.editor`:当前编辑器实例 - 可通过 `editor.getSelection()` 获取选中的文本/光标位置 ### 示例应用场景 ```javascript // 点击时插入特定文本 editor.editable().on('click', function() { editor.insertText("已点击插入"); }); // 点击时显示弹窗 editor.on('click', function() { alert("编辑器被激活!"); }); ``` ### 注意事项 1. **多编辑器实例**: 若页面有多个 CKEditor,需遍历所有实例: ```javascript for (let instance in CKEDITOR.instances) { CKEDITOR.instances[instance].on('click', ...); } ``` 2. **动态加载内容**: 若编辑器内容通过 AJAX 加载,需在内容加载后重新绑定事件: ```javascript $(document).ajaxComplete(function() { CKEDITOR.instances.your_field_id.on('click', ...); }); ``` 3. **与 Flask 后端交互**: 如需将点击数据传回 Flask: ```javascript editor.on('click', function() { fetch('/click-track', { method: 'POST', body: JSON.stringify({action: "ckeditor_click"}) }); }); ``` [^1]: 引用[1]:实操: 修改forms/account_form.py文件中的LoginForm()为以下代码:... [^1] [^2]: 引用[2]:实现资源上传功能需要为CKEditor指定文件上传所使用的视图函数... [^2] --- ### 相关问题 1. 如何监听 CKEditor 的内容变化事件? 2. 怎样通过 CKEditor 的点击事件获取当前光标位置? 3. 如何实现 CKEditor 点击时插入预定义内容片段? 4. 在 Flask 中如何处理 CKEditor 的事件数据并存储到数据库?
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值