Home  >  Article  >  Web Front-end  >  Implementation code of automatic test paper layout system based on jQuery_jquery

Implementation code of automatic test paper layout system based on jQuery_jquery

WBOY
WBOYOriginal
2016-05-16 18:12:361184browse

Generate a multi-page test paper based on the provided test paper questions (which is a clean HTML webpage with only "data"). The user can turn pages and has a time limit for answering questions. The questions in the test paper displayed to the user need to occupy as little space as possible. (For example, in multiple-choice questions, two shorter options are merged from two lines to one). The same question should not be displayed across pages to facilitate the answerers. The administrator can change the style of the test paper (font, color, line spacing, page margins, Like word processing software...), some explanatory text can be inserted between the questions (such as informing the respondent of the instructions for answering, etc.). The question title, multiple-choice question options, and explanatory text can contain multimedia information (text, pictures, lists, tables, videos, etc...). There is no limit to the number of multiple-choice options and no limit to single-choice or multiple-choice questions. Page turning should have customizable animation effects

The test paper sample provided is similar to the following (Input):

Copy code The code is as follows:


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


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









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









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









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


  5. 4.床前明月光,



  6. 5. What kind of teacher do you think is a good teacher?






Thinking
What should we do in the face of this demand? Using JavaScript too, it seems. Later, I decided to use jQuery and Aptana as IDE (although the jQuery support library cannot be installed on Windows, it will be fine if I change the OS, which is strange), and I will use CSS for formatting.

Specific steps:

Import the test paper question HTML
Format all multiple-choice questions, divide a row into four positions, and try to fit the options into one position, two positions, or four Position (that is, the effect of four items in a row, two items in a row, or one item in a row)
Paging all questions
The idea is still clear, but due to the large number of browsers, it is still quite troublesome, and I am a novice. Before I came into contact with jQuery...

Implement
page file (different from the example, but the same format)
Copy code The code is as follows:




No title...








PrevPage

NextPage

Loading the test...






    left


    right



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


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









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









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









  4. 4What kind of teacher do you think is a good teacher?








  5. It’s still a multiple-choice question: a lot of explanatory text. A lot of captions. A lot of captions. A lot of captions. A lot of captions.


  6. 5 What kind of teacher do you think is a good teacher?









  7. 5 What kind of teacher do you think is a good teacher?









  8. 6What kind of teacher do you think is a good teacher?

















Style file (CSS)
Copy code The code is as follows:

/* YahooUI CSS Reset */
body,div,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; }

#divToolbar { height: 35px; }
#divPrev, #divNext { float: left; width: 100px; height: 30px; border: solid 1px green; background-color: #999999; }
#divPageInfo { float: left; width: 100px; height: 30px; }
#divTimer { float: left; width: 500px; height: 30px; }


/*for debugging... perhaps for non-IE only*/
/**label { outline: dotted 1px red; background-color: gray; }**/
/**div {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 < mCss.length; ++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 < 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();
$(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));

mPage를 반환합니다.
},

/**
*
* @param {Number} 페이지 번호
* @return {jQuery}
*/
_GetPage: function(PageNumber) {
if (PageNumber < 1 || PageNumber > this.FPageCount) {
throw new Error('잘못된 페이지 번호: ' PageNumber '.');
}
return $('#___page_' 페이지 번호);
},

/**
*
*/
_DivideIntoPages: function() {
var mProblems = $('.' this.FProblemClass ', .' this.FDescClass) ;
var mProblemsCount = mProblems.length;
var mCurrPage = this._CreateNewPage();
//var mPageHeight = mCurrPage.attr('offsetHeight'); chrome: 때때로 0. safari: 항상 0, $(window).ready()에 넣은 경우.
var mPageHeight = mCurrPage.outerHeight(true); //위의 코드와 동일합니다. 수정: $(window).load()에 넣으세요.
var mUsedPageHeight = 0;
for (var mCurrProblem = 0; mCurrProblem < mProblemsCount; 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();
},
/**
* 1부터 시작하여 왼쪽의 현재 페이지를 가져옵니다.
* @return {Number} 현재 페이지입니다.
*/
getCurrPage: function() {
if (this.FPageCount == 0) {
throw new Error('페이지가 없습니다. 아직 생성되지 않았습니다.');
}
return this.FCurrPage;
},
/**
* 왼쪽의 특정 페이지로 이동합니다.
* @param {Number} 값 페이지 번호입니다.
*/
setCurrPage: function(Value) {
if (Value < 1 || Value > this.FPageCount) {
throw new Error('해당 페이지가 없습니다: ' 값 '.');
}
this.FCurrPage =parseInt(Value / 2) * 2 1; // 홀수를 얻으려면.
$('#' 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.FPageCount) {
this.FCurrPage;
$('#___page_' this.FCurrPage).appendTo($('#' this.FRightPageId));
$('#___page_' this.FCurrPage).show('fast');
--this.FCurrPage;
}
}
},
/**
* @retrun {번호}
*/
getPageCount: function() {
return this.FPageCount;
},
/**
*
*/
이전: function() {
this.setCurrPage(this.FCurrPage - 2);
},
/**
*
*/
다음: function() {
this.setCurrPage(this.FCurrPage 2);
}
};

//클라이언트 코드는 여기에 있습니다...
$(window).load(function() {
var obj = new TTestPaperProcessor('olThePaper', 'Problem', 'Desc', '선택', 'divLeft', 'divRight');
$('#divPrev').click(function() {
try {
obj.Prev();
$(' #divPageInfo').text(obj.getCurrPage() ' of ' obj.getPageCount());
}
catch (e) {
alert('해당 페이지가 없습니다!'); }
});
$('#divNext').click(function() {
try {
obj.Next();
$('#divPageInfo').text (obj.getCurrPage() ' of ' obj.getPageCount());
}
catch (e) {
alert('해당 페이지가 없습니다!')
}
}) ;
//USAGE: http://keith-wood.name/countdown.html
function TimeUp() {
$('#formPaper').submit()
}
$('#divTimer').countdown({
until: ' 90m',
compact: true,
format: 'HMS',
description: '',
onExpiry: TimeUp
});
$('#divPageInfo').text(obj.getCurrPage() ' of ' obj.getPageCount());


嘿嘿,其实这是一个俺们school校一位博导老师的项目的一part分~托给我做了。
测试代码打包
http //xiazai.jb51 .net/201101/yuanma/TestPaperProcessor.rar
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn