利用CSS隐藏HTML元素并插入替代内容

创建一个支持切换阅读模式和答题模式的Anki问答题模板中,我创建了一个支持切换阅读模式和答题模式的问答题模板,该文最终利用JavaScript将Anki输出的向下箭头删除,并插入自定义的提示语。经过进一步测试,发现实现上述功能完全不需要使用JavaScript,仅使用CSS即可以实现。

Anki产生向下箭头的那行代码如下:

format!("{provided}<br><span id=typearrow>&darr;</span><br>{expected}")

从上面的模板字符串可知向下箭头所在span元素的id为typearrow,在这个元素后面跟着一个br元素,后面紧接着输出的内容是用户输入的答案存在的错误,可以通过继续查阅源代码搞清楚这些内容包含在什么HTML元素中,也可以在背面内容模板中插入以下JavaScript让系统提示:

var typearrow = document.getElementById('typearrow');
alert(typearrow.nextSibling.nextSibling.tagName);

运行上述代码可知br元素后面紧跟着的是span元素。不过,在CSS选择器中,可以用“+”定位到紧邻的兄弟结点,也可以用“*”通配符匹配任何HTML节点,因此,如果我们只想在br元素后面紧跟着的元素前面添加提示,实际上无需搞清楚用户输入的答案存在的错误包含在哪个元素中,只需用CSS选择器“#typearrow + br + *”就可以定位到那个元素,再加上伪元素选择器“::before”,就可以插入提示信息了。

利用上面的思路改造可切换答题模式与阅读模式的问答题模板后,从下面的源代码可以看出,正面内容模板和背面内容模板都更为简洁,特别是背面内容模板,其中的JavaScript代码完全删除了,理论上运行效率也更高。

正面内容模板:

<script>
  // v1.1.8 - https://github.com/SimonLammer/anki-persistence/blob/584396fea9dea0921011671a47a0fdda19265e62/script.js
  if(void 0===window.Persistence){var e="github.com/SimonLammer/anki-persistence/",t="_default";if(window.Persistence_sessionStorage=function(){var i=!1;try{"object"==typeof window.sessionStorage&&(i=!0,this.clear=function(){for(var t=0;t<sessionStorage.length;t++){var i=sessionStorage.key(t);0==i.indexOf(e)&&(sessionStorage.removeItem(i),t--)}},this.setItem=function(i,n){void 0==n&&(n=i,i=t),sessionStorage.setItem(e+i,JSON.stringify(n))},this.getItem=function(i){return void 0==i&&(i=t),JSON.parse(sessionStorage.getItem(e+i))},this.removeItem=function(i){void 0==i&&(i=t),sessionStorage.removeItem(e+i)},this.getAllKeys=function(){for(var t=[],i=Object.keys(sessionStorage),n=0;n<i.length;n++){var s=i[n];0==s.indexOf(e)&&t.push(s.substring(e.length,s.length))}return t.sort()})}catch(n){}this.isAvailable=function(){return i}},window.Persistence_windowKey=function(i){var n=window[i],s=!1;"object"==typeof n&&(s=!0,this.clear=function(){n[e]={}},this.setItem=function(i,s){void 0==s&&(s=i,i=t),n[e][i]=s},this.getItem=function(i){return void 0==i&&(i=t),void 0==n[e][i]?null:n[e][i]},this.removeItem=function(i){void 0==i&&(i=t),delete n[e][i]},this.getAllKeys=function(){return Object.keys(n[e])},void 0==n[e]&&this.clear()),this.isAvailable=function(){return s}},window.Persistence=new Persistence_sessionStorage,Persistence.isAvailable()||(window.Persistence=new Persistence_windowKey("py")),!Persistence.isAvailable()){var i=window.location.toString().indexOf("title"),n=window.location.toString().indexOf("main",i);i>0&&n>0&&n-i<10&&(window.Persistence=new Persistence_windowKey("qt"))}}</script>
  <script>
    var model = Persistence.getItem();
    if (model == null) {
      model = { model:'answer',};
      Persistence.setItem(model);
    }else{
      var back = document.getElementById('back');
      var btnToggle = document.getElementById('btnToggle');
      var answer = document.getElementById('answer');
      if (model.model == 'answer'){
        btnToggle.value = '答题模式';
        back.style = 'display:none';
        answer.style = 'display:bolck';
      }else{
        btnToggle.value = '阅读模式';
        back.style = 'display:bolck';
        answer.style = 'display:none';
      }
    }
    
    function toggleModel(){
      var btnToggle = event.currentTarget;
      var back = document.getElementById('back');
      var answer = document.getElementById('answer');
      if (model.model == 'answer'){
        model.model = 'read';
        btnToggle.value = '阅读模式';
        back.style='display:bolck';
        answer.style = 'display:none';
      }
      else{
        model.model = 'answer';
        btnToggle.value = '答题模式';
        back.style='display:none';
        answer.style = 'display:block';
      }
      Persistence.setItem(model);
    }
  </script>
  <div>
    <a>说明:</a><q>当前模式如下方按钮所示。点击下方按钮可在阅读模式和答题模式之间切换。</q>
  </div>
  <div align="center">
    <input id='btnToggle' type='button' onclick='toggleModel()' value='答题模式'/>
  </div>
  
  <hr class="separator" />
  <div class="h1 xcolor xleft">
    <span>⛳问题</span>	
      <span id="time">
    </span>
  </div>
  <div class="h2 xleft" align='left'>{{edit:问题}}</div>
  <hr class="separator" />
  
  <div class="slide">
    <div class="h1 ycolor yleft">
    <span>👉	口诀</span>
    </div>
    <div class="h3  yleft";align='left'><span class='margin'>{{edit:口诀}}<span></div>
  </div>
  <hr class="separator" />
  
  <div id='answer' class="h1 ycolor xleft" style='display:block'>
    <span class="yimg">✍️	回答</span><br><br>
    {{type:答案}} 	
    <hr class="separator" />
  </div>
  
  <div id='back' style='display:none'>
    <div class="h1 ycolor yleft">
      <span>👍正确答案</span>	
    </div>
    <div class='normal'><span class='margin'>{{edit:答案}}</span></div>
  
    <hr class="separator" />
    <div class="h1 ycolor xleft md-content">
      <span>⚓备注</span>
    </div>
    <div class='normal'><span class='margin'>{{edit:备注}}</span></div>
  </div>

