GVKun编程网logo

Nodejs/Jquery/Bootstrap搭建简单的web服务(node.js bootstrap)

10

对于想了解Nodejs/Jquery/Bootstrap搭建简单的web服务的读者,本文将是一篇不可错过的文章,我们将详细介绍node.jsbootstrap,并且为您提供关于Angularjsboo

对于想了解Nodejs/Jquery/Bootstrap搭建简单的web服务的读者,本文将是一篇不可错过的文章,我们将详细介绍node.js bootstrap,并且为您提供关于Angularjs bootstrap jquery jquery easyUI extjs 详解、bootstrap + bootstrap-table + jquery + bootstrap-paginator、Bootstrap 基于Bootstrap和JQuery实现动态打开和关闭tab页、Bootstrap's JavaScript requires jQuery at bootstrap.min.js:6的有价值信息。

本文目录一览:

Nodejs/Jquery/Bootstrap搭建简单的web服务(node.js bootstrap)

Nodejs/Jquery/Bootstrap搭建简单的web服务(node.js bootstrap)

Nodejs/Jquery/Bootstrap搭建简单的web服务

Jquery  前端  Bootstrap  Nodejs 

Contents

    • 整体思路
    • 跨域访问问题
    • Jquery.post()回调函数不执行问题
    • 总结

最近想给毕设加入一个前端界面来调用后台的一些功能,这样展示性更好。我使用BootStrap,Jquery写了一个很简陋的前端界面。服务器端使用Node.js express框架开了接口。之前以为是挺简单的一个东西,因为这些代码网上应该有很多可以参考。然而这个过程中,踩了不少的坑,花了3天时间,才把基本流程调通...记录一下我踩过的坑。

整体思路

  • 我的需求是:
    调用后台的Nodejs接口,进行增删查改操作,并向前端返回操作结果。由于我对于前后端的了解非常的肤浅,所以就选择了自己听说过的几个框架来写:

    • 后端用Nodejs Express开接口
    • 前端用Bootstrap,Jquery实现基本逻辑
  • 代码实现:
    那么根据我的需求,参考了一系列教程/博客,我抄来写的代码如下

  1. Nodejs端
var express = require(''express'');
var path = require(''path'')
var bodyParser = require(''body-parser'');

var app = express();
app.use(bodyParser.urlencoded({extended : false}));//这是一个中间件,用于解析请求内容

var SaveData = require("./SaveData.js");
var OffChainDB = require("./OffChainDB.js");

app.use(express.static(path.join(__dirname, ''../privacy_frontend'')));//设置静态文件中间件,在../privacy_frontend下包含我的前端html文件

app.post(''/savedata'',function(request,response){
    console.log(request.body);//打印request的json内容
    
    var result = SaveData.SaveData();//调用接口,作用是向数据库插入数据,返回一个Promise对象,并携带着数据库返回的消息
    
    result.then(r => {
        console.log(''success'', r)
        str = JSON.stringify(r)
        response.json(str)
    }).catch(e => {
        console.log(''error'', e)
    })
})

var server = app.listen(3000,function(){//监听3000端口,这样浏览器直接访问IP:3000就可以访问到上面开的接口了
    var host = server.address().address;
    var port = server.address().port;

    console.log("app listening at port 3000");
})

process.on(''unhandledRejection'',function(err){//绑定对于unhandleRejection的回调函数,报错
    console.error(err.stack);
});

process.on(''uncaughtException'',console.error);//跟上一句类似
  1. 前端
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>保存数据</title>
    <link href="bootstrap.min.css" rel="stylesheet">
    <script src="jquery-3.4.0.min.js"></script>
    <script src="bootstrap.min.js"></script>
