热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

基于jQuery试卷自动排版系统_jquery

jQuery试卷自动排版系统,需要的朋友可以参考下。
需求
根据提供的试卷题目(是一个干净的只有“数据”的HTML网页)生成一份多页的试卷,用户能执行翻页、具有答题时间限制,展示给用户的试卷中题目需要占用尽量少的空间(比如选择题中把两条较短的选项由两行合并到一行)、同一道题目不要跨页面显示以方便答题者,管理员能够改变试卷的样式(字体、颜色、行距、页面边距,像字处理软件一样……),题目之间可以插入一些说明性的文字(比如告知答题者作答的须知等等)。题目提干、选择题的选项、说明文字可以包含多媒体信息(文字、图片、列表、表格、视频等等……)。选择题选项数目不限、单选多选不限。翻页要有可订制的动画效果

提供的试卷样板类似如下(Input):

代码如下:



    选择题:说明文字。说明文字。说明文字。说明文字。说明文字。说明文字。说明文字。说明文字。说明文字。说明文字。说明文字。说明文字。说明文字。说明文字。



  1. 1.你认为怎样的老师是好老师?









  2. 2.一位有15年教龄的英语教师,教了多年高三,可谓学校的核心骨干。一次接受邀请到外校介绍教学经验,台下有老师发表了观点并问到几个英语教法发面的问题,一下子把她给卡住了。这是因为









  3. 3.哪张图片最好看?









  4. 填空题和选择题:一大堆的说明文字。一大堆的说明文字。一大堆的说明文字。一大堆的说明文字。一大堆的说明文字。



  5. 4.床前明月光,



  6. 5.你认为怎样的老师是好老师?














思路
面对这种需求该怎么办呢?使用Javascript了,看来。后来决定用jQuery,Aptana作IDE(虽然jQuery支持库在Windows上死活装不上去,换了个OS就好了,奇怪),格式么就用CSS了。

具体步骤:

导入试卷题目HTML
对所有选择题进行排版,把一行划分为四个位置,使选项尽量适应一个位置、两个位置或四个位置(也就是一行四项、一行两项或者一行一项的效果)
对所有题目进行分页
思路还是清晰的,但是由于浏览器众多,还是比较麻烦的,并且我是新手,没接触过jQuery之前……

实现
页面文件(和例子不同,但是格式一样的)

代码如下:


PrevPage


NextPage


Loading the test...





    left



    right




    选择题:说明文字。说明文字。说明文字。说明文字。说明文字。说明文字。说明文字。说明文字。说明文字。说明文字。说明文字。说明文字。说明文字。说明文字。



  1. 1你认为怎样的老师是好老师?









  2. 2你认为怎样的老师是好老师?









  3. 3你认为怎样的老师是好老师?









  4. 4你认为怎样的老师是好老师?








  5. 还是选择题:一大堆的说明文字。一大堆的说明文字。一大堆的说明文字。一大堆的说明文字。一大堆的说明文字。



  6. 5你认为怎样的老师是好老师?









  7. 5你认为怎样的老师是好老师?









  8. 6你认为怎样的老师是好老师?













样式文件(CSS)

代码如下:


/* YahooUI CSS Reset */
body,p,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td { padding: 0; margin: 0; }
table { border-collapse: collapse; border-spacing: 0; }
fieldset,img { border: 0; }
address,caption,cite,code,dfn,em,strong,th,var { font-weight: normal; font-style: normal; }
ol,ul { list-style: none; }
caption,th { text-align: left; }
h1,h2,h3,h4,h5,h6 { font-weight: normal; font-size: 100%; }
q:before,q:after { content:''; }
abbr,acronym { border: 0;}

label { padding: 0; margin: 0; }

/* My css */
.Choices { line-height: 150%; margin: 5px 0; }
.Page { height: 500px; border: solid 1px gray; }
#olThePaper, .Display { padding: 0; width: 500px; }
/* NOTICE: the width of .Display and #olThePaper should be the SAME. */
.Display { float: left; }

#pToolbar { height: 35px; }
#pPrev, #pNext { float: left; width: 100px; height: 30px; border: solid 1px green; background-color: #999999; }
#pPageInfo { float: left; width: 100px; height: 30px; }
#pTimer { float: left; width: 500px; height: 30px; }


/*for debugging... perhaps for non-IE only*/
/**label { outline: dotted 1px red; background-color: gray; }**/
/**p {outline: dashed 1px blue;}**/


下面是重点,TTestPaperProcessor.js:

代码如下:


/**
*
* @param {String} PaperOlId the id value of the ol tags indicating pages.
* @param {String} ProblemClass the css class name for problem area.
* @param {String} DescClass the css class name for description area.
* @param {String} ChoicesClass the css class name for choices area.
* @param {String} LeftPageId the id of the left page.
* @param {String} RightPageId the id of the right page.
* @author ExSystem
*/
function TTestPaperProcessor(PaperOlId, ProblemClass, DescClass, ChoicesClass, LeftPageId, RightPageId) {
this.FPaperOlId = PaperOlId;
this.FProblemClass = ProblemClass;
this.FDescClass = DescClass;
this.FChoicesClass = ChoicesClass;
this.FLeftPageId = LeftPageId;
this.FRightPageId =RightPageId;
$('#' + this.FLeftPageId).html('');
$('#' + this.FRightPageId).html('');
this._FormatProblemOptions();
this._DivideIntoPages();
this.setCurrPage(1);
}

