当前位置: 首页 > 编程笔记 >

jQuery EasyUI基础教程之EasyUI常用组件(推荐)

拓拔富
2023-03-14
本文向大家介绍jQuery EasyUI基础教程之EasyUI常用组件(推荐),包括了jQuery EasyUI基础教程之EasyUI常用组件(推荐)的使用技巧和注意事项,需要的朋友参考一下

本文主要内容是介绍EasyUI的一些常用组件的使用,都是一些非常基础的知识,适合入门者学习,主要包括Base(基础)、Layout(布局)、菜单和按钮、表单、窗口、表格和树等的使用。要求完全掌握这些内容,学会查阅文档,了解开发基本思想。如果想进一步深入学习,可以直接去官网进行学习,查阅文档等http://www.jeasyui.com/。

一、简介

EasyUI是一种第三方组织开发的,开源的,功能强大的,基于jquery的插件库。 主要可以用于web的后台前端。jQuery EasyUI 提供易于使用的组件,它使 Web 开发人员能快速地在流行的 jQuery 核心和 HTML5 上建立程序页面。 这里介绍的都是一些基本组件,项目中需要将其装配起来,方可构建完整的web页面,EasyUI只是众多前端WEB组件之一。

作用:快速基于现成的组件创建自己的web页面。组件:指已经有第三方写好的,直接可以使用的功能界面,例如:form,layout,tree等。

二、开发步骤

1、先去官网下载相应的插件:
2、在myeclipse中新建一个web工程

3、在WebRoot目录下创建js和themes目录,导入官方文件

4、新建一个helloword.html的网页,并引入下列文件:

<link rel="stylesheet" href="themes/default/easyui.css" type="text/css" /> 
<link rel="stylesheet" href="themes/icon.css" type="text/css" /> 
<script type="text/javascript" src="js/jquery.min.js"></script> 
<script type="text/javascript" src="js/jquery.easyui.min.js"></script> 
<script type="text/javascript" src="js/easyui-lang-zh_CN.js"></script>

文件引入的顺序不要错,那么到目前为止,开发的准备工作就已经完成了。

三、Base组件的使用

3.1 Pagination(分页)

使用$.fn.pagination.defaults重写默认值对象

.分页组件是一个比较常用的组件之一,我们可以有两种使用方式,一种是直接在标签上面添加相应的属性,另一种是通过js进行操作。

静态方式创建如下:

<div 
id="pagination" 
class="easyui-pagination" 
data-options="total:2000,pageSize:10" 
style="background:#efefef;border:1px solid #ccc;" 
> 
</div>

动态方式:

<div id="pp" style="background:#efefef;border:1px solid #ccc;"></div> 
<script> 
$("#pp").pagination({ 
"total":100, //表示总记录数 
"pageSize":10, //每页显示多少条记录 
"pageNumber":2, //当前页号 
"pageList":[10,20], // 
"buttons":[ 
{ 
iconCls:'icon-add', 
handler:function(){alert('add')} 
},'-',{ 
iconCls:'icon-save', 
handler:function(){alert('save') 
} 
}], 
"layout":['list','sep','first','prev','manual','next','last','links'], 
"showPageList":false, 
}); 
$("#pp").pagination({ 
"onSelectPage":function(pageNumber,b){ 
alert(pageNumber); 
alert(b) 
} 
})

我这里是添加了一些事件和方法的,可以依据实际情况进行增加或删除或修改里面的小的部分组件。大大方便了我们的开发。


3.2 ProgressBar(进度条)

使用$.fn.progressbar.defaults重写默认值对象。

使用HTML标签或程序创建进度条组件。从标签创建更加简单,添加'easyui-progressbar'类ID到<div/>标签。

<div id="p" class="easyui-progressbar" data-options="value:60" style="width:400px;"></div>

使用Javascript创建进度条。

