c := make(chan bool) //创建一个无缓冲的bool型Channel
c <- x //向一个Channel发送一个值
<- c //从一个Channel中接收一个值
x = <- c //从Channel c接收一个值并将其存储到x中
x, ok = <- c //从Channel接收一个值,如果channel关闭了或没有数据,那么ok将被置为false
不带缓冲的Channel兼具通信和同步两种特性,颇受青睐。
三、Channel用作信号(Signal)的场景
1、等待一个事件(Event)
等待一个事件,有时候通过close一个Channel就足够了。例如:
//testwaitevent1.go
package main
import “fmt”
func main() {
fmt.Println(“Begin doing something!”)
c := make(chan bool)
go func() {
fmt.Println(“Doing something…”) close(c)
}() <-c
fmt.Println(“Done!”)
}
根据《Go memory model》中关于close channel与recv from channel的order的定义:The closing of a channel happens before a receive that returns a zero value because the channel is closed.
我们可以很容易判断出上面程序的输出结果:
Begin doing something!
Doing something…
Done!
如果将close(c)换成c<-true,则根据《Go memory model》中的定义:A receive from an unbuffered channel happens before the send on that channel completes.
“<-c“要先于”c<-true“完成,但也不影响日志的输出顺序,输出结果仍为上面三行。
func worker(die chan bool, index int) {
fmt.Println(“Begin: This is Worker:”, index)
for {
select {
//case xx:
//做事的分支
case <-die:
fmt.Println(“Done: This is Worker:”, index)
return
}
}
}
func main() {
die := make(chan bool)
for i := 1; i <= 100; i++ {
go worker(die, i)
}
time.Sleep(time.Second * 5)
close(die)
select {} //deadlock we expected
}
func worker(die chan bool) {
fmt.Println(“Begin: This is Worker”)
for {
select {
//case xx:
//做事的分支
case <-die:
fmt.Println(“Done: This is Worker”)
die <- true
return
}
}
}
func main() {
die := make(chan bool)
go worker(die)
die <- true
<-die
fmt.Println(“Worker goroutine has been terminated”)
}
func generator(strings chan string) {
strings <- “Five hour’s New York jet lag”
strings <- “and Cayce Pollard wakes in Camden Town”
strings <- “to the dire and ever-decreasing circles”
strings <- “of disrupted circadian rhythm.”
close(strings)
}
func main() {
strings := make(chan string)
go generator(strings)
for s := range strings {
fmt.Printf(“%s\n”, s)
}
fmt.Printf(“\n”)
}
四、隐藏状态
下面通过一个例子来演示一下channel如何用来隐藏状态:
1、例子:唯一的ID服务
//testuniqueid.go
package main
import “fmt”
func newUniqueIDService() <-chan string {
id := make(chan string)
go func() {
var counter int64 = 0
for {
id <- fmt.Sprintf(“%x”, counter)
counter += 1
}
}()
return id
}
func main() {
id := newUniqueIDService()
for i := 0; i < 10; i++ {
fmt.Println(<-id)
}
}
declare @t table(CountryRegionCode nvarchar(3))
insert into @t(CountryRegionCode) (select CountryRegionCode from person.CountryRegion where Name like ‘C%’)select * from person.StateProvince where CountryRegionCode
in (select * from @t)
虽然上面的SQL语句要比第一种方式更复杂,但却将子查询放在了表变量@t中,这样做将使SQL语句更容易维护,但又会带来另一个问题,就是性能的损失。由于表变量实际上使用了临时表,从而增加了额外的I/O开销,因此,表变量的方式并不太适合数据量大且频繁查询的情况。为此,在SQL Server 2005中提供了另外一种解决方案,这就是公用表表达式(CTE),使用CTE,可以使SQL语句的可维护性,同时,CTE要比表变量的效率高得多。
with
cr as
(
select CountryRegionCode from person.CountryRegion where Name like ‘C%’
)select * from person.StateProvince where CountryRegionCode in (select * from cr)
其中cr是一个公用表表达式,该表达式在使用上与表变量类似,只是SQL Server 2005在处理公用表表达式的方式上有所不同。
with
cr as
(
select CountryRegionCode from person.CountryRegion where Name like ‘C%’
)
select * from person.CountryRegion — 应将这条SQL语句去掉
— 使用CTE的SQL语句应紧跟在相关的CTE后面 —
select * from person.StateProvince where CountryRegionCode in (select * from cr)
with
cte1 as
(
select * from table1 where name like ‘abc%’
),
cte2 as
(
select * from table2 where id > 20
),
cte3 as
(
select * from table3 where price < 100
)
select a.* from cte1 a, cte2 b, cte3 c where a.id = b.id and a.id = c.id
declare @s nvarchar(3)
set @s = ‘C%’
; — 必须加分号
with
t_tree as
(
select CountryRegionCode from person.CountryRegion where Name like @s
)
select * from person.StateProvince where CountryRegionCode in (select * from t_tree)
Even if you are not a Terminal wizard, there are some fun tools and features of it that can be amusing. For instance, some online services are available for you to log into with Telnet and watch a text-based version of Star Wars, or you can play odd games that folks have coded into the “emacs” editor, among others. If you are ever sitting at your Mac and suddenly have the urge to print out a massive banner of a text phrase, then you can do that to.
First, open the Terminal, then type the following:
banner "MacIssues"
This will create a vertical banner in hash characters of the word “MacIssues” and you can change the text to whatever you would like, to have a banner of that printed. By default this will output to the Terminal window, but you can quickly route the output to a TextEdit document by piping the output with the following approach:
banner "MacIssues" | open -fe
In the text document that opens, if the banner appears garbles, then resize the window until the message is accommodated, and then print to whatever printer you have.
Granted there are plenty of free tools or those in common word processing and design programs that can do this, and often with greater style (drop shadows, colors, fonts, etc.); however, this is a quick way to punch out a banner on pretty much any Mac, at any time. Note that being a Terminal-based option, this approach is doable on many other Unix and Linux distributions as well, so if you’re ever indulging in your geek side and suddenly have the urge to make a banner, this is likely how you would do it.
If you have a system that is used by other people, you may want to give them managed user accounts and then reserve a separate administrative account for installing apps and changing system settings. This is especially true for situations where many people may be using one computer, such as in classrooms. While you can always create an administrative account, by default such accounts will show up along with others at the login window, in the Fast User Switch menu, and other locations; however, you can set this up to be hidden from most of these locations.
The root account
One approach for a hidden user account is to enable the root account. However this being fully unrestricted comes with inherent risks. Even though admin accounts may authenticate for root access, this ability is time- or session-limited, meaning that authentication is regularly required to ensure administrative actions are truly desired. However, with the root account no such checks are done, and faulty administrative actions can be harmful. Since practically every root action can be done from an administrative account, its best to avoid enabling root unless some action cannot be done otherwise.
Dedicated administrative accounts
To create a special hidden user account that has administrative rights, you can go one of two routes based on the version of OS X that you have, but first you must create the account. This can either be done in the Users & Groups system preferences, or by using the command line (useful for scripting or remote-access approaches). For the second approach, open the Terminal and then run the following set of commands (replace USERNAME with the corresponding name of your account):
Now the following commands will create and assign the user’s home folder, which by default is in the /Users directory, but since this is a hidden account we are putting it in the hidden /var directory:
Set the user’s ID to a value unique from the list of User IDs you found in the first step above (change NUM to reflect the value of your selected ID):
sudo dscl . create /Users/USERNAME UniqueID NUM
If your version of OS X is prior to Yosemite, then you can set this unique value to something less than 500, and OS X should hide it. Otherwise, run the following command to have the login window hide users under 500:
Note that if you have created the user account in the Users & Groups system preferences, then you can change the User ID and home folder location in the system preferences by right-clicking the user and choosing the advanced options, then adjusting the values accordingly.
If your version of OS X is Yosemite or later, then you have additional approaches available to you for hiding the user account. Instead of being forced to use a User ID value under 500, you can use any ID you want and then set a special attribute for the user account that will hide it:
sudo dscl . create /Users/USERNAME IsHidden 1
To undo this change, re-run the command with “0” instead of “1,” or run the following command to remove the attribute altogether:
sudo dscl . delete /Users/USERNAME IsHidden
Finding hidden user accounts
While these approaches will hide a user account from the login window, the Users & Groups system preferences, and the Fast User Switching menu, you can still view the account. The following command will list the users on the system and then filter out system-based accounts, so you will see the short usernames of all the current users:
dscl . list /Users | grep -v "_\|nobody\|root\|daemon"
Online tools for testing code snippets make it an indispensable assistant to the developers to check the quality of their code in reducing errors and keep coding practices easier. Here are 10 of the best online tools for testing code snippets in order to help find security flaws and reduce developments costs.
Build, Explore, and Teach the Web, Instantly. CodePen is a web-based HTML, CSS, and JavaScript code editor that lets you experiment with code right in the browser.
JS Bin is a webapp specifically designed to help JavaScript and CSS folk test snippets of code, within some context, and debug the code collaboratively.
SQLFiddle is an online SQL query processing tool. You can run your SQL statements online without having a locally installed database. It can overcome the feature where you can have a database inside a portable disk and plug it for use anywhere. It is also designed to support multiple databases.
Dabblet is an interactive playground for quickly testing code snippets of CSS and HTML. It uses -prefix-free, so that you won’t have to add any prefixes in your CSS code. You can save your work in Github gists, embed it in other websites and share it with others.
Ideone is an online compiler and debugging tool which allows you to compile source code and execute it online in more than 60 programming languages. Choose a programming language, enter the source code with optional input data and you are ready to go!
Tinkerbin lets you play around with HTML, JavaScript, and CSS without creating files or uploading to servers. It also supports CoffeeScript, Sass(with Compass), Less, HAML, and more.
Whether you’re a developer or a designer, a strong jQuery skillset is something you can’t afford to be without. Today, I’m going to show you 30 handy jQuery coding tricks that will help you make your scripts more robust, elegant and professional.
Getting Started
These tips and tricks all have one thing in common- they are all smashingly useful. With this stuff in your back pocket, you’ll be ready to go change the world, and even better, write jQuery like you know what you’re doing. It’s gonna be fun.
We’ll start with some basic tricks, and move to some more advanced stuff like actually extending jQuery’s methods and filters. Of course, you should be familiar with the basics of jQuery first. If you haven’t used jQuery before, I highly recommend browsing the documentation and watching jQuery for Absolute Beginners Video Series. Otherwise, you’re ready to dig in!
#1 – Delay with Animate()
This is a very quick, easy way to cause delayed actions in jQuery without using setTimeout. The way we make it work is to add an animate function into your chain and animate the element to 100% opacity (which it’s already at), so it looks like nothing is happening.
For instance, let’s say that you wanted to open a dialog and then fade it away after 5 seconds. Using animate, you can do it like this:
Don’t you just love jQuery chaining? You’re welcome to read more about this technique from Karl Swedberg.
UPDATE: jQuery 1.4 has eliminated the need for this hack with a method called delay(). It is just what is sounds like – a function specifically made to delay an animation effect. Way to go, jQuery!
#2 – Loop through Elements Backwards
One of my personal favorites is being able to loop backwards through a set of elements. We all know each() lets us easily loop through elements, but what if we need to go backwards? Here’s the trick:
1
2
3
4
5
6
7
8
$(function(){
var reversedSet = $("li").get().reverse();
//Use get() to return an array of elements, and then reverse it
$(reversedSet).each(function(){
//Now we can plug our reversed set right into the each function. Could it be easier?
});
});
#3 – Is There Anything in the jQuery Object?
Another very elementary but regularly useful trick is checking if there are any elements in the jQuery object. For example, let’s say we need to find out if there are any elements with a class of ‘active’ in the DOM. You can do that with a quick check of the jQuery object’s length property like this:
1
2
3
4
5
$(function(){
if( $(".active").length ){
//Now the code here will only be executed if there is at least one active element
}
});
This works because 0 evaluates false, so the expression only evaluates true if there is at least one element in the jQuery object. You can also use size() to do the same thing.
#4 – Access iFrame Elements
Iframes aren’t the best solution to most problems, but when you do need to use one it’s very handy to know how to access the elements inside it with Javascript. jQuery’s contents() method makes this a breeze, enabling us to load the iframe’s DOM in one line like this:
1
2
3
4
5
6
7
$(function(){
var iFrameDOM = $("iframe#someID").contents();
//Now you can use <strong>find()</strong> to access any element in the iframe:
iFrameDOM.find(".message").slideUp();
//Slides up all elements classed 'message' in the iframe
});
#5 – Equal Height Columns
This was one of CSS Newbie’s most popular posts of 2009, and it is a good, solid trick to have in your toolbox. The function works by accepting a group of columns, measuring each one to see which is largest, and then resizing them all to match the biggest one. Here’s the code (slighly modified):
1
2
3
4
5
6
7
8
9
10
11
12
$(function(){
jQuery.fn.equalHeight = function () {
var tallest = 0;
this.each(function() {
tallest = ($(this).height() > tallest)? $(this).height() : tallest;
});
return this.height(tallest);
}
//Now you can call equalHeight
$(".content-column").equalHeight();
});
An interesting and similar concept is the awesome jQuery masonry plugin, if you’re interested in checking it out.
#6 – Find a Selected Phrase and Manipulate It
Whether you’re looking to perform find and replace, highlight search terms, or something else, jQuery again makes it easy with html():
1
2
3
4
5
6
7
8
9
10
11
12
$(function(){
//First define your search string, replacement and context:
var phrase = "your search string";
var replacement = "new string";
var context = $(body);
//
context.html(
context.html().replace('/'+phrase+'/gi', replacement);
);
});
#7 – Hack Your Titles to Prevent Widows
Nobody likes to see widows – but thankfully with some jQuery and a little help from we can stop that from happening:
1
2
3
4
5
6
7
8
$(function(){
//Loop through each title
$("h3").each(function(){
var content = $(this).text().split(" ");
var widow = "&nbsp;"+content.pop();
$(this).html(content.join(" ")+widow);
});
});
This technique was suggested in a comment by Bill Brown on Css-Tricks.
#8 – Add Pseudo-Selector Support in IE
Whether or not to support IE (especially 6) is a hotly debated issue, but if you are of the “let’s-make-the-best-of-this” camp, it’s nice to know that you can add pseudo-selector support with jQuery. And we aren’t just limited to :hover, although that’s the most common:
$(function(){
<strong>//ADD HOVER SUPPORT:</strong>
function hoverOn(){
var currentClass = $(this).attr('class').split(' ')[0]; //Get first class name
$(this).addClass(currentClass + '-hover');
}
function hoverOff(){
var currentClass = $(this).attr('class').split(' ')[0]; //Get first class name
$(this).removeClass(currentClass + '-hover');
}
$(".nav-item").hover(hoverOn,hoverOff);
<strong>//ADD FIRST-CHILD SUPPORT:</strong>
jQuery.fn.firstChild = function(){
return this.each(function(){
var currentClass = $(this).attr('class').split(' ')[0]; //Get first class name
$(this).children(":first").addClass(currentClass + '-first-child');
});
}
$(".searchform").firstChild();
});
The great thing about setting it up that way firstChild(), hoverOn() and hoverOff() are very reusable. Now, in the CSS we can simply add the ‘nav-item-hover’ or ‘searchform-first-child’ classes as additional selectors:
It’s not pretty, but it is valid and it works. I’ve got to say, though, that I sure am looking forward to the day we won’t have to bother with this stuff!
#9 – Manage Search Box Values
A popular effect is to fill a site’s search box with a value (like ‘search…’) and then use jQuery to clear the default value when the field receives focus, reverting if the field is empty when blurred. That is easily accomplished with a couple lines of jQuery:
The disappearing back-to-top link was inspired by Brian Cray. All you have to do is add a back-to-top link at the bottom of your content like normal, and then jQuery performs the magic:
$(function(){
/* set variables locally for increased performance */
var scroll_timer,
displayed = false,
$message = $('#message a'),
$window = $(window),
top = $(document.body).children(0).position().top;
/* react to scroll event on window */
$window.scroll(function () {
window.clearTimeout(scroll_timer);
scroll_timer = window.setTimeout(function () { // use a timer for performance
if($window.scrollTop() <= top) // hide if at the top of the page
{
displayed = false;
$message.fadeOut(500);
}
else if(displayed == false) // show if scrolling down
{
displayed = true;
$message.stop(true, true).show().click(function () { $message.fadeOut(500); });
}
}, 100);
});
});
Brian also added some nice-looking CSS, which you could add as a css file or define in an object literal and apply it using jQuery.css(). Feel free to go check out his in-depth explanation if you want to learn more.
#11 – Easily Respond to Event Data
One of my favorite things about jQuery is its convenient remapping of event data, virtually eliminating cross-browser inconsitencies and making events much easier to respond to. jQuery passes an event parameter into all bound/triggered functions, which is commonly called e:
1
2
3
4
5
6
7
8
9
10
11
12
$(function() {
//We can get X/Y coordinates on click events:
$("a").click(function(<em>e</em>){
var clickX = e.pageX;
var clickY = e.pageX;
});
//Or detect which key was pressed:
$("window").keypress(function(<em>e</em>){
var keyPressed = e.which;
});
});
You can check out the jQuery docs on this one to see all the possibilites, or view this keycode reference if you’d like to look up a certain key’s character code.
#12 – Encode HTML Entities
The first place I saw this mentioned was over at Debuggable, and I have to say they really came up with something good here. The idea is to produce a jQuery result similar to PHP’s htmlentities(). Check this out:
1
2
3
4
5
6
7
8
9
$(function(){
var text = $("#someElement").text();
var text2 = "Some <code> & such to encode";
//you can define a string or get the text of an element or field
var html = $(text).html();
var html2 = $(text2).html();
//Done - html and html2 now hold the encoded values!
});
#13 – Friendly Text Resizing
Originally mentioned at ShopDev, this is an excellent way to include some user-centricity in your code (allowing them to control the font-size):
$(function(){
// Reset Font Size
var originalFontSize = $('html').css('font-size');
$(".resetFont").click(function(){
$('html').css('font-size', originalFontSize);
});
// Increase Font Size
$(".increaseFont").click(function(){
var currentFontSize = $('html').css('font-size');
var currentFontSizeNum = parseFloat(currentFontSize, 10);
var newFontSize = currentFontSizeNum*1.2;
$('html').css('font-size', newFontSize);
return false;
});
// Decrease Font Size
$(".decreaseFont").click(function(){
var currentFontSize = $('html').css('font-size');
var currentFontSizeNum = parseFloat(currentFontSize, 10);
var newFontSize = currentFontSizeNum*0.8;
$('html').css('font-size', newFontSize);
return false;
});
});
As I said, this is nice trick to know and adds some of that dynamic friendliness that people enjoy so much.
#14 – Open External Links in a New Window
This external links hack has been mentioned before at Cats Who Code, and although imperfect it’s a good way to open external links in new windows without causing validation errors in XHTML 1.0 Strict.
This works by grabbing all links with an external rel and adding a blank target. Same result, it’s just not hardcoded into the site.
#15 – Gracefully Degrading AJAX Navigation
AJAX navigation is great – but not for users and bots who can’t use it. The good news is, it’s possible to offer direct links to your content while still presenting AJAX functionality (to users who have that capability) by catching links before they go anywhere, returning false on them and loading the AJAX content instead. It could look like this:
1
2
3
4
5
6
$(function(){
$("a").bind("click",function(){
//Put your AJAX request code here
return false;
});
});
Although this is not specifically a jQuery trick, it’s useful enough to be included here. Using GET variables in Javascript code doesn’t happen everyday, but when it does you’ll want to know a quick and efficient way to read them. All we have to do is get document.location.search and do some parsing on it:
1
2
3
4
5
6
7
8
9
10
var searchArray = document.location.search.substring(1).split("&");
//Take off the '?' and split into separate queries
//Now we'll loop through searchArray and create an associative array (object literal) called GET
var GET = [];
for (searchTerm in searchArray){
searchTerm.split("="); //Divide the searchTerm into property and value
GET[searchTerm[0]] = searchTerm[1]; //Add property and value to the GET array
}
#17 – Partial Page Refresh Using load()
This excellent technique found at the Mediasoft Blog is way cool and very handy for creating a regularly updating dashboard/widget/etc. It works by using jQuery.load() to perform a AJAX request:
Voila! It works – no iframes, meta refreshes or other such nonsense.
#18 – Skin with jQuery UI
If you’re going to write any jQuery plugins (I hope you have already!), you should know that a great way to add flexibility and elegance is to incorporate jQueryUI theming classes into any widgets/visible elements your plugin produces. The great thing about doing this is that it cuts or eliminates the css you have to provide with the plugin, and it adds a lot of customizability, too (which is one of the key factors in a successful plugin).
And the actual implementation is as simple as learning how the classes work and attaching them to plugin elements. I can see this would be especially great with plugins like form beautifiers and photo sliders, making it easy to keep a consistent look throughout a website or app. You can check out the Theming Reference here.
#19 – Include Other Scripts
Stylesheet switchers are nothing new, but adding other scripts with jQuery is something that is often overlooked. The advantage is twofold:
It makes it easy to have lazy script loading.
It also allows us to add scripts at runtime, which could be useful in a whole host of situations.
It’s as easy as using append() to add a new script to the head of the document:
1
2
3
4
5
6
7
8
$(function(){
$("head").append("<script type='text/javascript' src='somescript.js'></script>");
//Or, loading only when the slow stuff is ready:
$("img,form").load(function(){
$("head").append("<script type='text/javascript' src='somescript.js'></script>");
});
});
#20 – Use Body Classes for Easy Styling
Do you want to save on code and keep your styling in the css file where it should be? Body classes (another great ideas suggested by Karl Swedberg) allow you to do that. In short, you can use jQuery to add a ‘JS’ class to the body element, which will enable you to set styles in your css that will only be applied if Javascript is enabled. For example:
This gives us a great way to change styles based on whether or not Javascript is supported/enabled, and we can still keep the styling in the CSS file. Another interesting related use of this technique is to add browser classes to the body, enabling easy browser-specific styling. You can read more about that here.
#21 – Optimize Your Performance
Experienced coders don’t make clients wait – they write code that runs fast! There are several ways you can make your code run faster like:
Reference id’s rather than classes (id selection is native and therefore quicker)
Use for instead of each()
Limit DOM manipulation by adding elements in one big chunk rather than one at a time
Link to Google’s jQuery copy rather than hosting your own – it’s faster and always up to date
Basically, it all boils down to not making jQuery do any more work than it has to (and using native abilites whenever possible). Giulio Bai wrote an excellent post on jQuery perfomance, if you’d like to dig in deeper.
#22 – Adapt Your Scripts to Work Cross-Browser – The Right Way
Thankfully, jQuery’s cross-browser compatibility really cuts down the need for browser hacks. Sometimes, though, it is good to be able to get information about the client, and we can do that cleanly and unobtrusively with jQuery.support:
1
2
3
4
5
//Does this client follow the W3C box model?
var boxModel = $.support.boxModel;
//Does this client support 'opacity'?
var opacity = $.support.opacity;
It’s definitely better practice to use feature-detection rather than browser sniffing, and this is a very efficient way to do it. Read more about jQuery.support’s properties here.
#23 – Configure jQuery to be Compatible with Other Libraries
We all find ourselves in situations where multiple libraries are needed, and because jQuery isn’t the only library that uses the $ alias, compatiblity issues sometimes pop up. Thankfully, this is easy to fix using jQuery’s noConflict(). You can even define a custom alias to replace the $:
1
2
3
4
var $j = jQuery.noConflict();
//Now you can use '$j' just like '$'
$j("div").hide();
An alternate technique is to wrap jQuery calls in an anonymous function and pass jQuery in as a parameter. Then you can use whatever alias you want, including the ‘$’. This is especially useful for plugin authoring:
1
2
3
4
5
(function($){
$(document).ready(function(){
//You can use normal jQuery syntax here
});
})(jQuery);
#24 – Efficiently Store Element-Specific Information with data()
data() is probably one of the lesser used jQuery methods, although it certainly shouldn’t be. It allows us to attach/retrieve as much data as we want to DOM elements without misusing attributes, and is especially useful for more complex scripts. For example, Stefan Petre’s Colorpicker plugin uses data a lot because it’s tracking lots of fields and colors, converting rgb to hex, etc. Here’s are some examples of how data() works:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$(document).ready(function() {
//Set status to 'unsaved'
$("button:first").data("status", "unsaved");
//Retrieve status
var buttonStatus = $("button:first").data("status");
//Change status, this time defining an object literal
$("button:first").data("status", {saved : true, index : 1});
//Retrieve status of index property
var buttonStatusIndex = $("button:first").data("status").index;
//Remove status data
$("button:first").removeData("status");
});
I’m sure you can imagine the huge extent of possibilities this presents. Again, it’s worth reading the documentation if you haven’t used data() before.
#25 – Extend/Modify Existing jQuery Functions
Nobody says you can’t use the existing jQuery platform as a springboard for new ideas – and many have done just that using extend(), another wonderful jQuery method. The popular Easing plugin, for example, adds some animation variety by extending the easing object, an already existing object that is passed to animate() and others:
By extending and improving jQuery’s default functionality, you can open up a whole new world of cool possibilities.
#26 – Reverse Engineer before() and after()
I always appreciated how jQuery provided append()/prepend() and appendTo()/prependTo(), enabling us to easily perform an append in either direction. I’ve wished, though, that a similar ability was provided with before() and after(). To change that, we can easily add two functions called putBefore() and putAfter() that will fulfill that purpose. Here’s how:
I’m sure we all have found ourselves in this situation – needing to know if an element is a descendant of another element. The good news is, with one line of code we can extend jQuery to allow this:
1
2
3
4
5
6
7
8
$(function(){
jQuery.fn.isChildOf = function(b){return (this.parents(b).length > 0);};
//Now we can evaluate like this:
if ( $("li").isChildOf("ul") ){
//Obviously, the li is a child of the ul so this code is executed
}
});
This is another one that has been talked about a lot in the development community, so you may have this already figured out. If not, get ready because this will open some whole new windows for jQuery efficiency. The short story is, jQuery allows us to extend its expression object, which means we can add whatever custom selectors we want. For example, say we wanted to add a selector version of the isChildOf() method we wrote earlier:
1
2
3
4
5
6
7
8
9
10
$(function(){
jQuery.extend(jQuery.expr[':'], {
'child-of' : function(a,b,c) {
return (jQuery(a).parents(c[3]).length > 0);
}
});
//'child-of' is now a valid selector:
$("li:child-of(ul.test)").css("background","#000");
});
Debuggable has a great post on this one as well, if you’d like to read more about how the parameters work, etc.
#29 – Smooth Scrolling Without Plugin
Karl Swedberg posted this one a while back on the Learning jQuery site, and it is definitely worth a look. Of course, there are a couple of plugins to accomplish this (and they have more features), but I think the real value in this is the excercise of doing it yourself. Plus, look at how tiny it is:
jQuery tabs are often covered but also often used, and like the scrolling trick above it’s important to know how to do these without a plugin. The first thing to do is write our markup, which should be perfectly presentable in the absence of Javascript:
As you can see, there are infinite opportunities for amazing innovation with jQuery. So keep experimenting, keep trying things, keep thinking, “What if?” You could be the next jQuery supergeek!
WITH cte_name ( column_name [,...n] )
AS
(
CTE_query_definition –- Anchor member is defined.
)
使用示例
1. 查询临时结果集
WITH cte(CategoryID,CategoryName,ParentID,CategoryLevel)
AS (
SELECT CategoryID
,CategoryName
,ParentID
,CategoryLevel
FROM Category(NOLOCK)
WHERE Status = 1 and parentid = 23
)
select * from cte;
WITH cte(CategoryID ,CategoryName,ParentID,CategoryLevel)
AS (
SELECT CategoryID
,CategoryName
,ParentID
,CategoryLevel
FROM Category(NOLOCK)
WHERE Status= 1 and parentid in (21,22,23,25,26)
UNION ALL
SELECT t.CategoryID
,t.CategoryName
,t.ParentID
,t.CategoryLevel
FROM Category(NOLOCK) AS t
INNER JOIN cte AS c ON t.parentid = c.CategoryID where Status= 1
)
select * from cte;
3. cte结果集和数据表关联
WITH cte(CategoryID,CategoryName,ParentID,CategoryLevel)
AS (
SELECT CategoryID
,CategoryName
,ParentID
,CategoryLevel
FROM Category(NOLOCK)
WHERE Status = 1 and parentid = 23
)
select p.ProductId,p.ProductName,c.CategoryID,c.CategoryName,c.CategoryLevel
from product p(NOLOCK)
inner join cte c(NOLOCK) on p.CategoryId=c.CategoryID