TTestPaperProcessor.prototype = {
FPaperOlId: '', //the id property of the ol tag contains the whole test paper.
FProblemClass: '', //the css class name for problem area.
FDescClass: '', //the css class name for description area.
FChoicesClass: '', //the css class name for choices area.
FLeftPageId: '', //the left page.
FRightPageId: '', //the right page.
CPageClass: 'Page',
FIsDisplayTableSupported: null, //whether the browser is the EVIL M$IE6,7 that does not support display: table(-cell).
FCurrPage: 0, //start from 1, 0 for no page has been displayed yet.
FPageCount: 0, //page count.
// /**
// * Get external css stylesheet info.
// * @param {String} Selector The selector in the css style sheet.
// * @param {String} Property The property name.
// * @return {String} The value of the property, or null for undefined property.
// */
// _GetCssInfo: function(Selector, Property) {
// var mCss = document.styleSheets[0].cssRules || document.styleSheets[0].rules;
// for (var mIndex = 0; mIndex // if (mCss[mIndex].selectorText.toLowerCase() == Selector) {
// return mCss[mIndex].style[Property];
// }
// }
// return null;
// },

/**
* @return {Boolean}
*/
_IsDisplayTableSupported: function() {
if (this.FIsDisplayTableSupported != null) {
return this.FIsDisplayTableSupported;
}

this.FIsDisplayTableSupported = !(jQuery.browser.msie && jQuery.browser.version <8.0);
return this.FIsDisplayTableSupported;
},

/**
* Formats radios and checkboxes for the Choices quiz.
*/
_FormatProblemOptions: function() {
var mThis = this;
var mSelector = '.' + this.FProblemClass + ' .' + this.FChoicesClass;
$(mSelector).each(function() {
//Rearrange the options for each problem ordered by offsetWidth of the label tag.
var mLabels = new Array();
mLabels = jQuery.makeArray($('label', this));
mLabels.sort(function(First, Second) {
return $(Second).outerWidth(true) > $(First).outerWidth(true);
});
$(mLabels).appendTo(this);

//Layout the options into the appropreate form.
var mSlots = -1; //Force to create a new row, inside the while() loop.
var mSlotWidth = $(mSelector).width() / 4.0;
var mCellSize = 0;
if (mThis._IsDisplayTableSupported()) {
while (mLabels.length > 0) {
//alert($(mLabels[0]).outerWidth(true) + '::' + $(mLabels[0]).outerHeight(true) + '::' + $(mLabels[0]).html());
if (mSlots <= 0) { //If no empty slot, create a new row.
mCurrRow = $('

');
mCurrRow.appendTo(this);
mSlots = 4;
mCellSize = 0;

var mRealCellWidth = $(mLabels[0]).outerWidth(true);
if (mRealCellWidth mCellSize = 1;
}
if (mRealCellWidth >= mSlotWidth && mRealCellWidth mCellSize = 2;
}
if (mRealCellWidth >= mSlotWidth * 2) {
mCellSize = 4;
}
}
mSlots -= mCellSize;
if (mSlots >= 0) { //If empty slots exists, put the cell into the row.
mLabel = mLabels.shift();
$(mLabel).addClass('___cell');
$(mLabel).css('display', 'table-cell');
$(mLabel).appendTo(mCurrRow);
}
}
$('.___table').each(function() { //Align all the tables and cells.
$(this).css('width', '100%');
var mCellWidth = 100 / $('.___cell', this).length;
$('.___cell', this).css('width', mCellWidth + '%');
});
}
else { // for the evil M$IE6, use table, tr, td tags.
while (mLabels.length > 0) {
if (mSlots <= 0) { //If no empty slot, create a new row.
mCurrRow = $('
');
mRow = $('');
mRow.appendTo(mCurrRow);
mCurrRow.appendTo(this);
mSlots = 4;
mCellSize = 0;

var mRealCellWidth = $(mLabels[0]).attr('offsetWidth');
//The EVIL IE only:
//be sure to use this css reset: table { border-collapse: collapse; border-spacing: 0; }
//otherwise, 2 lines will be occupied by some long problem options instead of 1.
//or use this code instead: var mRealCellWidth = $(mLabels[0]).attr('offsetWidth') * 1.3;
if (mRealCellWidth <= mSlotWidth) {
mCellSize = 1;
}
if (mRealCellWidth > mSlotWidth && mRealCellWidth <= mSlotWidth * 2) {
mCellSize = 2;
}
if (mRealCellWidth > mSlotWidth * 2) {
mCellSize = 4;
}
}
mSlots -= mCellSize;
if (mSlots >= 0) { //If empty slots exists, put the cell into the row.
mLabel = mLabels.shift();
mCell = $('');
$(mLabel).appendTo(mCell);
mCell.appendTo($('tr', mCurrRow)[0]);
}
}
$('.___table').each(function() { //Align all the tables and cells.
$(this).css('width', '100%');
var mCellWidth = 100 / $('tbody tr .___cell', this).length;
$('tbody tr .___cell', this).css('width', mCellWidth + '%');
});
}
});
},

/**
* Create a new page, and add it to the paper.
* @return {jQuery} the new page.
*/
_CreateNewPage: function() {
++this.FPageCount;

mPage = $('

');
mPage.appendTo($('#' + this.FPaperOlId));

return mPage;
},

/**
*
* @param {Number} PageNumber
* @return {jQuery}
*/
_GetPage: function(PageNumber) {
if (PageNumber <1 || PageNumber > this.FPageCount) {
throw new Error('invalid page number: ' + PageNumber + '.');
}
return $('#___page_' + PageNumber);
},

/**
*
*/
_DivideIntoPages: function() {
var mProblems = $('.' + this.FProblemClass + ', .' + this.FDescClass);
var mProblemsCount = mProblems.length;
var mCurrPage = this._CreateNewPage();
//var mPageHeight = mCurrPage.attr('offsetHeight'); chrome: sometimes 0. safari: always 0, IF PUTTED IN $(window).ready().
var mPageHeight = mCurrPage.outerHeight(true); //the same as the code above. FIX: PUT IT INTO $(window).load().
var mUsedPageHeight = 0;
for (var mCurrProblem = 0; mCurrProblem if (mUsedPageHeight + $(mProblems[mCurrProblem]).outerHeight(true) > mPageHeight) {
mCurrPage.hide();
mCurrPage = this._CreateNewPage();
mPageHeight = mCurrPage.outerHeight(true);
mUsedPageHeight = 0;
}
$(mProblems[mCurrProblem]).appendTo(mCurrPage);
mUsedPageHeight += $(mProblems[mCurrProblem]).outerHeight(true);
}
mCurrPage.hide();
},
/**
* Get the current page of the left side, started from 1.
* @return {Number} The current page.
*/
getCurrPage: function() {
if (this.FPageCount == 0) {
throw new Error('No page has been created yet.');
}
return this.FCurrPage;
},
/**
* Trun to a specific page in the left side.
* @param {Number} Value The page number.
*/
setCurrPage: function(Value) {
if (Value <1 || Value > this.FPageCount) {
throw new Error('No such page: ' + Value + '.');
}
this.FCurrPage = parseInt(Value / 2) * 2 + 1; // to get an odd number.
$('#' + this.FLeftPageId + ' .' + this.CPageClass).hide();
$('#' + this.FRightPageId + ' .' + this.CPageClass).hide();
if (this.FCurrPage >= 0) {
$('#___page_' + this.FCurrPage).appendTo($('#' + this.FLeftPageId));
$('#___page_' + this.FCurrPage).show('fast');
if (this.FCurrPage ++this.FCurrPage;
$('#___page_' + this.FCurrPage).appendTo($('#' + this.FRightPageId));
$('#___page_' + this.FCurrPage).show('fast');
--this.FCurrPage;
}
}
},
/**
* @retrun {Number}
*/
getPageCount: function() {
return this.FPageCount;
},
/**
*
*/
Prev: function() {
this.setCurrPage(this.FCurrPage - 2);
},
/**
*
*/
Next: function() {
this.setCurrPage(this.FCurrPage + 2);
}
};

//client code goes here...
$(window).load(function() {
var obj = new TTestPaperProcessor('olThePaper', 'Problem', 'Desc', 'Choices', 'pLeft', 'pRight');
$('#pPrev').click(function() {
try {
obj.Prev();
$('#pPageInfo').text(obj.getCurrPage() + ' of ' + obj.getPageCount());
}
catch (e) {
alert('No such page!');
}
});
$('#pNext').click(function() {
try {
obj.Next();
$('#pPageInfo').text(obj.getCurrPage() + ' of ' + obj.getPageCount());
}
catch (e) {
alert('No such page!');
}
});
//USAGE: http://keith-wood.name/countdown.html
function TimeUp() {
$('#formPaper').submit();
}
$('#pTimer').countdown({
until: '+90m',
compact: true,
format: 'HMS',
description: '',
onExpiry: TimeUp
});
$('#pPageInfo').text(obj.getCurrPage() + ' of ' + obj.getPageCount());
});



嘿嘿,其实这是一个俺们学校一位博导老师的项目的一部分~~托给我做了。马上要出门了,回来放源文件下载,就可以看到效果了~~昨天回来太晚了,现在放出源代码文件下载:点击此处
/201007/yuanma/TestPaperProcessor.rar
推荐阅读
author-avatar
yuyiyin乐悠悠_964
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有