<div id="p" style="width:400px;" ></div><br /> 
<input id="startID" type="button" value="开始" style="width:100px;height:30px" /> 
<script> 
$("#p").progressbar({ 
width:1000, 
height:40, 
value:0 
}); 
//获取1-9之间的随机数 
function getNum(){ 
return Math.floor(Math.random()*9)+1; 
} 
/* for(var i=0;i<20;i++){ 
var num=getNum(); 
document.write(num+"<br />"); 
} */ 
var timeID=null; 
function update(){ 
//获取随机值 
var num=getNum(); 
//获取进度条当前值 
var value=$("#p").progressbar("getValue"); 
if(value+num>100){ 
//设置进度条当前值为100,且停止运行 
$("#p").progressbar("setValue",100); 
window.clearInterval(timeID); 
$("#startID").removeAttr("disabled"); 
}else{ 
$("#p").progressbar("setValue",(value+num)) 
} 
} 
$("#startID").click(function(){ 
timeID=window.setInterval("update()",500); 
//按钮失效 
$(this).attr("disabled","disabled"); 
}); 
</script>

四、Layout组件的使用

4.1 layout的使用

布局是最常用的组件了,官方提供的是拥有5个布局方向的:北、南、东、西、中.

基本的使用方式如下:

<div 
id="layoutID" 
class="easyui-layout" 
data-options="fit:true" 
style="width:800px;height:500px"> 
<!-- 上 --> 
<div data-options="region:'north',title:'上',split:true,iconCls:'icon-edit',minHeight:'100',maxHeight:'200'" style="height:100px;"></div> 
<!-- 下 --> 
<div data-options="region:'south',title:'South Title',split:true" style="height:100px;"></div> 
<!-- 右 --> 
<div data-options="region:'east',iconCls:'icon-reload',title:'East',split:true" style="width:100px;"></div> 
<!-- 左 --> 
<div data-options="region:'west',title:'West',split:true" style="width:200px;"></div> 
<!-- 中 --> 
<div data-options="region:'center',title:'center title' " style="padding:5px;background:#eee;"></div> 
</div>

我们可以为其添加js的属性:

<script> 
$(function(){ 
$('#layoutID').layout('collapse','north'); 
//休息3秒 
window.setTimeout(function(){ 
//将南边折叠 
$('#layoutID').layout("collapse","south"); 
//将北边展开 
$('#layoutID').layout('expand','north'); 
//将南边展开 
window.setTimeout(function(){ 
$("#layoutID").layout("expand","south"); 
},3000); 
},3000); 
}); 
</script>

对于布局来说,当然也还是可以进行嵌套处理的,我们可以摘除掉我们不需要的部分,然后将需要的部分进行再次组装。

<div id="layoutID" class="easyui-layout" data-options="fit:true" > 
<div data-options="region:'north',border:false" style="height:100px"></div> 
<div data-options="region:'center'"> 
<div class="easyui-layout" data-options="fit:true" > 
<div data-options="region:'west',border:false" style="width:180px"></div> 
<div data-options="region:'center'"> 
<div class="easyui-layout" data-options="fit:true"> 
<div data-options="region:'north'" style="height:100px"></div> 
<div data-options="region:'south'" ></div> 
</div> 
</div> 
</div> 
</div> 
</div>

效果如下:


4.2 面板的使用

第一种方式:通过标签直接创建。

<div 
id="panel" 
class="easyui-panel" 
title="我的第一个面板" 
data-options="iconCls:'icon-save',collapsible:'true',minimizable:true,maximizable:true" 
style="width:800px;height:300px;padding:15px" 
> 
easyui入门 
</div>

第二种方式:

<div id="p" style="padding:10px;"> 
<p>panel content.</p> 
<p>panel content.</p> 
</div> 
<script> 
$('#p').panel({ 
width:500, 
height:150, 
title: 'My Panel', 
tools: [{ 
iconCls:'icon-add', 
handler:function(){alert('new')} 
},{ 
iconCls:'icon-save', 
handler:function(){alert('save')} 
}] 
}); 
<div id="p" style="padding:10px;"> 
<p>panel content.</p> 
<p>panel content.</p> 
</div> 
$('#p').panel({ 
width:500, 
height:150, 
title: 'My Panel', 
tools: [{ 
iconCls:'icon-add', 
handler:function(){alert('new')} 
},{ 
iconCls:'icon-save', 
handler:function(){alert('save')} 
}] 
}); 
</script>

4.3 Accordion(分类)

使用$.fn.accordion.defaults重写默认值对象。

分类空间允许用户使用多面板,但在同一时间只会显示一个。每个面板都内建支持展开和折叠功能。点击一个面板的标题将会展开或折叠面板主体。面板内容可以通过指定的'href'属性使用ajax方式读取面板内容。用户可以定义一个被默认选中的面板,如果未指定,那么第一个面板就是默认的。

<div 
id="adID" 
class="easyui-accordion" 
data-options="fit:false,border:true,multiple:false,selected:-1" 
style="width:300px;height:200px;" 
> 
<div title="北京" data-options="iconCls:'icon-save'" 
style="overflow:auto;padding:10px;"> 
朝阳区 
</div> 
<div title="湖南" data-options="iconCls:'icon-reload'" 
style="padding:10px;">衡阳市 
</div> 
<div title="北京" data-options="iconCls:'icon-save'" 
style="overflow:auto;padding:10px;"> 
<p>朝阳区</p> 
</div> 
<div title="湖南" data-options="iconCls:'icon-reload'" 
style="padding:10px;"> 
<p>衡阳市</p> 
<p>长沙市</p> 
</div> 
</div> 
<script> 
$(function(){ 
//增加一个面版 
$("#adID").accordion("add",{ 
"title":"广东省", 
"iconCls":"icon-add", 
"content":"广州", 
"selected":false 
}); 
window.setTimeout(function(){ 
$("#adID").accordion("remove","北京"); 
$("#adID").accordion("unselect",0); 
},3000); 
}); 
</script>

4.4 Tabs(选项卡)

使用$.fn.tabs.defaults重写默认值对象。

选项卡显示一批面板。但在同一个时间只会显示一个面板。每个选项卡面板都有头标题和一些小的按钮工具菜单,包括关闭按钮和其他自定义按钮。

<div 
id="tt" 
class="easyui-tabs" 
data-options="plain:false,fit:false,border:true,tools:[ 
{ 
iconCls:'icon-add', 
handler:function(){ 
alert('添加') 
} 
}, 
{ 
iconCls:'icon-sava', 
handler:function(){ 
alert('保存') 
} 
} 
],toolPosition:'right',tabPosition:'top',selected:2" 
style="width:500px;height:250px;" 
> 
<div title="Tab1" style="padding:20px;display:none;">tab1</div> 
<div title="Tab2" data-options="closable:true" 
style="overflow:auto;padding:20px;display:none;">tab2</div> 
<div title="Tab3" data-options="iconCls:'icon-reload',closable:true" 
style="padding:20px;display:none;">tab3</div> 
</div>

五、Menu 和Button组件的使用

LinkButton(按钮)

使用$.fn.linkbutton.defaults重写默认值对象。

按钮组件使用超链接按钮创建。它使用一个普通的<a>标签进行展示。它可以同时显示一个图标和文本,或只有图标或文字。按钮的宽度可以动态和折叠/展开以适应它的文本标签。

<a id="btn_add" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-add',group:'sex',toggle:true,iconAlign:'right'">增加部门</a><br /> 
<a id="btn_find" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-search',group:'sex',toggle:true"">查找部门</a><br /> 
<a id="btn_update" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-edit',group:'sex',toggle:true"">修改部门</a><br /> 
<a id="btn_delete" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-remove',group:'sex',toggle:true"">删除部门</a><br /> 
<script> 
$("a").click(function(){ 
//获取单击的按钮的标题 
var title=$(this).text(); 
//去空格 
title=$.trim(title); 
alert(title); 
}); 
</script>

六、Form组件的使用

6.1 ValidateBox(验证框)

使用$.fn.validatebox.defaults重写默认值对象。

validatebox(验证框)的设计目的是为了验证输入的表单字段是否有效。如果用户输入了无效的值,它将会更改输入框的背景颜色,并且显示警告图标和提示信息。该验证框可以结合form(表单)插件并防止表单重复提交。