</head>
<body>
    <form>
        <div>
            <label for="inputChaincode">链码</label>
            <div>
                <input type="text"id="inputChaincode" placeholder="链码">
            </div>
        </div>
        <div>
            <label for="inputMethod">链码方法</label>
            <div>
                <input type="text"id="inputMethod" placeholder="链码方法">
            </div>
        </div>
        <div>
            <label for="inputDataType">数据类型</label>
            <div>
                <input type="text"id="inputDataType" placeholder="插入数据类型">
            </div>
        </div>
        <div>
            <label for="inputData">数据</label>
            <div>
                <input type="text"id="inputData" placeholder="数据">
            </div>
        </div>
        <div>
            <div>
                <!-- <button type="submit"id="btn_submit">保存数据</button> -->
                <a type="submit"id="btn_submit">保存数据</a>
                <script>
                    var json = {};//对象类型的变量
                    $("#btn_submit").click(function () {
                        json[''chaincode''] = $("#inputChaincode").val();//从表单的每一个输入框获取信息,拼接成一个json对象
                        json[''method''] = $("#inputMethod").val();
                        json[''datatype''] = $("#inputDataType").val();
                        json[''data''] = $("#inputData").val();
                        alert(JSON.stringify(json));

                        $.post("http://192.168.253.130:3000/savedata",//向服务器发送post请求
                        json,//要发送的数据(request body)
                        function (data,status) {//成功收到消息的回调函数
                            alert("数据:\n"+data+"\n状态: "+status);//一系列弹窗提示
                            console.log(data);
                            console.log(status);
                            alert("callback is invoked!");
                            alert(data);
                        })
                    });
                </script>
            </div>
        </div>
    </form>
</body>
</html>
  • 界面部分使用了bootstrap自带的表单样式,代码基本来源于官网文档。然而这就是坑的开始。
  • js脚本部分,也很简单。就是为提交按钮增加一个点击事件回调函数。回调函数内容就是向Nodejs后台发起post请求,等待回应。

跨域访问问题

  • 之前听说过跨域访问这个名词,然而不知道具体是什么意思。这一次算是有了切身经验,理解了这个概念的含义。

  • 我的nodejs后端运行在我的虚拟机linux上,而前端最开始放在我的本地windows里(为了方便调试)。然后发现发出的post请求怎么也收不到。

  • 最后发现因为这是跨域请求。跨域请求的概念是:

    • 请求者和被请求者的 协议,ip,端口 中的任意一个不相同,就是跨域访问,js默认是不允许跨域访问的(出于安全考虑)。
    • 这一点在Jquery文档里也有写

    文档内容
    文档内容

  • 解决方法

    • 将前端界面也放到linux虚拟机上,跟后端使用同一IP:端口,就解决了跨域访问的问题
    • 这告诉我们,使用轮子之前一定要好好看文档啊。

Jquery.post()回调函数不执行问题

  • 以上的第一个问题其实很快就发现了,然而第二个问题才是大坑。找了很久才发现问题所在。
  • 在上面的<script>脚本里边,调用了$.post()函数,看起来挺简单的,参考了一下菜鸟教程,然后就写好了。
    • 运行的现象
    • 后端能收到请求,也能发送响应。但是前端收到数据的回调函数怎么也不执行,浏览器F12调试也根本看不到发出的post请求。
    • 用postman进行请求,没有任何问题。
  • 然后就开始了漫长的找bug过程,由于没有任何报错信息,只能盲目的通过注释代码,修改代码来尝试。
    • 开始认为是后端的问题,因为尝试发现:如果不调用SaveData.SaveData()这个函数,而是直接给一个resolved的Promise,就没有问题。于是我各种修改SaveData()函数,将它由Promise写法改成了普通回调的写法。结果好像并没有什么用。
    • 然后怀疑是response.send()参数数据类型的问题。尝试发现:如果这个数据比较短,前端就能执行回调,否则就不行。是否能执行回调貌似变成了一个概率事件...要看运气的...这时候我已经绝望了,这是什么玄学问题,还从没遇到那么诡异的bug。
    • 绝望之后,再怀疑前端,把$post改成链式调用的方式,写了$.post().done().fail()函数来代替作为参数的回调函数。居然就成功了。稳定的能够执行回调函数。但是依然不知道为什么。
    • 直到看到StackOverflow上面的一个回答,问题与我类似;他说是因为他的前端会自动刷新,所以刷新过后,上一次执行script代码时创建的jqXHR对象就没有了,自然浏览器也看不到这个请求的消息,也不会执行回调函数。
    • 仔细观察我的前端运行,貌似的确每次点击提交按钮就会刷新一下页面,但是我并没有写这个逻辑啊...问题出在哪呢?只有可能是bootstrap,搜了一下发现点击按钮就刷新页面这个逻辑是bootstrap自带的,自带的....发现bootstrap才是罪魁祸首,欲哭无泪啊...从始至终就没有注意到这一点。
    • 解决方法:
      • 参考了这一篇博文
      • 修改了<button>标签为<a>标签,问题解决。跟nodejs后端,跟jquery.post()没有任何关系emmmmm....
      • 以上经验告诉我们:用轮子的时候看文档也不一定管用啊...bootstrap文档里没有告诉我点击button会自动刷新的啊...

总结

  • 回顾整个过程,还是能学到一些经验
    • VSCode用作Nodejs的调试工具非常好用,能用调试器就不要用打印日志这种办法了,效率极低。
    • 当你对一些语法类的东西不确定的时候,一个简单的方法是:跳出复杂的场景,自己重新写一个test.js来测试各种情况。比如我对promise的状态改变,执行流程搞不清楚,那么就写一个test的代码来各种尝试,这样很快就能弄清楚一些模糊的地方。
    • Postman如果测试没问题,那么后端的接口就一定是没问题的。我并没有意识到这一点,将注意力放在了后端上。其实是南辕北辙了。一开始就定位问题在前端,可能就没有那么费劲了。
    • 用轮子之前,尽量还是把一些注意事项,文档通读一遍,直接上来就怼代码可能事倍功半。

Angularjs bootstrap jquery jquery easyUI extjs 详解

Angularjs bootstrap jquery jquery easyUI extjs 详解

AngularJS不能做什么?对比Angular/JSjQueryUI/Extjs


1.angularjs

html和js之间的数据衔接层,可以操控html元素(数据绑定、重复、隐藏)等,上手很容易,但想要精通,了解内部运行机制不容易。

2.bootstrap

用于页面布局样式设计,CSS等,与数据无关,是一种UI设计工具,一般搭配angularjs使用。

3.jquery

是一个JavaScript函数库,与angularjs作用一直,但更偏重于操作dom元素,对dom遍历和修改。

4.easyUI

是基于jQuery的框架,它侧重于页面显示部分,即UI,但是所有效果都是用jQuery实现的。



框架就好比兵器,你得明白你手里拿的是屠龙刀还是倚天剑,刀法主要是砍,剑法主要是刺。对于那些职业喷子和脑残粉,小僧送你们两个字:呵呵;同时祝你幸福,请点右上角。

首先要明白Angular不能做什么,或者Angular没有提供什么,然后再来看它能做什么,来看Angular与其它一些主流框架的对比。



对于上面的表格,有人可能要跟我抬杠,咱大jQuery不是有各种插件吗!不是有各种EasyUI、LigerUI等等一大堆UI吗!

我只想说,你特么到底有没有做过大型的开发?各种东西倒腾在一起的组装货能比得上品牌机?另外遇到jQuery版本不兼容就够你喝一壶了吧!说jQueryUI各种乱已经是对它客气了,实际上是一塌糊涂!

提醒某些小白区分好概念,小僧的喷点是jQueryUI,而不是jQuery,jQuery这把小巧玲珑的瑞士军刀小僧还是非常喜欢滴!另外,也有 一批基于jQuery的UI套件做得非常优秀,比如KendoUI,但是一分钱一分货,好东西基本上都是收费的。这么多年下来了,你应该早就习惯了这条行 规。再说一次,好!东!西!都!是!收!费!的!

