【blog项目】layui与jquery冲突导致鼠标悬停事件失效、如何调用layui.use()作用域里的方法

blog项目前台展示------查询数据库中的文章类型并展示时出现的bug

1 正常演示

2 用jquery查询数据库并添加到页面后

3 相关代码

html 复制代码
<script src="/static/jquery-2.1.4.js"></script>
<script src="/static/layui/layui.js"></script>
<script src="/static/js/yss/gloable.js"></script>
<script src="/static/js/plugins/nprogress.js"></script>
<script>NProgress.start();</script>
<script src="/static/js/yss/article.js"></script>
js 复制代码
$.post(
	'/blog?method=selectBlogType',
	function (result) {
		if (result.code === 0) {
			console.log(result.data);
			var i = 2;
			$(result.data).each(function (){
				console.log(this.name);
				var html = '';
				/*<li data-index="3"><a href="/Blog/Article/2/" onClick="selectByType('1')">HTML5&amp;CSS3</a></li>*/
				html += '<li data-index="'+ i +'"><a href="javascript:void(0)" οnclick="selectByType('+ this.id +', null)">' + this.name +'</a></li>';
				$('#category').append(html);
				i++;
			});
		}
	},
	'json'
)

其余部分:

javascript 复制代码
layui.use(['form'], function(){
			var form = layui.form;

			// 搜索提交
			form.on('submit(submitSearch)', function(data){
				var field = data.field; // 获得表单字段JSON格式
				//console.log(field);//title
				selectByType(null, field.title);
				return false; // 阻止默认 form 跳转
			});
		});

		function selectByType(typeId, title) {
			$.post(//抽取成方法 直接放到function里边就行
				'/blog?method=selectByType',
				{'typeId': typeId,'title': title},
				function (result) {
					if(result.code === 0) {
						$('#LAY_bloglist').empty();
						$(result.data).each(function (){
							//js切割日期并展示
							var html = '';
							html += '<section class="article-item zoomIn article">';
							html += '	<div class="fc-flag">置顶</div>';
							html += '	<h5 class="title">';
							html += '		<span class="fc-blue">【原创】</span>';
							html += '		<a href="read.html">'+this.title+'</a>';
							html += '	</h5>';
							html += '	<div class="time">';
							html += '		<span class="day">21</span>';
							html += '		<span class="month fs-18">1<span class="fs-14">月</span></span>';
							html += '		<span class="year fs-18 ml10">'+ this.createTime +'</span>';
							html += '	</div>';
							html += '	<div class="content" style="height: 180px; overflow:hidden">';
							html += '		<a href="read.html" class="cover img-light">';
							html += '			<img src="/pic/'+ this.image +'">';
							html += '		</a>';
							html += '		'+ this.content +'';
							html += '	</div>';
							html += '	<div class="read-more">';
							html += '		<a href="read.html" class="fc-black f-fwb">继续阅读</a>';
							html += '	</div>';
							html += '	<aside class="f-oh footer">';
							html += '		<div class="f-fl tags">';
							html += '			<span class="fa fa-tags fs-16"></span>';
							html += '			<a class="tag">ASP.NET MVC</a>';
							html += '		</div>';
							html += '		<div class="f-fr">';
							html += '		<span class="read">';
							html += '			<i class="fa fa-eye fs-16"></i>';
							html += '			<i class="num">57</i>';
							html += '		</span>';
							html += '			<span class="ml20">';
							html += '			<i class="fa fa-comments fs-16"></i>';
							html += '			<a href="javascript:void(0)" class="num fc-grey">1</a>';
							html += '		</span>';
							html += '		</div>';
							html += '	</aside>';
							html += '</section>';

							$('#LAY_bloglist').append(html);
						})
					}
				},
				'json'
			);
		}

4 原因分析

4.1 用jquery添加的新节点没有绑定相应的事件监听器

这是我用火狐浏览器才发现的(就是那个event),其他浏览器没有明显地显示事件监听器

4.2 因为layui本身就用到了jquery,所以再导入jquery并使用产生了一些冲突(具体是啥没分析出来,控制变量法得知是有问题的)

5 解决措施

针对4.1

让我想到了后台管理界面 的权限管理展示逻辑也是查询后再生成的,也是用的layui,但它却正常带有事件监听器,正常显示

回顾了下代码发现是将查询到的数据放到了session(域对象)中,然后用JSTL的foreach进行遍历生成的,而不是用jquery

servlet:

jsp(html):

所以我也修改了这个前台的类型展示逻辑:查询出博客类型后放到session中然后用JSTL来遍历(试了下request好像不行?)

servlet:

java 复制代码
private void selectBlogType(HttpServletRequest req, HttpServletResponse resp) {
    System.out.println("BlogController.selectBlogType");
    List<Type> types = blogService.selectBlogType();
    System.out.println(types);
    HttpSession session = req.getSession();
    session.setAttribute("types", types);
    //toJSON(resp, Result.ok("查询成功", types));
    toJSON(resp, Result.ok("查询成功",types));
}

jsp(html):

html 复制代码
<ul class="category mt20" id="category">
    <li data-index="0" class="slider"></li>
    <li data-index="1"><a href="javascript:void(0)" onclick="tools.selectByType(null)">全部文章</a></li>
	<c:forEach items="${types}" var="type" varStatus="st">
		<li data-index="${st.count+1}"><a href="javascript:void(0)" onclick="tools.selectByType(${type.id},null)">${type.name}</a></li>
	</c:forEach>
</ul>

这样改之后还是不行,主要原因就是4.2

针对4.2

不再单独引入jquery,直接在layui.use中调用jquery,使用layui自带的jquery。

这就需要把所有的jquery相关的操作全都放进layui.use,这就导致了另一个问题:
a标签的onclick绑定的方法也在layui.use里边,如何调用layui.use()作用域里的方法?
使用layui,动态生成的标签加onclick点击事件,终于找到一个能用的方法了,可以获取当前元素
如何调用layui.use()作用域里的方法

我采用了第二篇博客的方法,很管用!

jsp(js):

js 复制代码
layui.use(['form', 'jquery'], function(){
	var form = layui.form;
	var $ = layui.$ //重点处

	var _tools = {
		selectByType: function (typeId, title) {
			$.post(//抽取成方法 直接放到function里边就行
					'/blog?method=selectByType',
					{'typeId': typeId,'title': title},
					function (result) {
						if(result.code === 0) {
							$('#LAY_bloglist').empty();
							$(result.data).each(function (){
								//js切割日期并展示
								var html = '';
								html += '<section class="article-item zoomIn article">';
								html += '	<div class="fc-flag">置顶</div>';
								html += '	<h5 class="title">';
								html += '		<span class="fc-blue">【原创】</span>';
								html += '		<a href="read.html">'+this.title+'</a>';
								html += '	</h5>';
								html += '	<div class="time">';
								html += '		<span class="day">21</span>';
								html += '		<span class="month fs-18">1<span class="fs-14">月</span></span>';
								html += '		<span class="year fs-18 ml10">'+ this.createTime +'</span>';
								html += '	</div>';
								html += '	<div class="content" style="height: 180px; overflow:hidden">';
								html += '		<a href="read.html" class="cover img-light">';
								html += '			<img src="/pic/'+ this.image +'">';
								html += '		</a>';
								html += '		'+ this.content +'';
								html += '	</div>';
								html += '	<div class="read-more">';
								html += '		<a href="read.html" class="fc-black f-fwb">继续阅读</a>';
								html += '	</div>';
								html += '	<aside class="f-oh footer">';
								html += '		<div class="f-fl tags">';
								html += '			<span class="fa fa-tags fs-16"></span>';
								html += '			<a class="tag">ASP.NET MVC</a>';
								html += '		</div>';
								html += '		<div class="f-fr">';
								html += '		<span class="read">';
								html += '			<i class="fa fa-eye fs-16"></i>';
								html += '			<i class="num">57</i>';
								html += '		</span>';
								html += '			<span class="ml20">';
								html += '			<i class="fa fa-comments fs-16"></i>';
								html += '			<a href="javascript:void(0)" class="num fc-grey">1</a>';
								html += '		</span>';
								html += '		</div>';
								html += '	</aside>';
								html += '</section>';

								$('#LAY_bloglist').append(html);
							})
						}
					},
					'json'
			);
		},
	}
	window.tools = _tools;

	_tools.selectByType(null, null);
	/*$.post(
			'/blog?method=selectBlogType',
			function (result) {
				/!*if (result.code === 0) {
					console.log(result.data);
					var i = 2;
					$(result.data).each(function (){
						console.log(this.name);
						var html = '';
						/!*<li data-index="3"><a href="/Blog/Article/2/" onClick="selectByType('1')">HTML5&amp;CSS3</a></li>*!/
						html += '<li data-index="'+ i +'"><a href="javascript:void(0)" οnclick="tools.selectByType('+ this.id +', null)">' + this.name +'</a></li>';
						$('#category').append(html);
						i++;
					});
				}*!/
			},
			'json'
	)*/

	// 搜索提交
	form.on('submit(submitSearch)', function(data){
		var field = data.field; // 获得表单字段JSON格式
		//console.log(field);//title
		_tools.selectByType(null, field.title);
		return false; // 阻止默认 form 跳转
	});
});