姓名:<input id="nameID" /><br /> 
邮箱:<input id="emailID" /><br /> 
密码:<input id="pwdID" /> 
<script> 
$("#nameID").validatebox({ 
required:true, 
//validType:'length[1,6]' 
validType:['length[1,6]','chinese'], 
delay:200, 
tipPosition:'left' 
}); 
//自定义规则,验证是否为汉字 
$.extend($.fn.validatebox.defaults.rules,{ 
chinese:{ 
//validator表示用户在文本框中输入的内容 
validator:function(value){ 
var reg=/^[\u4e00-\u9fa5]/; 
if(reg.test(value)){ 
return true; 
} 
}, 
//如果不符合中文规则, 
message:'姓名必须是中文' 
} 
}); 
$("#emailID").validatebox({ 
required:true, 
validType: ['length[1,30]','email'] 
}); 
$("#pwdID").validatebox({ 
required:true, 
validType: ['length[6,6]','pwdnum'] 
}); 
//自定义规则,验证是否为密码 
$.extend($.fn.validatebox.defaults.rules,{ 
pwdnum:{ 
//validator表示用户在文本框中输入的内容 
validator:function(value){ 
var reg=/^[0-9]/; 
if(reg.test(value)){ 
return true; 
} 
}, 
//如果不符合中文规则, 
message:'密码必须为数字' 
} 
}); 
</script>

对于表单验证,我们可以对其进行自定义规则。这个时候如果加上正则验证,就完全可以写出一个非常好的验证功能的了。在上面的这个属性中,还可以对提示框的位置进行改变,可以使用的属性是left和right。下面图片中显示的就是一个提示框在left的情况,一般情况下使用默认的right就可以了。

6.2 ComboBox(下拉列表框)

扩展自$.fn.combo.defaults。使用$.fn.combobox.defaults重写默认值对象。

下拉列表框显示一个可编辑文本框和下拉式列表,用户可以选择一个值或多个值。用户可以直接输入文本到列表顶部或选择一个或多个当前列表中的值。

静态方法创建:

<select id="cc" class="easyui-combobox" name="dept" style="width:200px;"> 
<option value="aa">aitem1</option> 
<option>bitem2</option> 
<option>bitem3</option> 
<option>ditem4</option> 
<option>eitem5</option> 
</select>

动态方法创建:

<input id="cityID" name="city" value="1"/> 
<script> 
$("#cityID").combobox({ 
url:"json/city.json", 
valueField:"id", 
textField:"name" 
}); 
$(function(){ 
$("#cityID").comcobox("setValue","长沙"); 
}); 
</script>

6.3 DateBox(日期输入框)

扩展自$.fn.combo.defaults。使用$.fn.datebox.defaults重写默认值对象。

日期输入框结合了一个可编辑的文本框控件和允许用户选择日期的下拉日历面板控件。选择的日期会自动转变为一个有效的日期然后填充到文本框中。选定的日期也可以被格式化为预定格式

日期:

<input id="dd" type="text"></input> 
<script> 
$('#dd').datebox({ 
required:true 
}); 
$("#dd").datebox({ 
onSelect:function(mydate){ 
var year=mydate.getFullYear(); 
var month=mydate.getMonth()+1; 
var date=mydate.getDate(); 
alert(year+"年"+month+"月"+date+"日"); 
} 
}); 
</script>

6.4 Slider(滑动条)

使用$.fn.slider.defaults重写默认值对象。

滑动条允许用户从一个有限的范围内选择一个数值。当滑块控件沿着轨道移动的时候,将会显示一个提示来表示当前值。用户可以通过设置其属性自定义滑块。

学生成绩:<span id="tip" ></span> 
<hr /> 
<div id="ss" style="height:400px;width:400px"> 
</div> 
<script> 
$("#ss").slider({ 
mode:"h", 
min:0, 
max:100, 
rule:[0,'|',25,'|',50,'|',75,'|',100], 
showTip:true, 
value:60 
}); 
$("#ss").slider({ 
onChange:function(newValue){ 
if(newValue==60){ 
$("#tip").text("合格").css("color","yellow"); 
}else if(newValue==70){ 
$("#tip").text("中等").css("color","pink"); 
}else if(newValue==80){ 
$("#tip").text("良好").css("color","blue"); 
}else if(newValue==90){ 
$("#tip").text("优秀").css("color","green"); 
} 
} 
}) 
</script>

6.5 NumberSpinner(数字微调)

数字微调控件的创建是基于微调控件和数值输入框控件的。他可以转换输入的值,比如:数值、百分比、货币等。它也允许使用上/下微调按钮调整到用户的期望值。

商品数量:

