前言:公司前端只会BootStrap写的html+css,不是前后端分离的开发模式,所以只能自己搞JSP和JavaScript,有点浪费光阴。不过心态要摆正,既来之则安之,总结几个常用的JavaScript和JSP的常用知识以便日后查看。
1、如何等待ajax异步完成再执行相应操作
要先引入jQuery.js
//ajax操作
myajax = $.ajax(
{
url: "",
async:false,
type: "post",
success: function (data) {
}
});
//myajax请求完毕时执行
$.when(myajax).done(function () {
//要执行的操作
});
}
2、js中动态添加JavaScript语句
动态脚本指的是在页面加载时不存在,但将来的某一时刻通过修改该DOM动态添加的脚本,比如在ajax异步执行完后再加载js进行渲染UI等操作。
<script>
$().ready(function getCode()
{
var htmlobj=$.ajax({url:"/tempfile/"+"${temPath}",async:false});
var str =htmlEncode(htmlobj.responseText);
$("#file").html(str);
//htmlob请求完毕时,再动态加载js
$.when(htmlobj).done(function ()
{
loadScript();
})
}
</script>
动态加载js:(和操作HTML元素一样,创建动态脚本也有两种方式:插入外部文件和直接插入JavaScript代码。)
<script>
//动态加载JS,插入外部文件方式,这里是为了ajax异步加载代码块后利用prism.js进行代码高亮渲染
function loadScript()
{
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "/prism/prism.js";
document.body.appendChild(script);
}
</script>
3、jsp中使用<c:foreach>同时遍历两个list集合
先确保在jsp页面中已加入jstl(JSP标准标签库):
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
有时我们拿到两个长度相等的List,不想封装到一起,又想同时遍历,就需要用到下面的方法。
这里需要遍历从控制器传过来的两个List集合:gallerylist 和 classlist
<c:forEach items="${requestScope.gallerylist}" var="gallerylist" varStatus="loop">
<h4 class="card-title">${gallerylist.title}</h4>
<p class="card-text">
<span class="badge badge-${classlist[loop.count-1][0]}">${gallerylist.label_1}</span>
<span class="badge badge-${classlist[loop.count-1][1]}">${gallerylist.label_2}</span>
<span class="badge badge-${classlist[loop.count-1][2]}">${gallerylist.label_3}</span>
<span class="badge badge-${classlist[loop.count-1][3]}">${gallerylist.label_4}</span>
<span class="badge badge-${classlist[loop.count-1][4]}">${gallerylist.label_5}</span>
</p>
</c:forEach>
第一个 gallerylist 正常使用常规方法即可。
第二个 classlist , 我们使用 varStatus 这个关键属性,那么当值为 loop 时,loop.count 代表当前被遍历元素块已执行的次数,例如,当遍历到第五次时,gallerylist 已经按顺序取到 index 为 4 的值,同样 classlist 也需要取 index 为 4 的值,这时用 [loop.count-1] 来标注 index ,刚好为 4 。
4、jQuery中$.each()方法的使用
$.each()是对数组,json和dom结构等的遍历
①遍历一维数组
var arr1=['aa','bb','cc','dd'];
$.each(arr1,function(i,val){ //两个参数,第一个参数表示遍历的数组的下标,第二个参数表示下标对应的值
console.log(i+'```````'+val);
输出的结果为:
0```````aa
1```````bb
2```````cc
3```````dd
②遍历json
var json1={key1:'a',key2:'b',key3:'c'};
$.each(json1,function(key,value){ //遍历键值对
console.log(key+'````'+value);
})
输出的结果为:
key1````a
key2````b
key3````c
5、js获取select标签选中的值
对于以下select标签,获取当前选择的值得方式如下:
<select id="test" name="">
<option value="1">text1</option>
<option value="2">text2</option>
</select>
①javascript原生的方法
- 拿到select对象: var myselect=document.getElementById("test");
- 拿到选中项的索引:var index=myselect.selectedIndex ; // selectedIndex代表的是你所选中项的index
- 拿到选中项options的value: myselect.options[index].value;
- 拿到选中项options的text: myselect.options[index].text;
- jquery方法(前提是已经加载了jquery库)
②jquery方法(前提是已经加载了jquery库)
- var options=$("#test option:selected"); //获取选中的项
- alert(options.val()); //拿到选中项的值
- alert(options.text()); //拿到选中项的文本
6、html 解决长串英文字母显示不能自动换行的方法
英文字母之间如果没有空格,系统认为这是一个单词,就不会自动换行,一但有空格就会换行,汉字就没有这种情况.
解决办法:
word-break:break-all;
CSS中英文换行问题:
1. word-break:break-all;只对英文起作用,以字母作为换行依据
2. word-wrap:break-word; 只对英文起作用,以单词作为换行依据
3. white-space:pre-wrap; 只对中文起作用,强制换行
4. white-space:nowrap; 强制不换行,都起作用
5. white-space:nowrap; overflow:hidden; text-overflow:ellipsis;不换行,超出部分隐藏且以省
7、js中boolean判断失效问题
<body>
<div id="radioTest" style="margin-left: 40%;margin-right: 40%;">
<input type="radio" name="flag" id="flag" value="true" onclick="trueClick()"/>真
<input type="radio" name="flag" id="flag" value="false" onclick="falseClick()"/>假
</div>
<script type="text/javascript">
function trueClick() {
const flag = $("#radioTest input[name='flag']:checked").val();
if (flag == true) {
console.log("true被选择");
}
console.log("真——被点击,其值为:" + flag + " 其类型为:" + typeof flag);
}
function falseClick() {
const flag = $("#radioTest input[name='flag']:checked").val();
if (flag == false) {
console.log("false被选中")
}
console.log("真——被点击,其值为:" + flag + " 其类型为:" + typeof flag);
}
</script>
</body>
如上述代码,为什么不能打印true被选择和false被选择这两条语句?
原因:
从<input type="radio" name="flag" id="flag" value="true" οnclick="trueClick()"/>中获取的值是String类型,而不是Boolean类型,flag和true进行比较的结果只能是false。
解决方案:字符串类型转换为boolean类型
8、html 的<textarea>文本域无故产生空行
如果这样写,页面载入后,会无故产生几行空行
<textarea name="txtara1" id="txtara1" cols="20" rows="11">${obj.remark}
</textarea>
必须得让开始标签<textarea>和</textarea>在同一行才行:
<textarea name="txtara1" id="txtara1" cols="20" rows="11">${obj.remark}</textarea>
9、<pre>和<code>组合标签显示代码块时,其开始标签必须在同一行,否则显示错乱
//<pre>和<code>必须同行,否则显示错乱
<pre class="line-numbers">
<code id="file" class="language-java">
</code></pre>
10、form表单重复提交处理
在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交。
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML>
<html>
<head>
<title>Form表单</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/servlet/DoFormServlet" method="post">
用户名:<input type="text" name="username">
<input type="submit" value="提交" id="submit">
</form>
</body>
</html>
场景1:在网络延迟的情况下让用户有时间点击多次submit按钮导致表单重复提交
解决方案:
既然存在上述所说的表单重复提交问题,那么我们就要想办法解决,比较常用的方法是采用JavaScript来控制Form表单只能提交一次,具体做法如下:
修改form.jsp页面,添加如下的JavaScript代码来防止表单重复提交
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML>
<html>
<head>
<title>Form表单</title>
<script type="text/javascript">
var isCommitted = false;//表单是否已经提交标识,默认为false
function dosubmit(){
if(isCommitted==false){
isCommitted = true;//提交表单后,将表单是否已经提交标识设置为true
return true;//返回true让表单正常提交
}else{
return false;//返回false那么表单将不提交
}
}
</script>
</head>
<body>
<form action="${pageContext.request.contextPath}/servlet/DoFormServlet" onsubmit="return dosubmit()" method="post">
用户名:<input type="text" name="username">
<input type="submit" value="提交" id="submit">
</form>
</body>
</html>
场景二:表单提交后用户点击【刷新】按钮导致表单重复提交
场景三:用户提交表单后,点击浏览器的【后退】按钮回退到表单页面后进行再次提交
使用JavaScript防止表单重复提交的做法只对上述提交到导致表单重复提交的三种场景中的【场景一】有效,而对于【场景二】和【场景三】是没有用,依然无法解决表单重复提交问题。
对于【场景二】和【场景三】导致表单重复提交的问题,既然客户端无法解决,那么就在服务器端解决,这就是需要保证接口的幂等性。
11、jsp接收action的值的方法总结(针对Structs2)
①Action类文件中只要有变量的get和set方法,就可以在JSP页面上通过EL表达式使用:
Struts2框架其实对request传值方式做了封装。只要在action中get和set了某属性,则可在jsp中直接使用
<script type="text/javascript">
var test= ${yourVariable};
</script>
但是定义的成员变量多了,感觉整个Action的代码就很长了。这个时候可以使用一些Servlet API进行值的存取操作:HttpServletRequest、HttpSession和ServletContext。Struts2对这个三个对象用Map进行了封装,我们就可以使用Map对象来存取数据了。
②Action类文件中,ServletActionContext作容器,让HttpServletRequest等serAttribute()传值到jsp,最后通过el表达式访问即可${requestScope.yourVariable}
request传值
(A)导入ServletActionContext类:
import org.apache.struts2.ServletActionContext;
(B) 获得request对象,具体的方法如下:
HttpServletRequest request = ServletActionContext.getRequest ();
(C)通过setAttribute()方法把需要传递的数据对象放入request对象中:
request.setAttribute("key",Object);application传值
(A)导入ServletActionContext类:
import org.apache.struts2.ServletActionContext;
(B)获得application对象,具体的方法如下:
ServletContext application = ServletActionContext.getServletContext ();
C)通过setAttribute()方法把需要传递的数据对象放入application对象中:
application.setAttribute("key",Object);session传值
(A)导入ActionContext类:
import com.opensymphony.xwork2.ActionContext;
(B) 获得session对象,具体的方法如下:
ActionContext context= ActionContext.getContext();
Map session = (Map)context.getSession();
(C)通过put()方法把需要传递的数据对象放入session对象中:
session.put("key",Object);
jsp通过el表达式直接使用:
${a}
${b}
${c}
or
${requestScope.a}
${sessionScope.b}
${applicationScope.c}
12、html文字过长显示省略号
<p style="overflow: hidden;white-space: nowrap;text-overflow: ellipsis;max-width: 16rem">
13、${param.xxx}获取url中的参数
在项目中看到了一个很奇怪的EL表达式...${param.pageNumber},最初一直找不到param.pageNumber在哪里定义的...
EL表达式${param.xxx}可以从url中获取参数放在页面中直接使用
比如:一个网址:127.0.0.1/test/testparam?test1=3&test2=hs
用${param.test1}就可以直接获取到test1的值,也就是3
用${param.test2}就可以直接获取到test2的值,也就是hs
${param.xxx} 就等价于 request.getparam("xxx"),也就是服务器从页面或者客户端获取的内容
14、Struts2中调用action中的方法method只能是无参的方法
Struts2动态方法调用中利用Java的反射技术是找到相应的方法的。但是Struts2的规范里面方法是不需要有参数的,加了的话会反而找不到的。那个方法会被认为是action你自己定义的一个业务处理反复供你内部调用而已,故抛出java.lang.NoSuchMethodError
所以struts2中调用action中的方法method只能是无参的方法。