又有人说,怎么没把bootstrap列在里面对比一下?请问油漆桶和Tank战车怎么比?你比给我看看。

关于前端UI体系的特别说明

对于前端UI系统,特别说明一下。一般来说,前端UI必须包含以下控件和工具(参照了我最熟悉的Extjs):

  • Form

    TextField

    NumberField

    PassWord

    ComboBox

    CheckBox

    Radio

    DatePicker/TimePicker(日期和时间控件一般没有人会自己去写,太复杂了!

    表单验证:本地验证和远程验证

  • DataGrid

    复杂表头、数据格式、行内各种格式、动态编辑、分页、动态列、滚动(等等)

    完善的数据表格也是一个非常复杂的控件,完全自己开发不容易!

  • Tree

  • Window

    模态/非模态

  • Panel

  • TabPanel

    tab懒加载(内存释放和浏览器兼容性比较繁琐,做完善不容易!

  • HTMLEditor

    应该没有哪个疯子想自己去做一个类似KindEditor那样在线编辑器吧!什么?你想做?药不能停!

  • 小组件

    ToolTip

    Slider

    Pager

    ProgressBar

    Menu

    Label

    Image

    Alert

  • 布局

    布局系统是比较复杂的,必须有深厚的CSS基础,否则搞出来的东西一定有兼容性问题!好吧,我知道有人肯定要说bootstrap了,既然都在说那么小僧就不说了,自己玩儿去!

  • 其它工具

    Ajax

    模板

    数据格式化

    其它各种控件就不说了,比如幻灯片效果、面包屑,再比如“×款超棒的jQuery××”等等。

Angular没有提供完善的UI,没有提供CSS样式套件,也没有对移动平台进行直接支持。所以,如果你使用Angular,你一定需要其它东西来配合。例如,如果需要UI,你需要使用jQueryUI,或者自己封装UI组件;如果需要CSS样式,你可以选择bootstrap或者LESS;如果需要支持移动平台,还是需要你自己 去开发。

好了,看到这里有人开始嘀咕了,这特么岂不是什么都没有嘛!!!

莫急,再来看Angular有什么。

Angular能做什么?

1、自动化的数据双向绑定;

2、MVC;

3、依赖注入---DI系统;

4、指令系统(可以自定义语义化标签)---Directive机制;

5、模块化---Module机制;

6、路由机制---Route机制;

7、服务---Service机制;

8、内嵌表达式---Expression机制;

9、前端代码单元测试和集成测试的自动化(借助于Yeoman等工具);

10、模板;

11、动态加载;

这么多机制里面,核心的核心是指令系统,实际上其它所有特性都是建立在指令系统之上的。本质上说,Angular写了一个JS版的编译器,一切都构 建在这款编译器之上。对于使用者来说,可以把解析器看成一个JS虚拟机,有兴趣的人可以自己阅读Angular的Parser(HTML解析器)源码。

HTML解析器机制是其它所有框架所不具备也不敢这样做的,它是Angular的灵魂。

结论

很显然,Angular并没有打算做一个高大全的所谓【框架】,它的核心价值在于,把一堆后台框架的概念带到了前端框架中,比如依 赖注入(来自Spring);同时又从其它地方抄了一些概念,比如数据自动双向绑定(貌似来自Flex)、模板、MVC、动态加载(来自 RequireJS等),等等。当然,这些理念都挺好。基于这些理念和工具,你可以把前端应用组织得非常良好。

但是,有一点请特别注意(尤其那些负责技术选型的所谓“架构尸”,请瞪大你的钛合金狗眼看好下面的内容):对于界面非常复杂的业务 型系统,必须要要有完备的UI支持(Form、DataGrid、Tree、Tab、Window等)。如果你的团队整体JS水平很烂,或者压根没打算自 己去做很多东西,请慎用AngularJS!尤其是那些只有两三条破枪,连美工都没有的小公司,您请靠边儿凉快,这儿没您什么事儿。


白及说:

有一些项目总结在里面,但是不是很全面,对于小白来说,可以听听简单理解一下!

bootstrap + bootstrap-table + jquery + bootstrap-paginator

bootstrap + bootstrap-table + jquery + bootstrap-paginator

 

http://127.0.0.1:8848/pangBo/index.html

 

 

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
		 crossorigin="anonymous">
		<script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script>
		<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
		 crossorigin="anonymous"></script>
		<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.12.1/bootstrap-table.min.css">
		<script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.12.1/bootstrap-table.min.js"></script>
		<script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.12.1/locale/bootstrap-table-zh-CN.min.js"></script>
		<script src="js/bootstrap-paginator.min.js" type="text/javascript" charset="utf-8"></script>
	</head>

	<body>
		<div>
			<formrole="search">
				<div>
					<div>
						<div>
							<label>客户编号: </label>
							<div>
								<input type="text"placeholder="">
							</div>
						</div>
						<div>
							<label>客户姓名: </label>
							<div>
								<input type="text"placeholder="">
							</div>
						</div>
						<div>
							<label>手机号码: </label>
							<div>
								<input type="text"placeholder="">
							</div>
						</div>
					</div>
					<div>
						<div>
							<label>客户编号: </label>
							<div>
								<input type="text"placeholder="">
							</div>
						</div>
						<div>
							<label>客户编号: </label>
							<div>
								<input type="text"placeholder="">
							</div>
						</div>
						<div>
							<label>客户编号: </label>
							<div>
								<input type="text"placeholder="">
							</div>
						</div>
					</div>
					<div>
						<button type="submit">查询</button>
					</div>
				</div>
			</form>
		</div>
		<div>
			<divrole="group" aria-label="...">
				<button type="button" id="btn-one">可撤单</button>
				<button type="button" id="btn-two">已撤单</button>
			</div>
		</div>
		<div id="table-one">
			<table id="table"></table>
			<div>
				<div id="example">
					<ul id="pageLimit"></ul>
				</div>
			</div>
		</div>
		<div id="table-two">
			<table id="table-ta-one"></table>
			<div>
				<div id="example-two">
					<ul id="pageLimit-two"></ul>
				</div>
			</div>
		</div>
		<divid="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
			<div>
				<div>
					<div>
						<button type="button"data-dismiss="modal" aria-hidden="true">&times;</button>
						<divid="myModalLabel">请输入登录密码:</div>
					</div>
					<div>
						<div>
							<input id="input-text" type="text" value=""placeholder="">
						</div>
						<button type="button" id="btn-ok">确定撤单</button>
					</div>
				</div>
			</div>
		</div>
	</body>
</html>
<script type="text/javascript">
	function operateFormatter(value, row, index) {
		return [
			''<button type="button"data-toggle="modal" data-target="#myModal">撤单</button>''
		].join('''');
	}
	window.operateEvents = {
		''click .RoleOfdelete'': function(e, value, row, index) {
			console.log(''kkk'');
		}
	};
	$(''#table'').bootstrapTable({
		url: '''', //请求后台的URL(*)
		method: ''GET'', //请求方式(*)
		// toolbar: ''#toolbar'', //工具按钮用哪个容器
		cache: false, //是否使用缓存,默认为true,所以一般情况下需要设置一下这个属性(*)
		pagination: false, //是否显示分页(*)
		// pageSize: 10, //每页的记录行数(*)
		// pageNumber: 1, //初始化加载第一页,默认第一页,并记录
		// sidePagination: "server", //分页方式:client客户端分页,server服务端分页(*)
		uniqueId: "id", //每一行的唯一标识,一般为主键列
		columns: [{
				field: ''id'',
				align: ''center'',
				title: ''交易合同号''
			},
			{
				field: ''ida'',
				align: ''center'',
				title: ''客户编号''
			},
			{
				field: ''idb'',
				align: ''center'',
				title: ''客户姓名''
			},
			{
				field: ''idc'',
				align: ''center'',
				title: ''手机号码''
			},
			{
				field: ''idd'',
				align: ''center'',
				title: ''证件号码''
			},
			{
				field: ''ide'',
				align: ''center'',
				title: ''产品代码''
			},
			{
				field: ''idf'',
				align: ''center'',
				title: ''产品名称''
			},
			{
				field: ''idg'',
				align: ''center'',
				title: ''购买金额''
			},
			{
				field: ''idh'',
				align: ''center'',
				title: ''交易时间''
			},
			{
				field: ''idi'',
				align: ''center'',
				title: ''撤单'',
				events: operateEvents,
				formatter: operateFormatter
			},
		],
		data: [{
				id: 1
			},
			{
				id: 1
			},
			{
				id: 1
			}
		],
		onLoadError: function() {
			showTips("数据加载失败!");
		},

	});
	$(''#table-ta-one'').bootstrapTable({
		url: '''', //请求后台的URL(*)
		method: ''GET'', //请求方式(*)
		// toolbar: ''#toolbar'', //工具按钮用哪个容器
		cache: false, //是否使用缓存,默认为true,所以一般情况下需要设置一下这个属性(*)
		pagination: false, //是否显示分页(*)
		// pageSize: 10, //每页的记录行数(*)
		// pageNumber: 1, //初始化加载第一页,默认第一页,并记录
		// sidePagination: "server", //分页方式:client客户端分页,server服务端分页(*)
		uniqueId: "id", //每一行的唯一标识,一般为主键列
		columns: [{
				field: ''id'',
				align: ''center'',
				title: ''交易合同号''
			},
			{
				field: ''ida'',
				align: ''center'',
				title: ''客户编号''
			},
			{
				field: ''idb'',
				align: ''center'',
				title: ''客户姓名''
			},
			{
				field: ''idc'',
				align: ''center'',
				title: ''手机号码''
			},
			{
				field: ''idd'',
				align: ''center'',
				title: ''证件号码''
			},
			{
				field: ''ide'',
				align: ''center'',
				title: ''产品代码''
			},
			{
				field: ''idf'',
				align: ''center'',
				title: ''产品名称''
			},
			{
				field: ''idg'',
				align: ''center'',
				title: ''购买金额''
			},
			{
				field: ''idh'',
				align: ''center'',
				title: ''交易时间''
			}
		],
		data: [{
				id: 1
			},
			{
				id: 1
			},
			{
				id: 1
			}
		],
		onLoadError: function() {
			showTips("数据加载失败!");
		},

	});
	$(''#btn-one'').click(function() {
		console.log(''kk'');
		$(''#table-one'').show();
		$(''#table-two'').hide();
		$(''#btn-one'').css({
			''background-color'': ''#e6e6e6''
		})
	})
	$(''#btn-two'').click(function() {
		console.log(''kkk'');
		$(''#table-two'').show();
		$(''#table-one'').hide();
		$(''#btn-one'').css({
			''background-color'': ''#FFF''
		})
	})
	$(''#pageLimit'').bootstrapPaginator({
		currentPage: 1, //当前的请求页面。
		totalPages: 100, //一共多少页。
		size: "normal", //应该是页眉的大小。
		bootstrapMajorVersion: 3, //bootstrap的版本要求。
		alignment: "right",
		numberOfPages: 5, //一页列出多少数据。
		itemTexts: function(type, page, current) { //如下的代码是将页眉显示的中文显示我们自定义的中文。
			switch (type) {
				case "first":
					return "首页";
				case "prev":
					return "上一页";
				case "next":
					return "下一页";
				case "last":
					return "末页";
				case "page":
					return page;
			}
		}
	});
	$(''#pageLimit-two'').bootstrapPaginator({
		currentPage: 1, //当前的请求页面。
		totalPages: 100, //一共多少页。
		size: "normal", //应该是页眉的大小。
		bootstrapMajorVersion: 3, //bootstrap的版本要求。
		alignment: "right",
		numberOfPages: 5, //一页列出多少数据。
		itemTexts: function(type, page, current) { //如下的代码是将页眉显示的中文显示我们自定义的中文。
			switch (type) {
				case "first":
					return "首页";
				case "prev":
					return "上一页";
				case "next":
					return "下一页";
				case "last":
					return "末页";
				case "page":
					return page;
			}
		}
	});
	$(''#btn-ok'').click(function() {
		var inputContent = $(''#input-text'').val();
		if (inputContent == '''') {
			alert(''密码不能为空 !'');
		}
		console.log(inputContent);
	})
</script>

 

Bootstrap 基于Bootstrap和JQuery实现动态打开和关闭tab页

Bootstrap 基于Bootstrap和JQuery实现动态打开和关闭tab页

基于BootstrapJQuery实现动态打开和关闭tab

 

by:授客 QQ1033553122

  1. 1.   测试环境

JQuery-3.2.1.min.j

 

Bootstrap-3.3.7-dist

 

win7

 

  1. 2.   实践

HTML代码片段

 
<div>
<div>
<!--添加左侧菜单栏 -->
<div>
<divid="accordion">
<div id="left-nav">
<divhttps://www.jb51.cc/tag/heading/" target="_blank">heading">
<h4><a data-toggle="collapse"data-parent="#accordion" href="#tag20"><i></i>&nbsp;&nbsp;项目管理<span></span></a></h4>
</div>
<div id="tag20">
<div>
<ul>
<li><a href="#" onclick="addTab({‘menuID‘:‘21‘,‘father‘:‘navtab‘,‘tabName‘:‘项目管理1‘,‘tabContentID‘:‘tabContent‘,‘tabUrl‘:‘/testulr‘})"><i></i>&nbsp;&nbsp;项目管理1</a></li>
<li><a href="#" onclick="addTab({‘menuID‘:‘22‘,‘tabName‘:‘项目管理2‘,‘tabUrl‘:‘‘})"><i></i>&nbsp;&nbsp;项目管理2</a></li>
</ul>
<!--添加tab页面 -->
<div>
<ulid="navtab">
<!--通过js获取 tab-->
<!-- tab页面的内容 -->
<div id="tabContent">
<!--通过js获取 tab对应的页面内容-->
</div>

</body>

</html>

JS代码片段

/**
 * 增加tab标签页
 * @param options
 * menuIDtab标签页对应的左侧导航菜单在数据库表中的id,作为tab元素id的组成部分
 * tabName       tab标签页名称
 * tabUrl        tab“装载url
 * tabContentID  tab标签页的页面内容所在的父级元素(div容器)
 *
 * @returns {boolean}
 */
function addTab(options) {
setBreadcrumb(options.level1,options.level2,options.tabName);
//tabUrl:当前tab所指向的URL地址
varisExists= isTabExists(options.menuID);
if(isExists){ // 如果tab标签页已打开,则选中、激活
$("#tab-a-" + options.menuID).click(); // 注意,必须是点击 a标签才起作用
} else {
// 新增 tab 标签页
        //按钮图标 ‘<i></i></a>‘
$("#" + tabFatherElementID).append(
‘<li role="presentation" id="tab-li-‘ + options.menuID + ‘">‘ +
‘    <a href="#tab-content-‘ +options.menuID + ‘" data-toggle="tab" role="tab" id="tab-a-‘ + options.menuID + ‘">‘+ options.tabName + ‘<buttontype="button" onclick="closeTab(this,‘ + "‘" + options.level1 + "‘,‘" + options.level2 + "‘,‘" + options.tabName + "‘" +‘);">×</button>‘ + ‘</a>‘ +
‘</li>‘);
// 设置 tab标签页的内容
var content = ‘<iframe name="tabIframe" src="‘ + options.tabUrl + ‘" width="100%" frameborder="no" border="0" marginwidth="0" marginheight="0" scrolling="yes" allowtransparency="yes" onload="changeFrameHeight()"></iframe>‘;
$("#" + options.tabContentID).append(‘<div id="tab-content-‘ + options.menuID + ‘" role="tabpanel">‘ + content + ‘</div>‘);

 

$("#tab-a-" + options.menuID).click(); // 选中打开的tab

currentIframID= ‘iframe‘ + options.menuID;

    }

}

