前端调试指南指北

做人做事,安全第一

目录

1. 防止input回车提交表单Form

描述: form表单中存在button和table,table中含有input搜索框,在input中输入内容后,按回车键(Enter键),会自动触发form表单提交。

form主要代码如下:

<form id="form" method="post">
    <div class="main-actions">
        <div class="row">
            <div class="col-sm-6">
                <button class="btn btn-wf-primary" id="search"><i class="be-icon fa fa-refresh"></i>搜索</button>
            </div>
        </div>
    </div>
    
    <div class="main-content">
        <table class="table" id="user_table">
            <thead>
                <tr>
                    <th width="100px">用户ID</th>
                    <th width="100px">用户姓名</th>
                    <th width="100px">用户电话</th>
                </tr>
            </thead>
            <tbody>
                <tr class="searchTr">
                    <td><input type="text" class="form-control" name="user_id"></td>
                    <td><input type="text" class="form-control" name="user_name"></td>
                    <td><input type="text" class="form-control" name="user_phone"></td>
                </tr>
            </tbody>
        </table>
    </div>
</form>

原因:

当button的type="submit"时(默认为submit),input文本框(input type="text")输入后,按回车键(Enter键)将触发提交。

当button的type="button"时,input文本框输入后,按回车键不会触发提交。


代码简单示例:form表单中含table也是类似的情况

<!DOCTYPE html>
<html>
<head>
    <title>防止input回车提交表单Form演示</title>
</head>
<body>
    <form method="post">
        请输入用户ID: <input type="text" name="userid" id="userid" />
        <br>    
        请输入用户姓名: <input type="text" name="username" id="username" />
        <br>
        <!-- 1. 无type属性或type属性值为submit时,在input中按Enter键都将触发提交操作 -->
        <!-- 2. type属性值为button时,在input中按Enter键不触发提交操作 -->
        <button type="submit" onclick="commit_onclick()">点击提交</button>
    </form> 
    <script>
        function commit_onclick() {
            var userid = document.getElementById("userid").value;
            var username = document.getElementById("username").value;
            window.alert('Hello ' + userid + '[' + username + ']');
        }
    </script>
</body>
</html>

2. Uncaught TypeError: $(...).bootstrapTable is not a function

出现这种错误的原因,可能是:

<1> jQuery和bootstrap顺序颠倒

<2> js文件重复导入

<3> 没有初始化bootstrapTable,直接refresh

<4> bootstrap版本和bootstrap-table版本不匹配


<1> jQuery和bootstrap顺序颠倒

引入js时,jQuery必须放在最前面,然后是bootstrap,顺序不能颠倒。

Bootstrap官网(Bootstrap 4.0版本)给出了的模板,如下:

( 链接为 : https://v4.bootcss.com/docs/4.0/getting-started/introduction/

<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">

    <title>Hello, world!</title>
  </head>
  <body>
    <h1>Hello, world!</h1>

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
    <script src="https://cdn.bootcss.com/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
    <script src="https://cdn.bootcss.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
  </body>
</html>

涉及到bootstrap-table,bootstrap-table-zh-CN(汉化),给出正确的导入顺序,如下:

<script src="${pageContext.request.contextPath}/js/jquery-3.1.0.min.js"></script>
<script src="${pageContext.request.contextPath}/js/bootstrap.min.js"></script>
<script src="${pageContext.request.contextPath}/js/bootstrap-table.min.js"></script>
<script src="${pageContext.request.contextPath}/js/bootstrap-table-zh-CN.min.js"></script>

<2> js文件重复导入

在同一个html或jsp文件中,js文件一般不会重复导入,没有人会这么干,除非前后放置位置不同,没有发现,删掉重复的js即可。

一般出现js文件重复导入都是在html或jsp文件有嵌套的情况,如下所示:

index.jsp文件 : 已经导入了bootstrap相关js文件

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8"/>
    <title>Hello, RangDanDanFei</title>
</head>
<body>
<%@ include file="/jsp/head.jsp" %>
<h1>Hello, RangDanDanFei</h1>

<script src="${pageContext.request.contextPath}/js/jquery-3.1.0.min.js"></script>
<script src="${pageContext.request.contextPath}/js/bootstrap.min.js"></script>
<script src="${pageContext.request.contextPath}/js/bootstrap-table.min.js"></script>
<script src="${pageContext.request.contextPath}/js/bootstrap-table-zh-CN.min.js"></script>
</body>
</html>

head.jsp文件 : 重复导入了bootstrap相关js文件

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<div class="panel panel-default">
    <div class="panel-heading"></div>
    <div class="panel-body">
        <div class="row">
            <div class="col-sm-2"></div>
        </div>
    </div>
</div>

<script src="${pageContext.request.contextPath}/js/jquery-3.1.0.min.js"></script>
<script src="${pageContext.request.contextPath}/js/bootstrap.min.js"></script>
<script src="${pageContext.request.contextPath}/js/bootstrap-table.min.js"></script>
<script src="${pageContext.request.contextPath}/js/bootstrap-table-zh-CN.min.js"></script>

<3> 没有初始化bootstrapTable,直接refresh

Stack Overflow有该问题的描述以及解答,链接地址为:https://stackoverflow.com/questions/56160322/typeerror-bootstraptable-is-not-a-function

<4> bootstrap版本和bootstrap-table版本不匹配

尝试升级其中一个版本

3. input文本框禁止输入

有两种方式:

<1> 增加readonly属性:表示该输入域只能读,不能写,可复制,可选择,可接收焦点,后台会接收到传值。

<input type="text" name="inputname" readonly="readonly" />

注意:readonly属性只能与type="text"配合使用

<2> 增加disabled属性:不可编辑,不可选择,不能接收焦点,后台不会接收到传值,页面显示置灰。

<input type="text" name="inputname" disabled="disabled" /> 

4. input文本框自动清除用户输入记录

增加autocomplete="off"属性,即可在每次重新请求页面时,自动清空用户输入记录。

<input type="text" autocomplete="off" />

相对应:
autocomplete="on"或者默认没有autocomplete属性,每次不会自动清空用户输入记录。

5. input文本框输入值的监听

总结:

<1> 文本框输入完成,失去焦点,触发change事件监听:

$('#id').on('change', function() {...})
或 $('#id').change(function() {...})
或 $('#id').bind('change', function() {...});

<2> 文本框输入值实时变化,触发input事件或者propertyChange事件监听:

$('#id').on('input propertychange', function() {...})
或
$('#id').bind('input propertychange', function() {...});

<1> 失去焦点的监听:即在文本框输入完成后,将焦点切出,触发change事件

触发change事件,需要满足以下两个条件:

1. 当前对象属性改变,并且是由键盘或鼠标事件触发的(脚本触发的无效)
2. 当前对象失去焦点

三种实现方式如下:

1. $('#id').on('change', function() {...});
2. $('#id').change(function() {...});
3. $('#id').bind('change', function() {...});

扩展:

change事件还可以用于以下事件:

1. select选择框:选中项发生变化

2. checkbox复选框:选中状态发生变化
    <input type="checkbox" id="checkboxId" />

3. radio单选按钮:选中状态发生变化
    <div>
        <input type="radio" name="colors" value="red"/>红色<br>
        <input type="radio" name="colors" value="blue"/>蓝色<br>
        <input type="radio" name="colors" value="green"/>绿色<br> 
    </div>

示例代码如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>input文本框输入失去焦点的监听</title>
</head>
<body>
    <input type="text" id="textId" placeholder="请输入字符!" /><i id="textTip"></i>
    <br>

    <select id="selectId">
        <option value="bejing">北京</option>
        <option value="shanghai">上海</option>
        <option value="shenzhen">深圳</option>
    </select>
    <i id="selectTip"></i>
    <br>

    <input type="checkbox" id="checkboxId" /><i id="checkboxTip"></i>
    <br>

    <div id="radioId">
        请选择你喜欢的颜色!<br>
        <input type="radio" name="colors" value="red"/>红色<br>   
        <input type="radio" name="colors" value="blue"/>蓝色<br>
        <input type="radio" name="colors" value="green"/>绿色<br> 
    </div>
    <i id="radioTip"></i>
    
    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
    <script>
        $(document).ready(function() {
            $('#textId').on('change', function(){
                $('#textTip').html("共输入了 " + $(this).val().length + " 个字符!");
            });

            $('#selectId').on('change', function() {
                $('#selectTip').html("您选择的城市是" + $(this).find("option:selected").text());
            });

            $('#checkboxId').on('change', function() {
                if (document.getElementById("checkboxId").checked == true) {
                    $('#checkboxTip').html("您已经选中");
                } else {
                    $('#checkboxTip').html("您已经取消选择");
                }
            });

            $('#radioId').on('change', function() {
                var radios = document.getElementsByName('colors');
                for (var i = 0, len = radios.length; i < len; i++) {
                    if (radios[i].checked) {
                        $('#radioTip').html("您喜欢的颜色是" + radios[i].nextSibling.data);
                        break;
                    }
                }
            });
        });
    </script>
</body>
</html>
失去焦点监听示例代码执行展示

<2> 实时监听:实时监听文本框中值的变化,触发input事件或者propertyChange事件

input事件:是HTML5的标准事件,一般浏览器都支持。当input的value发生变化时,无论是键盘输入、鼠标粘贴或脚本修改都能触发。IE9以下版本不支持input事件。

propertychange事件(IE专属):只要当前对象属性发生改变,都会触发,不仅仅会监听到input的value属性,还包括其他的属性标签,比如:span元素的style属性改变。同时在事件发生时还可以用 event.propertyName 访问到改变的属性名。

(由于IE9以下不支持input事件,所以要用到IE的专属propertychange事件)

实现方式:

1. $('#id').on('input propertychange', function() {...});
2. $('#id').bind('input propertychange', function() {...});

示例代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>input文本框输入实时监听</title>
</head>
<body>
    <input type="text" id="textId" placeholder="请输入字符!" /><i id="textTip"></i>

    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
    <script>
        $(document).ready(function() {
            $('#textId').on('input propertychange', function() {
                $('#textTip').html("您已经输入了 " + $(this).val().length + " 个字符!");
            });
        });
    </script>
</body>
</html>
实时监听示例代码执行展示

6. 获取表格指定的行,列

先看一下HTML构建简单表格的结构:


simple_table_structure

对简单表格操作总结:

  1. 获取表格行数
形式1: $('#tableId tr').length
形式2: $('#tableId').find('tr').length
  1. 获取表格列数
形式1: $('#tableId th').length
形式2: $('#tableId tr:eq(1) td').length
形式3: $('#tableId tr:eq(1)').find('td').length
注意:表头行标签形式为:
<thead>
  <tr>
      <th></th>
      <th></th>
  </tr>
</thead>
<tr>中嵌套的标签是<th>,不是<td>
所以上面形式2,形式3中选择器:eq(index)的index值不是0,即跳过表头
  1. 获取表格某一行的值
例如:获取表格第二行的值(表头算表的第一行)
形式1: $('#tableId tr:eq(1)').text();
形式2: $('#tableId tr').eq(1).text();
形式3: $('#tableId').find('tr').eq(1).text();
  1. 获取表格某一行某一列的值
例如:获取表格第二行第一列的值(表头算表的第一行)
形式1: $('#tableIndex tr:eq(1) td:eq(0)').text()
形式2: $('#tableIndex tr').eq(1).find('td:eq(0)').text())
形式3: $('#tableIndex').find('tr').eq(1).find('td').eq(0).text())