jsp(html):

html 复制代码
<ul class="category mt20" id="category">
    <li data-index="0" class="slider"></li>
    <li data-index="1"><a href="javascript:void(0)" onclick="tools.selectByType(null)">全部文章</a></li>
	<c:forEach items="${types}" var="type" varStatus="st">
		<li data-index="${st.count+1}"><a href="javascript:void(0)" onclick="tools.selectByType(${type.id},null)">${type.name}</a></li>
	</c:forEach>
</ul>

查询文章类型并放到session的操作我放到了上一个页面,如果放在这个页面的话,第一次加载时JSTL没法取到session中的内容,需要刷新一次才能显示出来,感觉不太好。

为了保持一致性,还是使用了layui里边的jquery,并且加了个查询反馈弹窗(拖会儿时间,保证跳转到页面时session中已经有内容了)

index.jsp:

js代码:

js 复制代码
layui.use(['layer', 'jquery'],function (){
    var layer = layui.layer;
    var $ = layui.$ //重点处
    $('#selectBlogType').on('click', function (){
        $.post(
            '/blog?method=selectBlogType',
            function (result) {
                if (result.code === 0) {
                    layer.msg(
                        result.msg,
                        {icon: 1, time: 1000},
                        function() {// msg消失之后触发的函数
                            location.href = '/page/list';
                        }
                    );
                }
            },
            'json'
        )
    })
})

html代码:

html 复制代码
<li><a href="javascript:void(0)" id="selectBlogType">博客列表</a></li>

6 结果展示

7 其他参考

jsp中使用c:forEach标签自动添加序号

基础知识回顾:
layui发送ajax请求post
Layui中jquery的使用方式

拓展------jquery事件委托:
jQuery-给ul添加了li之后,添加的li并没有绑定点击监听怎么办?
jQuery学习:事件委托--新添加的元素没有监听
JS事件监听与事件委托(前端小白必学)

相关推荐
AlienZHOU43 分钟前
AI Coding 时代下,我的技术面试实践分享
前端·后端·面试
刺客码3 小时前
Layui 表格固定列行高错位问题解决方案
前端框架·layui·jquery·web
Captaincc4 小时前
AI用量v0.1.11更新发布 新增 jusage doctor 诊断指令 托盘展示token 和余额 新增 AutoClaw 支持
前端·后端·vibecoding
计算机魔术师5 小时前
德国Wiki被黑后两周,OpenAI终于把模型失控的账本摊开了
前端
kyriewen6 小时前
我让 AI 当面试官面了我一轮:第 3 个追问我就卡住了(附 10 道追问清单)
前端·面试·ai编程
IT_陈寒6 小时前
Python的GIL把我坑惨了,多线程跑得比单线程还慢
前端·人工智能·后端
前端snow6 小时前
ai agent --- 多agent框架之图编排引擎-langgraph
前端
竹林8187 小时前
OmniPic Studio v3.2.1 核心技术架构与全平台发版解析文档
前端·浏览器
JamesZhang800787 小时前
页面内存只涨不跌? 一次泄漏排查, 牵出 WeakMap 的诞生
前端
Z小明7 小时前
第 6 章 组件进阶
前端·vue.js