/***
 * 判断tab页是否已经打开
 * @paramtabName当前tab的名称
 * @returns {boolean}
function isTabExists(menuID){
var tab = $(‘#tab-li-‘ + menuID + ‘ > #tab-a-‘ + menuID);
return tab.length>0;
}
 

/**

 * 关闭tab标签页

 * @param button

 */

function closeTab(button) {

//通过所点击的x 按钮,找到对应li标签的id

var li_id= $(button).parent().parent().attr(‘id‘);

var id = li_id.replace(‘tab-li-‘,‘‘);

var li_active= $("#"+ tabFatherElementID+ " >li.active");

if (li_active.attr(‘id‘) == li_id) { // 如果关闭的是当前处于选中状态的TAB

if (li_active.prev()[0]) { // 如果当前tab标签之前存在tab标签,则激活前一个标签页(前后顺序对应左右顺序

li_active.prev().find("a").click();

        } else if (li_active.next()[0]) { // 如果当前tab标签之前不存在tab标签,并且在其之后存在tab标签,则激活后一个tab标签页

li_active.next().find("a").click();

        }

//关闭TAB

$("#" + li_id).remove();

$("#tab-content-" + id).remove(); // 移除内容

* 设置tab标签对应的iframe页面高度

function changeFrameHeight(){
var iframes = document.getElementsByName(‘tabIframe‘);
var contentContainer= $(‘#‘ + tabContentID); // 获取tab标签对应的页面div容器对象 // 可能会出现获取不到的情况
var offsetTop= 0;
if(contentContainer.offset()) {
offsetTop= contentContainer.offset().top;  //容器距离document顶部的距离
$.each(iframes,function(index,iframe){
var h = window.innerHeight|| document.documentElement.clientHeight|| document.body.clientHeight;
iframe.height= h - offsetTop;// 这里offsetTop可以替换成一个比较合理的常量值
    });
* 浏览器窗口大小发生变化时,自动调整iframe页面高度
* 浏览器等因素导致改变浏览器窗口大小时,会发生多次resize事件,导致频繁调用changeFrameHeight()* 所以函数中添加了延迟事件
*/
$(function(){
var resizeTimer= null;
window.onresize=function(){
if(resizeTimer) {
clearTimeout(resizeTimer); // 取消上次的延迟事件
resizeTimer= setTimeout(‘changeFrameHeight()‘,500);  // //延迟500毫秒执行changeFrameHeight方法
});

Bootstrap's JavaScript requires jQuery at bootstrap.min.js:6

Bootstrap's JavaScript requires jQuery at bootstrap.min.js:6

在引入bootstrap前需要引入jQuery

蝶衣_疯魔 发布了137 篇原创文章 · 获赞 5 · 访问量 4294 私信 关注

总结

以上是小编为你收集整理的Bootstrap&#039;s JavaScript requires jQuery at bootstrap.min.js:6全部内容。

如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。

原文地址:https://blog.csdn.net/shujuku____/article/details/104104544

我们今天的关于Nodejs/Jquery/Bootstrap搭建简单的web服务node.js bootstrap的分享就到这里,谢谢您的阅读,如果想了解更多关于Angularjs bootstrap jquery jquery easyUI extjs 详解、bootstrap + bootstrap-table + jquery + bootstrap-paginator、Bootstrap 基于Bootstrap和JQuery实现动态打开和关闭tab页、Bootstrap's JavaScript requires jQuery at bootstrap.min.js:6的相关信息,可以在本站进行搜索。

本文标签: