溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Angularjs如何實(shí)現(xiàn)移動(dòng)端在線測(cè)評(píng)效果

發(fā)布時(shí)間:2021-05-21 14:22:55 來(lái)源:億速云 閱讀:186 作者:小新 欄目:web開發(fā)

這篇文章主要介紹了Angularjs如何實(shí)現(xiàn)移動(dòng)端在線測(cè)評(píng)效果,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

注:此文所用的angular版本為 1.6

一、運(yùn)行效果圖

Angularjs如何實(shí)現(xiàn)移動(dòng)端在線測(cè)評(píng)效果

二、需求

1. 點(diǎn)擊選項(xiàng)時(shí),背景變?yōu)辄S色(即選中狀態(tài)),并且自動(dòng)切換到下一題

2. 切換到下一題時(shí),頂部進(jìn)度隨之改變

3. 選中時(shí)要把對(duì)應(yīng)的分值記錄下來(lái)(因?yàn)橐鶕?jù)分值算出最后的測(cè)評(píng)結(jié)果)

4. 通過(guò)向右滑動(dòng)可以查看前面做過(guò)的題目

5. 當(dāng)前題目沒(méi)選,無(wú)法切換到下一題

6. 當(dāng)選中最后一道題目時(shí),切換到測(cè)評(píng)結(jié)果頁(yè)

三、具體實(shí)現(xiàn)

 題目json數(shù)據(jù),總共10道題,這里為了節(jié)省篇幅,就只貼出3道了。 (Score是分?jǐn)?shù), OrderNo是答案序號(hào))

{ "Questions":
 [
 { 
  "Question":"您的年齡范圍:",
  "AnswerList":[
   {"Text":"30歲以下","Score":5,"OrderNo":0},
   {"Text":"30-39歲","Score":4,"OrderNo":1},
   {"Text":"40-49歲","Score":3,"OrderNo":2},
   {"Text":"50-59歲","Score":2,"OrderNo":3},
   {"Text":"60歲以上","Score":1,"OrderNo":4}]
 },
 { 
  "Question":"您的婚姻狀況為:",
  "AnswerList":[
  {"Text":"未婚","Score":5,"OrderNo":1},
  {"Text":"已婚","Score":4,"OrderNo":2},
  {"Text":"單身有婚史","Score":3,"OrderNo":3},
  {"Text":"喪偶","Score":2,"OrderNo":4},
  {"Text":"不詳","Score":1,"OrderNo":5}]
 },
 { 
  "Question":"您的收入需要用來(lái)供養(yǎng)其他人(如父母或子女)嗎?",
  "AnswerList":[
  {"Text":"不需供養(yǎng)其他人","Score":5,"OrderNo":1},
  {"Text":"供養(yǎng)1人","Score":4,"OrderNo":2},
  {"Text":"供養(yǎng)2人","Score":3,"OrderNo":3},
  {"Text":"供養(yǎng)3人","Score":2,"OrderNo":4},
  {"Text":"供養(yǎng)4人或以上","Score":1,"OrderNo":5}]
 }
 ]
}

Html代碼

<div class="wrapper" ng-controller="RiskTestController as vm">
 <div class="process-box">
 <ul>
  <li class="page-icon"><span class="icon icon-txt">1</span></li>
  <li class="page-icon"><span class="icon icon-txt">2</span></li>
  <li class="page-icon"><span class="icon icon-txt">3</span></li>
  <li class="page-icon"><span class="icon icon-txt">4</span></li>
  <li class="page-icon"><span class="icon icon-txt">5</span></li>
  <li class="page-icon"><span class="icon icon-txt">6</span></li>
  <li class="page-icon"><span class="icon icon-txt">7</span></li>
  <li class="page-icon"><span class="icon icon-txt">8</span></li>
  <li class="page-icon"><span class="icon icon-txt">9</span></li>
  <li class="page-icon"><span class="icon icon-txt">10</span></li>
 </ul>
 <div class="page-info">
  已完成 {{vm.count}}/10
 </div>
 </div>
 <ul class="list-box" id="listBox">
 <li class="list-item" ng-repeat="question in vm.questionList track by $index" ng-class="{'first-li': $index == 0}">
  <div class="question-box">
  <div class="question">{{$index + 1}}. {{question.Question}}</div>
  <ul class="answer">
   <li class="answer-item" 
   ng-repeat="answer in question.AnswerList track by $index" 
   ng-click="vm.OnClickAnswer(answer, $parent.$index)"
   ng-class="{'selected': answer.Selected}">
   {{vm.letter[$index]}}. {{answer.Text}}
   </li>
  </ul>
  </div>
 </li>
 </ul>
 <div ng-show="vm.showResult">
 <span>{{vm.point}}</span>
 </div>
 </div>