背面内容模板:

<div class="h1 xcolor xleft">
	<span>⛳	问题</span>
		<span id="time">
	</span>
</div>
<div class="h2 xleft" align="left">{{edit:问题}}</div>
<hr class="separator" />

<div class="slide">
	<div class="h1 ycolor yleft">
	<span>👉	口诀</span>
	</div>
	<div class="h3  yleft" align="left">{{edit:口诀}}</div>
</div>
<hr class="separator" />
<div class="slide" id="slide1">
	<div class="h1 ycolor yleft">
	<span>👉答案对比</span>
	<div class= "note"><a>说明:</a>没有另外显示正确答案时表示你的答案完全正确。</div>
	</div>
	<div class="h1  yleft" align="left" >{{FrontSide:type:答案}}</div>
</div>
<hr class="separator" />
<div class="h1 ycolor xleft md-content">
	<span>⚓备注</span>
</div>
<div class='normal'>{{edit:备注}}<div>

样式文件只贴出在Anki自带的问答题模板基础上后来添加的内容,其中值得注意的地方均有注释注明:

@import url("_editor_button_styles.css");

/* ----------调用字体---------- */

@font-face { font-family: yh; src: url('_FZYHJW.ttf'); }
@font-face { font-family: times; src: url('_times.ttf'); }


/* ----------各种样式---------- */

body { background-color: #fff; color: black;font-family:cambria,'Aa奶糖油画体','微软雅黑' }
.card {
     font: 20px/30px Cambria,'Aa可爱の日系中文2万字';
	background-color:#fff;
	#background-image: url(_bg.png);
	#background-size:100%;
}

.h1 { font: 22px/22px 'Aa可爱の日系中文2万字'; padding: 0.3em 0em 0.3em 0.5em; }
.h2 { font: 20px/30px '干就完事了简'; padding: 0.3em 0em 0.3em 0.5em; }

.xleft { border-left: 3px solid #ec6c4f; }
.yleft { border-left: 3px solid #338eca; }
.zleft { border-left: 3px solid #4c991b; }

.xcolor { color: #ec6c4f; }
.ycolor { color: #338eca; }
.zcolor { color: #4c991b; }

.ximg { background: url(_x-day.svg); background-size: 100%; background-repeat: no-repeat; background-position: center; }
.yimg { background: url(_y-day.svg); background-size: 40%; background-repeat: no-repeat; background-position: left; }
.zimg { background: url(_z-day.svg); background-size: 100%; background-repeat: no-repeat; background-position: center; }

.hint { color: #333; }


/* ---------- 其他调整 ---------- */
img { max-width: 100%; vertical-align: middle; }
	.chrome img { max-width: 100%; vertical-align: middle; }
ul,ol { margin-top: 0em; }
li { margin-left: -0.5em; }
hr { height: 1px; width: 100%; display: block; border: 0px solid #fff; vertical-align: middle; margin:5px 0px 10px 0px; background-color: #ccc;}
#time { font-family: yh; float: right; } 


/* ----------夜间模式(Android)---------- */

body.night_mode { background-color: #232323; color:#727272; }
.night_mode .card { background-color: #232323;  color:#727272; }

.night_mode .xleft { border-left: 3px solid #a0a0a0; }
.night_mode .yleft { border-left: 3px solid #a0a0a0; }
.night_mode .zleft { border-left: 3px solid #a0a0a0; }

.night_mode .xcolor { #font-weight: bold; color:#a0a0a0; }
.night_mode .ycolor { #font-weight: bold; color:#a0a0a0; }
.night_mode .zcolor { #font-weight: bold; color:#a0a0a0; }

.night_mode .ximg{ background: url(_x-night.svg); background-size: 100%; background-repeat: no-repeat; background-position: center; }
.night_mode .yimg{ background: url(_y-night.svg); background-size: 100%; background-repeat: no-repeat; background-position: center; }
.night_mode .zimg{ background: url(_z-night.svg); background-size: 100%; background-repeat: no-repeat; background-position: center; }

.night_mode .hint { color: #727272; }
.night_mode u { color: #a0a0a0; background-color: #505050; border-bottom: 2px solid #5f5f5f; }
.night_mode img { filter: alpha(opacity=30); opacity:0.3;  filter:invert;}
.night_mode audio { filter: alpha(opacity=30); opacity:0.3; }
.night_mode hr { background-color: #484848; }


/* ----------动画效果---------- */

.slide { position: relative; -webkit-animation: slide 1s 0s; -webkit-animation-fill-mode: forwards; }

@-webkit-keyframes slide {
	0%	{ opacity: 0  ; top: 100px; }
	50%	{ opacity: 0.8; top: -10px; }
	100%	{ opacity: 1.0; top: -3px; }
}
.color1,q{
	font-weight:bold;
	color:#FF0622;
}
.color2,a,a:link,a:visited,a:hover,a:active{
	font-weight:bold;
	color:blue;
	text-decoration:none;
}
.color3,i{
	font-weight:bold;
	color:rgb(230,12,237);
	font-style: normal;
}
.separator{
	border:none;
	border-top-width:0.3em;
	border-top-style:solid;
	border-top-color:#aaa;
	margin:1.2em 0 1.2em 0;
}
.normal{
	line-height:1.5em;
}
.h3{
	font-family:"Aa奇思胖丫儿";
	color:green;
	background:yellow;
}
span.margin{display:inline-block;margin-left:0.5em;}
b{
	font-size:1.2em;color:#3526E0;
}
u{font-weight:bold;text-decoration:none;color:#D19E25;}

q::before,q::after{
	content:"";
}
#btnToggle {
    background-color: #4CAF50; /* Green */
    border: none;
    color: yellow;
    padding: 0.3em;
    text-align: center;
    text-decoration: none;
    display: inline-block;
    font-size: 1.2em;
	 border-radius:0.5em;
	 box-shadow: 0.1em 0.15em teal;
}
/*拼写正确时的文字样式*/
.typeGood{
 	background-color:#0f0; /*transparent:透明*/
}
/*拼写错误时的文字样式*/
/*没有拼写出来的文字样式*/
.typeBad, .typeMissed{
 	background-color:#ff0;
	color:#FF0622;
	font-weight:bold;
}

code#typeans {
	font-family: "Aa虎头虎脑";
	background-color:#ff0;
	font-weight:bold;
}
.note{
	text-indent:2em;
	margin:1em 0em;
}
/*在用户输入的答案前添加提示*/
code#typeans::before {
	content:"你的答案:";
	color:#33c;
}
/*隐藏anki生成的箭头,该箭头包含在一个id为typearrow的span中*/
#typearrow{
	display:none;
}
/*跳过向下箭头元素及其后面的br元素,添加提示*/
#typearrow + br + *:before{
	content:"正确答案:";
	color:#33c;
	-webkit-text-stroke:0em;
}

这篇文章本质上是上一篇文章的延续,但上一篇文章已经补充过多次,为方便阅读,在此另写一文。下面放一张背面截图:

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yivifu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值