JQuery对Dom节点操作以及事件操作

152 阅读8分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

一.选择器

1.1基本选择器

Id选择器:
(“#one”).css(“bcakground”,”red”); 类选择器: (“.mimn”).css(“background”,”red”);
标签选择器:
(div).css(background,red);通配符选择器:(“div”).css(“background”,”red”); 通配符选择器: (“*”)..css(“background”,”red”);
组合选择器:
(“span”,”#one”).css(“background”,”red”); 总结: JQuery中的基本选择器: ID选择器 类选择器 标签选择器 通配符选择器 群组选择器 ("#id"); (".className");(".className"); ("div"); ("\*");("\*"); ("h2,h3,.cc");

1.2层次选择器

选择body内的所有div元素:
(bodydiv).css(background,red)body内选择子元素是div(“body div”).css(“background”,”red”) 在body内选择子元素是div的 ("body > div").css("background","red");
Id为one 的下一个兄弟元素:
("#one + div").css("background","red"); id为two的元素后面的所有div兄弟元素: (“#one ~ div”).css("background","red");
层次选择器:从父子关系和兄弟关系来进行选择页面节点
("ab");:a节点的所有后代节点b都被选中("a b"); :a节点的所有后代节点b都被选中 ("a > b"); :a节点的所有子节点b都被选中
("a+b");:a节点之后的第一个兄弟节点b("a + b"); :a节点之后的第一个兄弟节点b ("a ~ b"); :a节点之后的所有兄弟节点b

1.3过滤选择器

1.3.1 基本过滤选择器

选择第一个DIV元素
(div:first).css("background","red");选择最后一个div元素(“div : first”).css("background","red"); 选择最后一个div元素 ("div:last").css("background","red");
选择class不为one的所有div元素
("div:not(.one)").css("background","red");选择索引值为偶数的div元素even:偶数odd:奇数("div:not(.one)").css("background","red"); 选择索引值为偶数的div元素 even:偶数 odd:奇数 ("div:even").css("background","red");
选择索引值为奇数的div元素
("div:odd").css("background","red");选择索引值等于3的元素("div:odd").css("background","red"); 选择索引值等于3的元素 ("div:eq(3)").css("background","red");
选择索引值大于3的元素
("div:gt(3)").css("background","red");选择索引值小于3的元素("div:gt(3)").css("background","red"); 选择索引值小于3的元素 ("div:lt(3)").css("background","red");
选择所有的标题元素
(":header").css("background","red");选择当前正在执行动画的所有元素(":header").css("background","red"); 选择当前正在执行动画的所有元素 (":animated").css("background","red");
基本过滤选择器:
从位置的角度来对页面的标签进行过滤选择
("tagName:first");("tagName:first"); ("tagName:last");
("tagName:eq(2)");("tagName:eq(2)"); ("tagName:gt(2)");
("tagName:lt(2)");("tagName:lt(2)"); ("tagName:odd");
("tagName:even");("tagName:even"); (":header");
(":animated");(":animated"); ("tagName:not(.one)")

1.3.2 内容过滤选择器

选取含有文本"di"的div元素
("div:contains(di)").css("background","red");选取不包含子元素(或者文本元素)div空元素.("div:contains('di')").css("background","red"); 选取不包含子元素(或者文本元素)的div空元素. ("div:empty").css("background","red");
选取含有class为mini元素 的div元素. ("tagName:has(.mini)")1.选中的是DIV元素2.子元素中的class值为mini("tagName:has(.mini)") 1.选中的是DIV元素 2.子元素中的class值为mini ("div:has(.mini)").css("background","red");
选取含有子元素(或者文本元素)的div元素.
("div:parent").css("background","red");内容过滤选择器总结:节点值是否为空,节点上的文本中是否包含指定的字符串,子元素中的class值是否为指定的值("div:parent").css("background","red"); 内容过滤选择器总结:节点值是否为空,节点上的文本中是否包含指定的字符串,子元素中的class值是否为指定的值 ("tagName:empty");
("tagName:parent");("tagName:parent"); ("tagName:contains('aaa')");
$("tagName:has(.one)");

1.3.3 属性过滤选择器:

选取含有属性title的div元素.
("div\[title\]").css("background","red"); 选取属性title值等于test的div元素. ("div[title='test']").css("background","red");
选取属性title值不等于test的div元素.
("div\[title!='test'\]").css("background","red"); 选取属性title值以te开始 的div元素. ("div[title^='te']").css("background","red");
选取属性title值以est结束的div元素.
("div\[title("div\[title='est']").css("background","red");
选取属性title值含有es的div元素.
("div\[title\*='es'\]").css("background","red"); 组合属性选择器,首先选取有属性id的div元素,然后在结果中 选取属性title值 含有 es 的元素. ("div[id][title*='es']").css("background","red");
属性过滤选择器:从节点的属性来过滤筛选节点:有无属性,属性值等于,不等于,包含,是**开头,是**结尾,多重过滤
("tagName:\[id\]"); ("tagName:[id='cc']");
("tagName:\[id!='cc'\]"); ("tagName:[title^='cc']");
("tagName:\[title("tagName:\[title='cc']");
("tagName:\[title\*='cc'\]"); ("tagName:[title*='cc'][name='ee'][id!='ff']");

1.3.4 可见性过滤选择性:

选中所有可见的div元素 ("div:visible"),设置样式;("div:visible"),设置样式; ("div:visible").css("background","blue");
1.选中不可见的所有元素 ("body:hidden").lenth;2.选中不可见的DIV元素("body :hidden").lenth; 2.选中不可见的DIV元素 ("div:hidden");
3.选中所有不可见的文本隐藏域 ("input:hidden")4.让所有不可见的DIV元素3秒内显示并且设置其为背景色("input:hidden") 4.让所有不可见的DIV元素3秒内显示并且设置其为背景色dm.show(3000).css("background","red");
选中body元素下看不到的元素,包含隐藏表单组件 ,这里有空格,代表层次选择器
alert(("body:hidden").length);alert(("body :hidden").length); alert(("div:hidden").length);
alert(("input:hidden").length);所有不可见的div元素在3秒内显示("input:hidden").length); 所有不可见的div元素在3秒内显示 ("div:hidden").show(3000);
可见性选择器:根据页面上的元素是否显示来选择节点
("tagName:visible");("tagName:visible"); ("tagName:hidden");
$("tagName :hidden"); 选中标签tagName下所有隐藏的元素,包括隐藏表单组件slow normal fast

1.3.5 元素过滤选择器

选取class为one的div下的第2个子元素
("div.one:nthchild(2)").css("background","blue");选取classonediv下的第1个子元素("div.one :nth-child(2)").css("background","blue"); 选取class为one的div下的第1个子元素 ("div.one :first-child").css("background","blue");
选取每个父元素下的最后一个子元素
("div.one:lastchild").css("background","blue");如果父元素下的仅仅只有一个子元素,那么选中这个子元素("div.one :last-child").css("background","blue"); 如果父元素下的仅仅只有一个子元素,那么选中这个子元素 ("div.one :only-child").css("background","blue");
子元素过滤选择器:选择父元素下的子元素(第1个,最后1个,唯一的一个,第几个子元素)
("tagName:firstchild");("tagName :first-child"); ("tagName :last-child");
("tagName:onlychild");("tagName :only-child"); ("tagName :nth-child(2)");
1.3.6 表单对象属性过滤选择器
选中所有可用元素 ("input:enabled")("input:enabled") ("input:enabled").val("AAA");
选中所有不可用元素 ("input:disabled")("input:disabled") ("input:disabled").val("BBB");
总结:从表单组件的可用还是不可用来进行选择节点

1.4表单选择器

选中页面上的2个按钮
alert(("#form1 :button").length); 选中表单下的<button> alert(("#form1 button").html("AAA"));
alert(("#form1 :checkbox").length); ("#form1 :checkbox:eq(0)").attr("checked","true");
选中id为form1的表单小的input开头的组件
alert(("#form1 input").length); 选中id为form1下的所有表单组件 包括textarea button select alert(("#form1 :input").length);
选中id为form1表单下的所有不可见元素
alert($("#form1 :hidden").length);

二.节点操作

2.1查找节点

获取p节点
var pDm=pDm=("p");
输出p节点的title属性
alert(pDm.attr("title"));//获取第2li节点varpDm.attr("title")); //获取第2个li节点 var li_2=("ulli:eq(1)");//输出第2li节点的title属性alert(("ul li:eq(1)"); //输出第2个li节点的title属性 alert(li_2.attr("title"));
//输出第2个li节点的文本内容
alert(li_2.html());2.2创建节点创建两个<li>元素节点,并且要把他们作为<ul>元素节点的子节点添加到DOMli\_2.html()); 2.2创建节点 创建两个<li>元素节点,并且要把他们作为<ul>元素节点的子节点添加到DOM中 (html);
(html)方法会根据传入的HTML对象标记字符串,创建一个DOM对象,并将这个对象包装成一个jQuery对象然后返回。创建2li节点,要求这2li节点包含文本包含属性titlevar(html)方法会根据传入的HTML对象标记字符串,创建一个DOM对象,并将这个对象包装成一个jQuery对象然后返回。 创建2个li节点,要求这2个li节点包含文本包含属性title var dm1=("<lititle=西瓜44>西瓜</li>");var("<li title='西瓜44'>西瓜</li>"); var dm2=("<lititle=香蕉55>香蕉</li>");//将新创建的第1li节点追加到ul节点下的最后一个子节点("<li title='香蕉55'>香蕉</li>"); //将新创建的第1个li节点追加到ul节点下的最后一个子节点 ("ul").append(dm1);dm1); ("ul").append(dm1);//将新创建的第2li节点追加到ul节点下的第一个子节点dm1); //将新创建的第2个li节点追加到ul节点下的第一个子节点 ("ul").prepend($dm2);

2.3插入节点

var dm1=dm1=("

  • 葡萄
  • ");
    var dm2=dm2=("
  • 西瓜
  • ");
    var dm3=dm3=("
  • 香蕉
  • ");
    var ulDm=ulDm=("ul");
    var li_2=li\_2=("ul li:eq(1)");
    //用2种方式来将创造的第1个节点添加到ul下的最后一个子节点
    //ulDm.append(ulDm.append(dm1);
    //dm1.appendTo(dm1.appendTo(ulDm);
    //用2种方式来讲创造的第2个节点添加到ul下的第一个子节点
    //ulDm.prepend(ulDm.prepend(dm2);
    //dm2.prependTo(dm2.prependTo(ulDm);
    //用2种方式将创造的li节点追加到第2个已经存在的li节点之后
    //li_2.after(li\_2.after(dm3);
    //dm3.insertAfter(dm3.insertAfter(li_2);
    //用2种方式将创造的li节点追加到第2个已经存在的li节点之前
    //li_2.before(li\_2.before(dm3);
    //dm3.insertBefore(dm3.insertBefore(li_2);

    2.4删除节点

    直接找到我们要操作的节点删除即可.
    ("ulli:eq(1)").remove();jquery种删除掉的节点还可以继续获得var("ul li:eq(1)").remove(); jquery种删除掉的节点还可以继续获得 var dm=("ulli:eq(1)").remove();("ul li:eq(1)").remove(); dm.appendTo(("ul"));JQuery中删除节点可以加过滤条件("ul")); JQuery中删除节点可以加过滤条件 ("ul li").remove("li[title!=菠萝]");
    获取第2个li节点后,将其元素中的内容清空
    $("ul li:eq(1)").empty();

    2.5复制元素

    克隆匹配的DOM元素并且选中这些克隆的副本。
    在想把DOM文档中元素的副本添加到其他位置时这个函数非常有用。
    克隆所有b元素(并选中这些克隆的副本),然后将它们前置到所有段落中。
    HTML 代码:
    Hello

    , how are you?


    jQuery 代码:
    ("b").clone().prependTo("p");结果:<b>Hello</b><p><b>Hello</b>,howareyou?</p>描述:创建一个按钮,他可以复制自己,并且他的副本也有同样功能。HTML代码:<button>CloneMe!</button>jQuery代码:("b").clone().prependTo("p"); 结果: <b>Hello</b><p><b>Hello</b>, how are you?</p> 描述: 创建一个按钮,他可以复制自己,并且他的副本也有同样功能。 HTML 代码: <button>Clone Me!</button> jQuery 代码: ("button").click(function(){
    $(this).clone(true).insertAfter(this);
    });

    2.6包裹节点

    2.6.1 把所有匹配的元素用其他元素的结构化标记包裹起来。

    这种包装对于在文档中插入额外的结构化标记最有用,而且它不会破坏原始文档的语义品质。这个函数的原理是检查提供的第一个元素(它是由所提供
    的HTML标记代码动态生成的),并在它的代码结构中找到最上层的祖先元素--这个祖先元素就是包裹元素。当HTML标记代码中的元素包含文本时无法
    使用这个函数。因此,如果要添加文本应该在包裹完成之后再行添加。
    $("p").wrap("

    ");

    2.6.2 这个方法将移出元素的父元素。

    这能快速取消 .wrap()方法的效果。匹配的元素(以及他们的同辈元素)会在DOM结构上替换他们的父元素。
    $("p").unwrap()

    2.6.3 将所有匹配的元素用单个元素包裹起来

    这于 '.wrap()' 是不同的,'.wrap()'为每一个匹配的元素
    都包裹一次。这种包装对于在文档中插入额外的结构化标记最有用,而且它不会破坏原始文档的语义品质。这个函数的原理是检查提供的第一个元素并
    在它的代码结构中找到最上层的祖先元素--这个祖先元素就是包装元素。
    $("p").wrapAll("

    ");

    2.6.4 将每一个匹配的元素的子内容(包括文本节点)用一个HTML结构包裹起来

    这个函数的原理是检查提供的第一个元素(它是由所提供的HTML标记代码动态生成的),并在它的代码结构中找到最上层的祖先元素--这个祖先元素
    就是包装元素。
    $("p").wrapInner("");

    2.7 属性操作

    在JQuery中有很多类似的操作,获取节点的文本,获取节点的属性,
    dm.html();dm.html(); dm.html("AAAA");
    dm.attr("title");dm.attr("title"); dm.attr("title","BBBBB");
    删除属性
    $("p").removeAttr("title");

    2.8 样式操作

    获取样式
    alert(("p").attr("class"));设置样式原先的样式不存在("p").attr("class")); 设置样式 原先的样式不存在 ("p").attr("class","high")
    追加样式 原先的样式还存在
    ("p").addClass("high")删除全部样式("p").addClass("high") 删除全部样式 ("p").removeClass()
    删除指定样式
    ("p").removeClass("high");重复切换样式("p").removeClass("high"); 重复切换样式 dm.toggleClass("another");
    ("p").toggleClass("high");判断元素p是否含有某样式("p").toggleClass("high"); 判断元素p是否含有某样式 dm.hasClass("another")
    alert($("p").hasClass("high"));
    JQuery提供了丰富的API让我们操作节点的样式:
    获取节点的样式,设置节点的样式,追加节点的样式,删除节点的样式(全部,指定)
    重复切换样式,判读节点是否包含指定的样式

    2.9 CSS-DOM

    alert(("p").css("color"));设置<p>元素的color("p").css("color")); 设置<p>元素的color ("p").css("color","red");
    设置

    元素的fontSize和backgroundColor dm.css("k1":v1,"k2":v2);dm.css({"k1":v1,"k2":v2}); ("p").css({"fontSize":30,"backgroundColor":'pink'});
    获取

    元素的高度
    alert(("p").height());获取<p>元素的宽度alert(("p").height()); 获取<p>元素的宽度 alert(("p").width());
    设置

    元素的高度
    ("p").height("100px");设置<p>元素的宽度("p").height("100px"); 设置<p>元素的宽度 ("p").width("300px");
    获取

    元素的的左边距和上边距 dm.offset();dm.offset(); dm.left dm.topvarobj=dm.top var obj=("p").offset();
    alert(obj.left);
    alert(obj.top);
    JQuery中对节点的样式操作,有2种实现方案:
    第一种是将节点的样式作为节点的一个属性来进行整体操作
    dm.attr("class","myClass");第二种方案通过节点的CSSDOM来控制节点的样式dm.attr("class","myClass"); 第二种方案通过节点的CSSDOM来控制节点的样式 dm.css("background","red");
    $dm.css("background");

    2.10 遍历节点数

    利用JQuery的chldren方法来获取页面上所有的body子元素
    children()方法只考虑子元素而不考虑任何后代元素。。
    alert(("body").children().length);vardms=("body").children().length); var dms=("body").children();
    for(var i=0;i<dms.length;i++){
    alert(dms[i].innerHTML);
    next()方法获取匹配元素后面紧临的同辈元素
    prev()方法获取匹配元素前面紧临的同辈元素。
    siblings()匹配元素前后所有的同辈元素。
    页面加载完毕之后,获取p节点后的同辈元素,输出其文本内容
    页面加载完毕之后,获取p节点前的同辈元素,输出其文本内容
    页面加载完毕之后,获取p节点所有的同辈元素
    window.onload=function(){
    //获取p节点之后所有的同辈元素
    var dms=("p").nextAll(); //for(var i=0;i<dms.length;i++){ // alert(dms\[i\].innerHTML); //} //获取节点P之前所有的兄弟节点 //dms=("p").prevAll();
    //for(var i=0;i<dms.length;i++){
    // alert(dms[i].innerHTML);
    //}
    //获取p节点所有的兄弟节点
    dms=$("p").siblings();
    for(var i=0;i<dms.length;i++){
    alert(dms[i].innerHTML);
    }

    2.11 设置和获取HTML文本和值

    获取

    元素的HTML代码 dm.html();如果p节点中有HTML标签,那么标签也会被返回alert(dm.html(); 如果p节点中有HTML标签,那么标签也会被返回 alert(("p").html());
    获取

    元素的文本
    通过方法text返回节点的内容,如果节点上包含HTML标签,那么这些标签不会被返回,仅仅返回文本信息
    alert(("p").text());PS:("p").text()); PS: dm.html(); dm.text();区别:设置<p>元素的HTML代码dm.text(); 区别: 设置<p>元素的HTML代码 dm.html("夹杂HTML标签");
    //如果文本中包含对应的HTML标签,那么这些标签将会被浏览器作为普通标签来识别
    ("p").html("<spanstyle=background:red>DDDDD</span>");设置<p>元素的文本("p").html("<span style='background:red'>DDDDD</span>"); 设置<p>元素的文本 dm.text("不夹杂html标签");
    ("p").text("FFFFFF");设置<p>元素的文本("p").text("FFFFFF"); 设置<p>元素的文本 dm.text("夹杂HTML标签");
    如果文本中包含了HTML标签,那么这些标签将会作为内容来识别
    ("p").text("<spanstyle=background:red>DDDDD</span>");获取当前按钮的valuealert(("p").text("<span style='background:red'>DDDDD</span>"); 获取当前按钮的value值 alert(("#btn1").val());
    设置当前按钮的value值
    ("#btn2").val("我是后来设置的内容"); 在JQuery中获取和设置节点的文本有2种方式:dm.html() dm.text();注意区分2者的不同之处获取:1html()不仅能获取文本内容,还可以获取标签内容2text()仅仅获取文本内容设置:1html()设置的文本中含有标签时,会被浏览器进行解析2text()设置的文本内容中含有标签时,不会被浏览器进行解析,作为字符串处理获取和设置节点的value值用dm.text(); 注意区分2者的不同之处 获取: 1、html()不仅能获取文本内容,还可以获取标签内容 2、text()仅仅获取文本内容 设置: 1、html()设置的文本中含有标签时,会被浏览器进行解析 2、text()设置的文本内容中含有标签时,不会被浏览器进行解析,作为字符串处理 获取和设置节点的value值用 dm.val();
    用JQuery的方式为页面上的按钮绑定事件
    ("#address").bind("focus",function(){ if(this.value=='请输入邮箱地址'){ this.value=""; } }); ("#address").bind("blur",function(){
    if(this.value==''){
    this.value="请输入邮箱地址";

    三.Jquery的事件

    3.1 Window.onload和$(document).ready()

    window.onload=function(){
    alert("BBBBB");
    }
    JQuery提供的 页面加载完毕之后执行function中的代码
    (document).ready(function()alert("CCCCCC"););简写形式(document).ready(function(){ alert("CCCCCC"); }); 简写形式 (function(){
    alert("DDDDDD");
    });
    区别:
    1.用window.onload的方式来加载页面:必须等页面上所有的元素(图片,.js文件,CSS文件)全部传递到客户端之后才去执行其中的代码
    2.用JQuery的形式来加载页面,页面上的DOM树形成了,无需等到所有资源加载完毕之后才去执行代码
    3.可以绑定的函数不一样 window.onload只能绑定1个函数 用JQuery的形式可以绑定多个

    3.2 JQuery完善的事件处理机制

    JQuery为节点pv绑定事件之前已经做过判断处理了
    window.onload=function(){
    var dm=document.getElementById("pvv");
    //为了保证代码的健壮性,为页面中的 节点绑定各种事件之前需要做大量的判断
    if(dm!=null){
    dm.onclick=function(){alert("ZZZZ");}
    }
    alert("ZZZZZZZ");
    }
    $("#pvv").bind("click",function(){alert("AAAAAA");})
    alert("AAAAAAA");
    });

    3.3 事件绑定与合成

    获取id为panel下的class的值为head的h5元素,
    * 为这个元素用JQuery的原始方式绑定点击事件
    * 让当前元素的下一个兄弟节点显示
    ("#panel h5.head").bind("click",function(){ (this).next().show();
    });
    用JQuery的这种事件绑定方式可以很方便的实现 代码和内容分离, html标签和JS代码没有任何掺杂.
    * 页面加载完毕之后为id为panel下的class值为head的h5元素用原始方式绑定一个click事件,
    * 获取当前节点的下一个兄弟元素content\*content \* 当coantent元素为的状态为可见状态是dm.is(":visible")让节点dm.is(":visible")让节点content节点隐藏.
    * 否则让节点content节点隐藏.content节点隐藏. ("#panel h5.head").bind("click",function(){
    var dm=dm=(this).next();
    //判断当前节点是否是显示
    if(dm.is(":visible")){ dm.hide(); //让当前节点隐藏
    }else{
    dm.show(); //让当前节点显示 } \* 页面加载完毕之后, \* 为id为panel下的class的值为head的h5元素用原始方式绑定mouseover事件, \* 让当前节点的下一个兄弟节点显示 \* 为id为panel下的class的值为head的h5元素用原始方式绑定mouseout事件, \* 让当前节点的下一个兄弟节点隐藏 ("#panel h5.head").bind("mouseover",function(){
    (this).next().show(); }); ("#panel h5.head").bind("mouseout",function(){
    (this).next().hide(); });\*/ JQuery支持链式操作 ("#panel h5.head").bind("mouseover",function(){
    (this).next().show(); }).bind("mouseout",function(){ (this).next().hide();
    });
    * 等待页面加载完毕之后,
    * 为id为panel下的class值为head的h5元素用简写形式绑定一个mouseover事件,让当前节点的下一个兄弟节点显示
    * 为id为panel下的class值为head的h5元素用简写形式绑定一个mouseout事件,让当前节点的下一个兄弟节点隐藏
    用简写形式为节点绑定事件
    ("#panel h5.head").mouseover(function(){ (this).addClass("highlight");
    (this).next().show(); }).mouseout(function(){ (this).removeClass("highlight");
    (this).next().hide(); }) 合成事件 \* 为元素"h5.head"绑定hover事件, \* 分别让当前节点的兄弟显示和隐藏 \* hover事件是模拟了页面上的鼠标悬停和鼠标移开事件 ("h5.head").hover(function(){
    (this).next().show(); },function(){ (this).next().hide();
    });
    * 为元素"h5.head"绑定toggle事件,
    * 分别让当前元素的下一个兄弟节点显示和隐藏
    * toggle模拟了鼠标的连续点击事件
    ("h5.head").toggle(function()alert("1111");,function()alert("22222");,function()alert("3333"););("h5.head").toggle(function(){ alert("1111"); },function(){ alert("22222"); },function(){ alert("3333"); }); ("h5.head").toggle(function(){
    (this).next().show(); },function(){ (this).next().hide();
    });
    * 为元素绑定click事件,让当前节点下一个兄弟节点切换显示dm.next().toggle();\*2种方式实现dm.next().toggle(); \* 2种方式实现 ("h5.head").click(function(){
    //如果将toggle当做一个函数来调用的话,可以切换当前节点的显示状态
    (this).next().toggle(); }); \* 为元素绑定toggle事件. \* 1.当前节点增加样式.highlight 当前节点的下一个兄弟节点显示 \* 2.为当前节点移除样式.highlight,当前节点的下一个兄弟节点隐藏 (".head").toggle(function(){
    (this).addClass("highlight");(this).addClass("highlight"); (this).next().show();
    },function(){
    (this).removeClass("highlight");(this).removeClass("highlight"); (this).next().hide();
    });
    });