说明:

1. jQuery选择器:
<1> $('#tableId tr') 表示:匹配id为"tableId"的表格下的<tr>元素
<2> $(':eq(index)') 表示:选择器选取带有指定index值的元素,index值从0开始,所有第一个元素的index值是0
    如果index是负数,则从集合中的最后一个元素倒着往回计数
    例如:$('#tableId tr:eq(-1)') 表示:id为"tableId"的表格的倒数第一行

2. jQuery方法:
<1> .eq(index) 表示:匹配元素集合中索引为index的元素上,index值从0开始,表示第一个元素,
    如果index是负数,则从集合中的最后一个元素倒着往回计数

实例:

代码:

<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <title>Hello, Simple Table!</title>
  </head>
  <body>
    <table id="usertable" border="1">
      <thead>
        <tr>
          <th>ID</th>
          <th>姓名</th>
          <th>职业</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>让蛋蛋飞</td>
          <td>尼古拉斯蛋蛋</td>
          <td>程序员</td>
        </tr>
        <tr>
          <td>夏至未至</td>
          <td>李木子</td>
          <td>医生</td>
        </tr>
      </tbody>
    </table>
    <br>
    <div id="rowSize"></div>
    <div id="colSize"></div>
    <div id="tipth"></div>
    <div id="tiptr"></div>
    <div id="tiptd"></div>
    <div id="tiptrtd"></div>

    <script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
    <script>
      $(document).ready(function() {
        $('#rowSize').html("此表共" + $('#usertable tr').length + "行");
        $('#colSize').html("此表共" + $('#usertable th').length + "列");
        $('#tipth').html("此表表头的值为:" + $('#usertable th').text());
        $('#tiptr').html("此表第二行(表头为第一行)的值为:" + $('#usertable tr:eq(1)').text());
        $('#tiptd').html("此表第一列的值为:" + $('#usertable td:nth-child(1)').text());
        $('#tiptrtd').html("此表第三行第二列的值为:" + $('#usertable tr:eq(2) td:eq(1)').text());
      });
    </script>
  </body>
</html>
simple_table
说明:
:nth-child(n)是CSS3选择器,匹配属于其父元素的第 N 个子元素,不论元素的类型。不支持IE8及更早版本。

实例解析:
$('#usertable td:nth-child(1)'):在usertable表中td的父元素为tr,则td是子,tr是父,
表示匹配tr中第一个子元素td,表中有两行<tr>包含<td>,因此最终会匹配到usertable表中第一列的值(不含表头)。

延伸:
:nth-child(n)中 n 可以为公式,(an + b)表示:周期的长度,n是计数器(从0开始),b是偏移量。
示例:指定了下标是3的倍数的所有p元素的背景色
p:nth-child(3n+0) {
    backgroup:#ff0000;
}

7. 获取表格中控件的值

有两种方式:以#6中的表格为例(表头为第一行)

方式一:

例如:获取usertable表第二行中id="userid"或name="userid"的文本框(input text)的值
$('#usertable tr:eq(1)').find('#userid').val();
或者 
$('#usertable tr:eq(1)').find('input[name="userid"]').val();

方式二:

例如:只知某表的某行中文本框组件id为"userid",表的相关信息不知,想要获取该行中文本框name="userjob"的值
$('#userid').closest('tr').find('input[name="userjob"]').val();
某表某行input id="userid"
说明:
jQuery的closest()方法:
.closest(selector) : 从当前元素开始,沿DOM树向上遍历,直到找到一个匹配selector的元素为止,然后返回一个包含该找到元素的jQuery对象。
(未找到的话,则返回0个)

实例解析:
$('#userid').closest('tr').find('input[name="userjob"]').val(): 选择器先匹配找到id="userid"的元素,
然后从该元素开始,沿DOM树向上找<tr>元素,匹配到一个后返回,即定位到了该行,
然后用find找出该行name="userjob"的文本框,取值。

延伸:
.closest(selector, DOMContext) : 表示从当前元素开始,在指定的DOM元素范围中遍历搜索。
示例:
DOM树结构如下:
<ul>
  <li id="i1">I1</li>
  <li id="i2">I2
    <ul>
      <li class="item-a">Item A</li>
      <li class="item-b">Item B</li>
      <li class="item-c">Item C</li>
    </ul>
  </li>
  <li id="i3">I3</li>
</ul>  

$('li.item-a').closest('ul', document.getElementById('i2')): 表示从Item A元素开始,指定遍历搜索的DOM范围是id="i2"的列表元素集合。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,142评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,298评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,068评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,081评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,099评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,071评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,990评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,832评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,274评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,488评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,649评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,378评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,979评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,625评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,643评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,545评论 2 352

推荐阅读更多精彩内容