A few days ago, I referred to a book about jquery in China and learned how to use native JavaScript to implement jquery's "function"-custom Function Extension Dom function to simulate some jquery effects. It is found that such a method can directly construct and implement the desired effect (only a small part of the function) When jquery cannot be used (such as conflicting with other frameworks and user-defined functions ). Here we mainly focus on the construction and implementation processes.
First, let's take a look at the cause of the incident: N days ago, I made a page for someone else to do on one of my own (mainly piecing together two others' homepage slides and switching between JS images, I tried to use jquery to add more dynamic and more beautiful features, so I hid a form window for login and planned to use slidedown () for dynamic pop-up control. If the script does not have any errors, it will be ineffective in any case. Open the Web Console in Firefox, the call action does not respond, and $ initialization does not work, so it is changed to a function method call. The following error occurs:
$ (...). Is is not a function
I finally ruled out it one by one and found that when I deleted several other JS script calls, it was back to normal. Finally, confirm the problem in a script named ntes_jslib_1.x.js:
<script language="javascript" src="js/ntes_jslib_1.x.js" type="text/javascript" charset=utf-8></script>
This is a script for slide switching on the Internet, but it is not open for details. If this script is removed, it will return to normal. It is determined that jquery conflicts with it. So I thought about the solution. The down script does not look at it in detail, and it does not solve the problem of changing other frameworks (although it has not been taken into consideration ). So I thought about whether the native method can be implemented (just for a small dynamic, jquery is no longer used ). This reminds you of your previous understanding of extended DOM in a book.Author: Zhu Yinhong, details and practices of the sharply developed jquery Kernel). So I tried to retrieve the book.
For extended Dom functions, Dom and JavaScript have different "Scopes". For example in the book, the following functions cannot be implemented:
VaR appendto () = function (e) {e. appendchild (this); return this;} window. onload = function () {var DIV = document. getelementsbytagname ("Div") [0]; var H1 = document. createelement ("h1"); h1.appendto (DIV); // call a custom method, which is not actually implemented}
Therefore, it is necessary to extend the Dom to provide the basis for the function before using the Javascript Extension function.
For Dom extension, because the browser's two main factions (in fact, because God IE does not support the htmlelement type), there are two requirements: add a custom method to the HTML element type prototype object (not supported by IE), and bind a custom method to the DOM node (for IE ).
The detailed implementation is as follows:
VaR domextend = function (name, FN) {If (! Document. all) // used to judge non-ieeval ("htmlelement. prototype. "+ name +" = FN "); else {// ievar _ createelement = document. createelement; // store the original method document. createelement = function (TAG) {// rewrite method, bind a custom VaR _ ELEM = _ createelement (TAG) to createelement ); // first add the original method eval ("_ ELEM. "+ name +" = FN "); // bind a custom value. Return _ ELEM;} VaR _ getelementbyid = document. getelementbyid; document. getelementbyid = function (ID) {// bind custom VaR _ ELEM = _ getelementbyid (ID) to getelementbyid (ID); EVAL ("_ ELEM. "+ name +" = FN "); Return _ ELEM;} VaR _ getelementsbytagname = document. getelementsbytagname; document. getelementsbytagname = function (TAG) {// bind custom VaR _ arr = _ getelementsbytagname () to getelementsbytagname (TAG); For (VaR _ ELEM = 0; _ ELEM <_ arr. length; _ ELEM ++) eval ("_ arr [_ ELEM]. "+ name +" = FN "); Return _ arr ;}}};
Then, after constructing the domextend () method, you can continue to expand and construct other user-defined functions:
What I want to imitate is the jquery slidedown () function. Therefore, I need to construct the following methods:
Getstyle () is used to get the element style, offset () is used to get the absolute offset position, fromstyle () is used to convert the style value to a numerical value for calculation, setcss () is used to set the element style, resetcss () is used to restore the style after setting the style, and width () and height () are used to obtain the width and height of the element.
The details are as follows:
Domextend ("getstyle", function (n) {VaR _ this = this; if (_ this. style [N]) {return _ this. style [N];} else if (_ this. currentstyle) {return _ this. currentstyle [N];} else if (document. defaultview & document. defaultview. getcomputedstyle) {n = n. replace (/([A-Z])/g, "-$1"); n = n. tolowercase (); var S = document. defaultview. getcomputedstyle (_ this, null); If (s) return S. getpropertyvalue (n);} elsereturn NULL;}) domextend ("offset", functi On () {VaR _ this = This; var left = 0, Top = 0; while (_ this. offsetparent) {left + = _ this. offsetleft; top + = _ this. offsettop; _ this = _ this. offsetparent;} return {"Left": left, "TOP": Top };}) domextend ("fromstyle", function (W, p) {VaR _ this = this; vaR P = arguments [2]; If (! P) p = 1; if (/PX /. test (w) & parseint (w) return parseint (W) * P); else if (/\ % /. tese (w) & parseint (w) {var B = parseint (w)/100; If (P! = 1) & P) B * = P; _ this = _ this. parentnode; If (_ this. tagname = "body") throw new error ("no size! "); W = _ this. getstyle ("width"); // return arguments. callee (_ this, W, B);} else if (/auto /. test (w) {var B = 1; if (P! = 1) & P) B * = P; _ this = _ this. parentnode; If (_ this. tagname = "body") throw new error ("no size! "); W = _ this. getstyle (" width "); Return arguments. callee (_ this, W, B);} elsethrow new error (" Special Unit! ") ;}) Domextend (" setcss ", function (o) {VaR _ this = This; var A ={}; for (var I in O) {A [I] = _ this. style [I]; _ this. style [I] = O [I];} return a;}) domextend ("resetcss", function (o) {VaR _ this = this; for (var I in O) {_ this. style [I] = O [I] ;}}) domextend ("width", function () {VaR _ this = this; if (_ this. getstyle ("display ")! = "NONE") return _ this. offsetwidth | _ this. fromstyle (_ this. getstyle ("width"); var r = _ this. setcss ({display: "", position: "absolute", visibility: "hidden"}); var W = _ this. offsetwidth | _ this. fromstyle (_ this. getstyle ("width"); _ this. resetcss (r); Return W ;}) domextend ("height", function () {VaR _ this = this; if (_ this. getstyle ("display ")! = "NONE") return _ this. offsetheight | _ this. fromstyle (_ this. getstyle ("height"); var r = _ this. setcss ({display: "", position: "absolute", visibility: "hidden"}); var H = _ this. offsetheight | _ this. fromstyle (_ this. getstyle ("height"); _ this. resetcss (r); Return h ;})
Finally, everything is ready to construct slidedown ():
DOMextend("slideDown",function(time,fn){var _this=this;var isShow=_this.getStyle("display");if(isShow!="none")return;var oldcss=_this.setCSS({display:"",visibility:"hidden"})var x=_this.offset().left;var y=_this.offset().top;var height=_this.height();var width=_this.width();_this.resetCSS(oldcss);_this.style.display="";var box=_this.cloneNode(true);for(var i=0;i<box.childNodes.length;i++){box.removeChild(box.childNodes[i]);}_this.parentNode.insertBefore(box,_this);_this=_this.parentNode.removeChild(_this);box.appendChild(_this);box.style.overflow="hidden";box.style.display="";box.style.height=0;box.style.width=width;var step=5;var stepheight=step*height/time;var curstep=0;var interval=setInterval(function(){if(curstep>=height){clearInterval(interval);_this=_this.parentNode.removeChild(_this);box.parentNode.insertBefore(_this,box);box.parentNode.removeChild(box);fn();}else{curstep+=stepheight;box.style.height=curstep+"px";}},step);})
Call in the part I need to call:
JS section:
Function bonce () {var hiddes = document. getelementbyid ("hiddenlog"); hiddes. slidedown (300, function () {;}// no callback function currently, empty statement );}
Page:
<! ---- Login start --> <Div id = "login"> <Div id = "loginmen"> </div> <Div id =" loginsub "> <Div id =" hiddenlog "style =" display: none; "> <! -- Hidden part --> </div> <! -- Login end -->
Therefore, I can construct the slidedown () method without using jquery to achieve the desired effect.