插入填空题,一个看似小小的需求,但是却是折腾了很9。主要产品那边的要求,空格上面要标有序号,并且再页面当中能够同步空格答案列表。

1.ueditor插件 插件入门,官方的例子还是很简单直接的,对于我们这个功能够用了,就不做过多介绍。

2.空格序号的显示。要求显示未(  1  ),删除的时候要一起删除

  方案1: 参考的QQ空间 @功能,原来是通过img的alt属性实现的,设置个下边框,这个灵活些,数字可以随意添加,只是样式上面没办法做到很好看

方案2: 直接用图片的方式,这个就是要事先出好图,没办法支持很大,不灵活

使用的方案2,项目中一道题的填空题项目也不能很多

3.填空的唯一性

  方案1:通过实行维护index,有上一次的index和这一次的index,进行逻辑处理

  方案2:通过uuid的方式进行相关的维护,不存在uuid属性的则新设一个

使用的方案2,uuid能确保唯一性,逻辑简单,易懂

4.列表 和 填空的对应关系

  针对3的方案1,需要判断本次index和上一次的index,是新增还是删除,还是修改序列。

  针对3的方案2,列表中不存在uuid的数据,则是新增,存在的就修改下索引,超出的删除。逻辑简明易懂

看看下面的效果。也可以点这里体验

插件代码入下,

function UE_UI_BLANK (editor,uiName) {
UEDITOR_CONFIG = {
UEDITOR_IMAGE_VISIT_URL: '../'
}
var s4 = function () {
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
};
var getUUID = function () {
return s4() + s4() + s4() + s4() + s4() + s4() + s4() + s4();
}; var hasClass = function (node, name) {
return node.attrs && node.attrs["class"] && node.attrs["class"].indexOf(name) != -1;
}
var me = this;
me.addInputRule(function (root) {
$.each(root.getNodesByTagName('img'), function (i, node) {
if (hasClass(node, 'question-blank-space')) {
node.setAttr('onclick', 'return false;');
node.setAttr('ondragstart', 'return false;');
}
});
});
me.addOutputRule(function (root) {
var flag = false;
var tab = [];
$(me.body).find('img.question-blank-space').each(function (index) {
this.src = UEDITOR_CONFIG.UEDITOR_IMAGE_VISIT_URL + "third-party/blank/" + ( index + 1 ) + ".png";
this.setAttribute('alt', index + 1);
if (!this.getAttribute('uuid')) {
this.setAttribute('uuid', getUUID());
}
tab[index] = this.getAttribute('uuid');
if (index > 9) {
$(this).remove();
flag = true;
}
})
if (flag) {
Win.alert('最多插入10个填空题');
}
var id = -1;
$.each(root.getNodesByTagName('img'), function (i, node) {
if (hasClass(node, 'question-blank-space')) {
id++;
node.setAttr('uuid', tab[id]);
node.setAttr('src', UEDITOR_CONFIG.UEDITOR_IMAGE_VISIT_URL + "third-party/blank/" + ( id + 1 ) + ".png");
node.setAttr('ondragstart', '');
node.setAttr('onclick', '');
node.setAttr('onfocus', '');
}
});
});
var btn = new UE.ui.Button({
name: uiName,
title: '插入填空项',
cssRules: 'border-bottom: 1px solid black;background: none repeat scroll 0 0 #fafafa !important;',
onclick: function () {
editor.execCommand(uiName);
}
});
me.commands[uiName] = {
execCommand: function (cmd, latex) {
if ($(me.body).find('.question-blank-space').length > 9) {
alert('最多支持插入10个空');
return;
}
me.execCommand('inserthtml', '<img class="question-blank-space edui-faked-music" onfocus="return false;" ondragstart="return false;" onclick="return false;"/>');
},
queryCommandState: function (cmd) {
return 0;
},
queryCommandValue: function (cmd) {
return false;
}
}
return btn;
};

例子页面逻辑代码如下

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<link type="text/css" rel="stylesheet" href="../../../public/reset.css" >
<script type="text/javascript" charset="utf-8" src="../ueditor.config.js"></script>
<script type="text/javascript" charset="utf-8" src="editor_api.js"> </script>
<script type="text/javascript" charset="utf-8" src="../lang/zh-cn/zh-cn.js"></script>
<script type="text/javascript" charset="utf-8" src="../third-party/blank/addBlankButton.js"> </script>
<script type="text/javascript" charset="utf-8" src="../../../public/jquery-1.11.3.min.js"> </script>
<style type="text/css">
body {
padding: 10px;
}
div{
width:100%;
}
#count {
color: #5cb85c;
}
table td{
border:1px solid #000;
padding: 8px; }
.mt10 {
margin-top: 10px;
}
</style>
</head>
<body>
<div>
<div class="mt10">填空题个数:    <span id="count"></span></div>
<table class="mt10" id="blankTable">
<tr>
<td width="50px">序列</td>
<td width="200px">答案</td>
</tr>
</table>
<script class="mt10" id="editor" type="text/plain" style="width:800px;height:300px;"></script>
</div>
</body>
<script type="text/javascript">
UE.getEditor('editor',{
toolbars:[[]]
})
UE.registerUI('blank', UE_UI_BLANK);
UE.getEditor('editor').addListener( 'contentChange', function() {
var content = this.getContent();
var $tmp = $('<div>' + content + '</div>');
var $fillChar = $tmp.find(".question-blank-space");
var $table = $('#blankTable');
var len = $fillChar.size();
$("#count").html(len);
$fillChar.each(function (index) {
var $elm = $(this);
var alt = index + 1;
var uuid = $elm.attr("uuid");
var $tr = $table.find("tr.blank-line" + uuid);
if ($tr.length == 0) {//新增的
$table.find("tr:eq(" + index + ")").after('<tr class="blank-line' + uuid + '" ><td>第' + alt + '空</td><td contentEditable="true"></td></tr>');
} else if ($tr.index() != index) {
$tr.find('td:eq(0)').html('第' + alt + '空');
$table.find("tr:eq(" + index + ")").after($tr);
}
});
$table.find("tr:gt(" + len + ")").remove();
$tmp.remove();
})
</script>
</html>

ueditor插件 -- 插入填空题的更多相关文章

  1. Linux笔试常见填空题

    一.填空题: 在Linux系统中,以 文件 方式访问设备 . Linux内核引导时,从文件 /etc/fstab 中读取要加载的文件系统. Linux文件系统中每个文件用 i节点 来标识. 全部磁盘块 ...

  2. YTU 2607: A代码填空题--更换火车头

    2607: A代码填空题--更换火车头 时间限制: 1 Sec  内存限制: 128 MB 提交: 91  解决: 73 题目描述 注:本题只需要提交填写部分的代码,请按照C++方式提交. 假设火车有 ...

  3. YTU 2601: 熟悉题型——填空题(删除线性表节点)

    2601: 熟悉题型--填空题(删除线性表节点) 时间限制: 1 Sec  内存限制: 128 MB 提交: 357  解决: 212 题目描述 给出一串具体长度的数据,删除指定数据. 已经给出部分代 ...

  4. springmvc集成Ueditor插件实现图片上传2、

    一.下载Ueditor插件. 地址:http://ueditor.baidu.com/website/download.html 二.环境搭建. 具体可以参看http://fex.baidu.com/ ...

  5. kindeditor自定义插件插入视频代码

    kindeditor自定义插件插入视频代码 1.添加插件js 目录:/kindeditor/plugins/diy_video/diy_video.js KindEditor.plugin('diy_ ...

  6. moodle中的完形填空题的文本编写方法

    moodle中的完形填空题的文本编写方法 [完形填空题]考题把一段文字挖去一些空,让考生根据上下文正确地完成这些填空.完型填空题中的一段短文可以包括各种题目,如选择,填空,和数字题等. 题目的编辑是在 ...

  7. 随笔:关于 FastAdmin ueditor 插件 中的 rand mt_rand mt_getrandmax 问题

    随笔:关于 FastAdmin ueditor 插件 中的 rand mt_rand mt_getrandmax 问题 问题来源 一位小伙伴在使用 Ueditor 插件时出错,因为用的是 php7.1 ...

  8. 『Python题库 - 填空题』151道Python笔试填空题

    『Python题库 - 填空题』Python笔试填空题 part 1. Python语言概述和Python开发环境配置 part 2. Python语言基本语法元素(变量,基本数据类型, 基础运算) ...

  9. 百度编辑器ueditor插件的基本使用

    注意:该插件是基于tpframe开发,请在tpframe框架上使用 插件下载地址:https://pan.baidu.com/s/1MOJbd1goQC0Bn5-7HcIdKA 插件下载下来后解压到a ...

随机推荐

  1. java中获取类加载路径和项目根路径的5种方法

    import java.io.File; import java.io.IOException; import java.net.URL; public class MyUrlDemo { publi ...

  2. powerdesigner 转换各种数据库SQL

    转各种SQL脚本的步骤 一.

  3. C#4 for循环 迭代法 穷举法应用

    for()循环. 四要素: 初始条件,循环条件,状态改变,循环体. 执行过程: 初始条件--循环条件--循环体--状态改变--循环条件.... 注意:for的小括号里面分号隔开,for的小括号后不要加 ...

  4. strcpy, mencpy, memmove三者区别

    首先来看strcpy,目的是实现字符串的复制,这里需要注意几个点: 1.判断指针的有效性 2.将复制后的指针地址返回,为了支持链式操作 3.不要忘记将字符串最后一个自负'\0'复制给dest 4.注意 ...

  5. 如何创建javascript只读变量

    最近学习了一下ES标准,发现其实有很多直接间接的方法实现一个只读变量,这里总结一下. 1.最直接的是利用对象属性的特性来实现: var obj = {pro1:1}; Object.definePro ...

  6. jquery 实现横向滑动自动切换源码(同时显示多张图片)

    html代码: <!doctype html> <html lang="en"> <head> <meta charset="U ...

  7. django随笔说明

    最近学习了vamei的快速Python教程,想着语法学了不用就要忘记,总要拿点东西来练练手,然后又开始学习Django,也算是顺势而为吧. 现在学Django,是跟着教程djangobook学的,内容 ...

  8. View的滑动冲突

    一.常见的滑动冲突 场景1:外部滑动和内部滑动不一致 场景2:外部滑动和内部滑动一致 场景3:上面两种情况的嵌套 二.滑动冲突的处理方法 场景一:根据水平滑动还是竖直滑动判断到底由谁来拦截事件. 场景 ...

  9. 安装solaris_11.2与windows双系统(VM10模拟实现)(二)

    下面我们在虚拟机下安装双系统 1.首先我们新建一个虚拟机 新建的时候一定要注意客户机操作系统应选择solaris,不然不行: 新建完成后我们先分两个分区,这里我先从U盘启动进去(也可以用xp/win7 ...

  10. win7下设置 WiFi AP

    开启windows 7的隐藏功能:虚拟WiFi和SoftAP(即虚拟无线AP),就可以让计算机变成无线路由器.实现共享上网. 1.以管理员身份运行命令提示符: “开始”---在搜索栏输入“cmd”-- ...