<input id="ss" style="width:100px"> <br /> 
你一共买了<span id="num">1</span>件商品 
<script> 
$('#ss').numberspinner({ 
value:1, 
min:1, 
max:100 
}); 
$('#ss').numberspinner({ 
onSpinUp:function(){ 
var value=$("#ss").numberspinner("getValue"); 
//将当前值设置到span标签 
$("#num").text(value).css("color","red"); 
}, 
onSpinDown:function(){ 
var value=$("#ss").numberspinner("getValue"); 
//将当前值设置到span标签 
$("#num").text(value).css("color","red"); 
} 
}); 
//添加键盘事件 
$('#ss').keyup(function(event){ 
//获取按键的unicode编码 
var myevent=event; 
var code=myevent.keyCode; 
if(code==13){ 
var value=$(this).val(); 
//将当前值设置到span标签 
$("#num").text(value).css("color","red"); 
} 
}); 
</script>

七、窗口组件的使用

7.1 Window(窗口)

扩展自$.fn.panel.defaults。使用$.fn.window.defaults重写默认值对象。

窗口控件是一个浮动和可拖拽的面板可以用作应用程序窗口。默认情况下,窗口可以移动,调整大小和关闭。它的内容也可以被定义为静态html或要么通过ajax动态加载。

静态方法创建:

<div id="win" class="easyui-window" title="My Window" style="width:600px;height:400px" 
data-options="iconCls:'icon-save',modal:true"> 
Window Content 
</div>

动态创建:

<input type="button" value="打开窗口1" id="open1"/> 
<input type="button" value="打开窗口2" id="open2"/> 
<div id="win1"></div> 
<div id="win2"></div> 
<script> 
$("#open1").click(function(){ 
$('#win1').window({ 
width:600, 
height:400, 
modal:false , 
minimizable :false, 
maximizable:false, 
title:"我的窗口" 
}); 
}); 
$("#open2").click(function(){ 
$('#win2').window({ 
width:600, 
height:400, 
modal:false , 
minimizable :false, 
maximizable:false, 
title:"我的窗口" 
}); 
}); 
</script>

7.2 Dialog(对话框窗口)

该对话框是一种特殊类型的窗口,它在顶部有一个工具栏,在底部有一个按钮栏。对话框窗口右上角只有一个关闭按钮用户可以配置对话框的行为显示其他工具,如collapsible,minimizable,maximizable工具等。

<input type="button" value="打开对话框" id="open1"/> 
<div id="win1"></div> 
<script> 
$("#open1").click(function(){ 
$('#win1').dialog({ 
width:400, 
height:400, 
modal:false , 
minimizable :false, 
maximizable:false, 
title:"我的对话框", 
toolbar:[ 
{ 
text:'编辑', 
iconCls:'icon-edit', 
handler:function(){alert('edit')} 
},{ 
text:'帮助', 
iconCls:'icon-help', 
handler:function(){alert('help')} 
} 
], 
buttons:[ 
{ 
text:'保存', 
handler:function(){alert("保存");} 
},{ 
text:'关闭', 
handler:function(){ 
//关闭对话框 
$("#win1").dialog("close"); 
} 
} 
], 
href:"/EasyUi/form.html" 
}); 
}); 
</script>

7.3 Messager(消息窗口)

消息窗口提供了不同的消息框风格,包含alert(警告框), confirm(确认框), prompt(提示框), progress(进度框)等。所有的消息框都是异步的。用户可以在交互消息之后使用回调函数去处理结果或做一些自己需要处理的事情。

<input type="button" value="确认框" /><br /> 
<input type="button" value="警告框" /><br /> 
<input type="button" value="输入框" /><br /> 
<input type="button" value="显示框" /><br /> 
<script> 
$("input").click(function(){ 
//定位button按钮,提供单击事件 
var tip=$(this).val(); 
tip=$.trim(tip); 
if("警告框"==tip){ 
$.messager.alert("警告框","警告处分","waring",function(){ 
//alert("关闭"); 
}); 
} 
if("确认框"==tip){ 
$.messager.confirm("确认框","你确认要删除么",function(value){ 
alert(value); 
}); 
} 
if("输入框"==tip){ 
$.messager.prompt("输入框","请输入你的姓名",function(name){ 
alert(name); 
}); 
} 
if("显示框"==tip){ 
$.messager.show({ 
showType: "slide", 
showSpeed: 600, 
width:300, 
height:300, 
title:"显示框", 
timeout:5000, 
msg:'消息将在5秒后关闭。' 
} 
); 
} 
}); 
</script>

八、表格和树组件的使用

使用$.fn.tree.defaults重写默认值对象。

树控件在web页面中一个将分层数据以树形结构进行显示。它提供用户展开、折叠、拖拽、编辑和异步加载等功能。

<ul id="treeID" class="easyui-tree"> 
<li> 
<span>第一章</span> 
<ul> 
<li> 
<span>第一节</span> 
<ul> 
<li> 
<span>第一条</span> 
</li> 
<li> 
<span>第二条</span> 
</li> 
</ul> 
</li> 
<li> 
<span>第二节</span> 
</li> 
</ul> 
</li> 
<li> 
<span>第二章</span> 
</li> 
</ul> 
<script type="text/javascript"> 
$(function(){ 
//收起所有的选项 
$("#treeID").tree("collapseAll"); 
}); 
</script>

我们还可以引入外部文件,使用json格式的文件来添加到这个tree中。

<ul id="treeID"></ul> 
<script type="text/javascript"> 
$("#treeID").tree({ 
url : "/EasyUi/json/pro.json" 
}); 
</script>

json格式为:

[ 
{ 
"id":1, 
"text":"广东", 
"state":"closed", 
"children":[ 
{ 
"id":11, 
"text":"广州" , 
"state":"closed", 
"children":[ 
{ 
"id":111, 
"text":"天河" 
}, 
{ 
"id":112, 
"text":"越秀" 
} 
] 
}, 
{ 
"id":12, 
"text":"深圳" 
} 
] 
}, 
{ 
"id":2, 
"text":"湖南" 
} 
] 

以上所述是小编给大家介绍的jQuery EasyUI基础教程之EasyUI常用组件(推荐),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对小牛知识库网站的支持!

 类似资料:
  • jQuery EasyUI 基础教程

  • 本文向大家介绍python基础教程之常用运算符,包括了python基础教程之常用运算符的使用技巧和注意事项,需要的朋友参考一下 Python的运算符和其他语言类似 (我们暂时只了解这些运算符的基本用法,方便我们展开后面的内容,高级应用暂时不介绍) 数学运算 判断 判断是真还是假,返回True/False  (还有is, is not等, 暂时不深入) 逻辑运算 True/False之间的运算 可以

  • 本文向大家介绍Javascript基础教程之数组 array,包括了Javascript基础教程之数组 array的使用技巧和注意事项,需要的朋友参考一下 字符串,数值,布尔值都属于离散值(scalar),如果某个变量是离散的,那么任何时候它只有一个值。 如果想使用变量存储一组值,就需要使用数组(array)。 数组是由多个名称相同的树值构成的集合,集合中每个数组都是数组的元素(element),

  • 本文向大家介绍DOM基础教程之事件类型,包括了DOM基础教程之事件类型的使用技巧和注意事项,需要的朋友参考一下 对于用户事件类型而言,最常用的是鼠标、键盘、浏览器。 1.鼠标事件: 鼠标的事件都频繁使用,下面例子就测试各种鼠标事件 鼠标的键值button测试(附对照表) 2.键盘事件 键盘事件种类不多,仅三种事件。 keydown(按下某键,一直按住会持续触发) keypress(按下某键并产生字

  • 本文向大家介绍Javascript基础教程之变量,包括了Javascript基础教程之变量的使用技巧和注意事项,需要的朋友参考一下 javascript 中变量通过var关键字(variable)来声明的。 也可以通过var 关键字给变量多个值。 此外,与java不同,javascript可以在同一个变量中存储不同的数据类型。例如 另外,javascript不需要声明变量就可以使用,例如: jav

  • 本文向大家介绍python基础教程之Hello World!,包括了python基础教程之Hello World!的使用技巧和注意事项,需要的朋友参考一下 Python命令行 假设你已经安装好了Python, 那么在Linux命令行输入: 将直接进入python。然后在命令行提示符>>>后面输入: 可以看到,随后在屏幕上输出: print是一个常用函数,其功能就是输出括号中得字符串。 (在Pyth