核心CSS樣式代碼

.wrapper{
  width: 100%;
  height: 100%;
  position: relative;
  overflow: hidden;
 }
 .process-box{
  width: 17.25rem;
  height: 2.5rem;
  line-height: 2.5rem;
  background-color: #FFF;
  margin: 1.5rem auto;
  border-radius: 0.2rem;
 }
 .page-icon{
  float: left;
  font-size: 0.4rem;
  color: #FFE7C9;
  width: 1.32rem;
  text-align: center;
 }
 .page-info{
  font-size: 0.65rem;
  color: #F3A84D;
 }
 .question-box{
  width: 17.25rem;
  background-color: #FFF;
  margin-left: 0.75rem;
  border-radius: 0.2rem;
 }
 .question{
  font-size: 0.8rem;
  color: #43689F;
  padding: 1.1rem 0 0.8rem 0.75rem;
 }
 .answer-item{
  font-size: 0.75rem;
  color: #80A1D0;
  border-top: 1px solid #EEE;
  padding: 1.1rem 0 1.1rem 1.0rem;
 }
 .icon-txt{
  background-color: orange;
  border-radius: 0.5rem;
  display: block;
  width: 0.8rem;
  height: 0.8rem;
  line-height: 0.8rem;
  margin: 0.95rem auto;
 }
 .icon-txt-active{
  background-color: #FFE7C9;
  border-radius: 0.3rem;
  display: block;
  width: 0.3rem;
  height: 0.3rem;
  line-height: 2.0rem;
  color: #FFF;
  margin: 1.25rem auto;
 }
 .list-item {
  width: 100%;
  position: absolute;
  transform: translate3d(100%,0,0);
  transition: transform 0.5s;
 }
 .first-li {
  transform: translate3d(0,0,0);
 }
 .selected {
  background-color: orange;
 }

控制器代碼(Controller)

(function (agr) {
 //模塊 - app
 var app = agr.module('app', []);
 //控制器 - 風(fēng)險(xiǎn)測(cè)評(píng)
 app.controller('RiskTestController', ['$scope', '$http', RiskTestController]);
 function RiskTestController($scope, $http) {
 var vm = this;
 vm.letter = ['A', 'B', 'C', 'D', 'E']; //答案編號(hào)
 vm.questionList = []; //題目
 vm.point = 0;  //得分
 vm.showResult = false; //是否顯示結(jié)果頁(yè)
 //加載數(shù)據(jù) 
 $http({
  method: 'GET',
  url: '/Service/RiskTest',
 }).then(function (resp) {  
  vm.questionList = resp.data.Questions;
 }, function (resp) {
  console.log("ERROR", resp);
 });
 var lis = document.querySelectorAll(".list-item"), //題目列表
  count = 0, //做了多少道題
  index = 0, //當(dāng)前第幾題
  BIG = 9; //最大索引值,因?yàn)榭偣?0道題,所以是9(常量)
 //選擇答案
 vm.OnClickAnswer = function (answer, $parentIndex) {

  var icons = document.querySelectorAll(".icon"),
  curr = $parentIndex; //當(dāng)前題目索引
  next = $parentIndex + 1; //下一題索引
  nextQuestion = vm.questionList[next]; //下一道題
  //當(dāng)前問(wèn)題的答案列表
  var answerList = vm.questionList[$parentIndex].AnswerList;
  //為每個(gè)答案對(duì)象添加屬性 Selected, 默認(rèn)值為false
  for (var i = 0, len = answerList.length; i < len; i++) {
  answerList[i].Selected = false;
  }
  //將選中的答案設(shè)置為true (從而應(yīng)用樣式.selected 將背景色設(shè)置為黃色)
  answer.Selected = true;
  //判斷是否為最后一道題
  if ($parentIndex < BIG) { //不是最后一題
  //改變頂部進(jìn)度樣式
  icons[curr].classList.remove("icon-txt");
  icons[curr].classList.add("icon-txt-active");
  //切換到下一題
  lis[curr].style.webkitTransform = 'Translate3d(-100%,0,0)';
  nextQuestion && (lis[next].style.webkitTransform = 'Translate3d(0,0,0)');
  } else { //是最后一題
  //改變頂部進(jìn)度樣式
  icons[curr].classList.remove("icon-txt");
  icons[curr].classList.add("icon-txt-active");
  //計(jì)算分?jǐn)?shù)
  vm.point = CalcPoint();
  //顯示測(cè)評(píng)結(jié)果
  vm.showResult = true;
  }
  //做了多少題
  count = CalcCount();

  //因?yàn)檫x中答案會(huì)自動(dòng)切換到下一題,所以索引更新為next
  index = next;  
 }
 //計(jì)算分?jǐn)?shù)
 var CalcPoint = function () {
  var point = 0;
  for (var i = 0, lenq = vm.questionList.length; i < lenq; i++) {
  for (var k = 0, lena = vm.questionList[i].AnswerList.length; k < lena; k++) {
   if (vm.questionList[i].AnswerList[k].Selected) {
   point += vm.questionList[i].AnswerList[k].Score;
   }
  }
  }
  return point;
 }
 //計(jì)算當(dāng)前做了多少道題
 var CalcCount = function(){
  var count = 0;
  for (var i = 0, lenq = vm.questionList.length; i < lenq; i++) {
  for (var k = 0, lena = vm.questionList[i].AnswerList.length; k < lena; k++) {
   if (vm.questionList[i].AnswerList[k].Selected) {
   count++;
   }
  }
  }
  return count;
 }
 /** 觸屏滑動(dòng)效果處理 == 開始 == **/
 var offsetX = 0, //手指滑動(dòng)偏移量
  startX,  //滑動(dòng)開始時(shí)的X軸坐標(biāo)點(diǎn)
  startTime; //手指滑動(dòng)開始時(shí)間
 //觸屏開始
 var startHandler = function (evt) {
  //每次觸屏?xí)r將偏移量重置為0
  offsetX = 0;
  //記錄X坐標(biāo)
  startX = evt.touches[0].pageX;
  //取得時(shí)間戳
  startTime = new Date() * 1;
 };
 //觸屏滑動(dòng)
 var moveHandler = function (evt) {
  //阻止默認(rèn)事件
  evt.preventDefault();
  //記錄手指滑動(dòng)的偏移量
  offsetX = evt.touches[0].pageX - startX;
  var curr = index,
  prev = index - 1,
  next = index + 1,
  prevQuestion = vm.questionList[prev],
  nextQuestion = vm.questionList[next],
  width = window.innerWidth; 
  //手指滑動(dòng)時(shí)題卡跟著手指滑動(dòng)(向右滑:[偏移量大于0,即正數(shù),并且不是第一道題])
  if (offsetX > 0 && index > 0) {
  lis[curr].style.webkitTransform = 'Translate3d(' + offsetX + 'px, 0, 0)';
  prevQuestion && (lis[prev].style.webkitTransform = 'Translate3d(' + (offsetX - width) + 'px, 0, 0)');
  }
  //手指滑動(dòng)時(shí)題卡跟著手指滑動(dòng)(向左滑:[偏移量小于0,即負(fù)數(shù),并且不是最后一題])
  if (offsetX < 0 && index < count) {
  lis[curr].style.webkitTransform = 'Translate3d(' + offsetX + 'px, 0, 0)';
  nextQuestion && (lis[next].style.webkitTransform = 'Translate3d(' + (offsetX + width) + 'px, 0, 0)');
  }
 };
 //觸屏結(jié)束
 var endHandler = function (evt) {
  var boundary = window.innerWidth / 5, //當(dāng)手指滑動(dòng)的偏移量為屏幕的5分之一時(shí)才進(jìn)行切換
  quickBoundary = 60,   //當(dāng)手指快速滑動(dòng)時(shí),偏移量為60即可 
  endTime = new Date() * 1;   //獲取結(jié)束時(shí)間戳
  //判斷是否為快速滑動(dòng)
  if (endTime - startTime > 1000) {
  //判斷是向左滑還是向右滑
  if (offsetX > 0) {
   //判斷是否達(dá)到切換偏移量
   if (offsetX >= boundary) {
   MoveToRight();
   } else {
   ResetMoveRight();
   }
  } else{
   if (offsetX < -boundary) {
   MoveToLeft();
   } else {
   ResetMoveLeft();
   }
  }
  } else {
  if (offsetX > 0) {
   if (offsetX >= quickBoundary) {
   MoveToRight();
   } else {
   ResetMoveRight();
   }
  } else {
   if (offsetX < -quickBoundary) {
   MoveToLeft();
   } else {
   ResetMoveLeft();
   }
  }
  }
 };
 //向右滑動(dòng)事件
 var MoveToRight = function () {
  var curr = index,
  prev = index -1,
  prevQuestion = vm.questionList[prev];
  if (curr > 0) {
  lis[curr].style.webkitTransform = 'Translate3d(100%, 0, 0)';
  prevQuestion && (lis[prev].style.webkitTransform = 'Translate3d(0, 0, 0)');
  index--;
  }  
 }
 //右滑重置(當(dāng)滑動(dòng)距離沒(méi)達(dá)到切換偏移量時(shí),題卡回到原點(diǎn))
 var ResetMoveRight = function () {
  var curr = index,
  prev = index -1,
  prevQuestion = vm.questionList[prev];
  lis[curr].style.webkitTransform = 'Translate3d(0, 0, 0)';
  prevQuestion && (lis[prev].style.webkitTransform = 'Translate3d(-100%, 0, 0)');
 }
 //向左滑動(dòng)事件
 var MoveToLeft = function () {
  var curr = index,
  next = index + 1,
  nextQuestion = vm.questionList[next];
  if (curr < count) {
  lis[curr].style.webkitTransform = 'Translate3d(-100%, 0, 0)';
  nextQuestion && (lis[next].style.webkitTransform = 'Translate3d(0, 0, 0)');
  index++;
  } 
 }
 //左滑重置(當(dāng)滑動(dòng)距離沒(méi)達(dá)到切換偏移量時(shí),題卡回到原點(diǎn))
 var ResetMoveLeft = function () {
  var curr = index,
  next = index + 1,
  nextQuestion = vm.questionList[next];
  lis[curr].style.webkitTransform = 'Translate3d(0, 0, 0)';
  nextQuestion && (lis[next].style.webkitTransform = 'Translate3d(100%, 0, 0)');
 }
 //監(jiān)聽(tīng)滑動(dòng)事件 
 var outer = document.getElementById("listBox");
 outer.addEventListener('touchstart', startHandler);
 outer.addEventListener('touchmove', moveHandler);
 outer.addEventListener('touchend', endHandler);
 

 /** 觸屏滑動(dòng)效果處理 == 結(jié)束 == **/
 }
})(angular);

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“Angularjs如何實(shí)現(xiàn)移動(dòng)端在線測(cè)評(píng)效果”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來(lái)學(xué)習(xí)!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI