代码改变世界

Fw:Preventing Users From Copying Text From and Pasting It Into TextBoxes

2010-07-16 16:45  Tracy.  阅读(541)  评论(0编辑  收藏  举报

Introduction
Many websites that support user accounts require users to enter an email address as part of the registration process. This email address is then used as the primary communication channel with the user. For instance, if the user forgets her password a new one can be generated and emailed to the address on file. But what if, when registering, a user enters an incorrect email address? Perhaps the user meant to enter me@example.com, but accidentally transposed the first two letters, entering em@example.com. How can such typos be prevented?

The only foolproof way to ensure that the user's entered email address is valid is to send them a validation email upon registering that includes a link that, when visited, activates their account. (This technique is discussed in detail in Examining ASP.NET's Membership, Roles, and Profile - Part 11.) The downside to using a validation email is that it adds one more step to the registration process, which will cause some people to bail out on the registration process. A simpler approach to lessening email entry errors is to have the user enter their email address twice, just like how most registration forms prompt users to enter their password twice. In fact, you may have seen registration pages that do just this. However, when I encounter such a registration page I usually avoid entering the email address twice, but instead enter it once and then copy and paste it from the first textbox into the second. This behavior circumvents the purpose of the two textboxes - any typo entered into the first textbox will be copied into the second.

Using a bit of JavaScript it is possible to prevent most users from copying text from one textbox and pasting it into another, thereby requiring the user to type their email address into both textboxes. This article shows how to disable cut and paste between textboxes on a web page using the free jQuery library. Read on to learn more!

 

Copy, Cut, and Paste Events in JavaScript
Much like ASP.NET, JavaScript code is typically event-driven, meaning that certain blocks of JavaScript execute in response to particular events. For example, you can run a block of script when the web page loads, when a form is submitted, or when an HTML element is clicked. If you are not familiar with JavaScript's event model, check out Introduction to Events, which gives a great overview of how event handling works in JavaScript.

JavaScript includes events that fire when the user attempts to copy, cut, or paste from within the browser window: copy, cut, and paste. What's more, by creating an event handler for these events you can write script that cancels the default behavior, meaning that with just a few lines of JavaScript you can "turn off" copying, cutting, and/or pasting behavior from within the browser. The copy, cut, and paste events are supported in most modern browsers, including Internet Explorer 5.5 and up, Firefox 3.0 and up, Safari 3.0 and up, and Chrome, although the support differs a bit between the various browsers. For instance, Firefox, Safari, and Chrome will fire the copy, cut, and paste events if the user copies, cuts, or pastes, anywhere in the document, but Internet Explorer only fires these events if the copy, paste, and cut occurs within a form, on an HTML element, within a text input, or on an image. (For more information on the browser compatibility for these events, refer to the cut, copy, paste Event Compatibility Matrix.)

Should You Disable Copy, Cut, or Paste Behavior?
As this article shows, most modern browsers provide the ability for a web page developer to disable copying, cutting, and/or pasting from within a web page. When considering whether to use this functionality there are two things worth keeping in mind:
  1. You cannot truly prevent someone from copying, cutting, or pasting. The techniques we'll examine in this article show how to use JavaScript to put up a roadblock to copying, cutting, and pasting. However, a determined user could disable JavaScript in their browser, at which point the JavaScript you've written to prevent copying, cutting, and pasting is moot.
  2. Preventing copying, cutting, and pasting can lead to a jarring and frustrating user experience. No matter what car you get into, when you turn the key you expect the to start. Imagine how frustrated you would become if you rented a car, hopped in, turned the key, and nothing happened. The same sentiment exists for computer user interfaces. Users expect certain functionality to be available when they sit down at a keyboard. They expect Ctrl+C to copy the selected contents to the clipboard, and Ctrl+V to paste. Disabling these comfortable and well-known idioms can unnerve users.
For these reasons, I would only recommend disabling copy and paste operations in specific circumstances where the benefits outweigh the negatives. Furthermore, I'd suggest giving users some sort of obvious and visual feedback when they attempt to copy or paste so that they understand these operations have been disabled and that it's not some software bug or hardware failure at play.

 

Using jQuery to Disable Copy and Paste
jQuery is a free, popular, open-source JavaScript library that simplifies accessing and working with HTML elements in a web page. jQuery is included with Visual Studio 2010; when you create a new ASP.NET website or project using the ASP.NET Web Site Template or the ASP.NET Web Application Template, Visual Studio 2010 adds a Scripts folder that includes the jQuery script files. (Of course, you can always get the latest version of jQuery from jQuery.com.) Let's look at a couple of examples that show how to use jQuery to disable copying and pasting.

Before we look at the examples, first make sure that you are properly including the jQuery library in your project. This is done by adding a <script> element to the <head> section that references the jQuery script file. If you have the jQuery script file jquery-1.4.2.min.js in the Scripts folder you could add the following markup to the section:

<script type="text/javascript" src='<%=Page.ResolveClientUrl("~/Scripts/jquery-1.4.2.min.js") %>'></script>

 

Alternatively, you could directly reference the jQuery file directly from jQuery.com or from Google's CDN or Microsoft's CDN. For instance, to reference the jQuery library directly from jQuery.com we could use the following <script> element in the <head> section:

<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.min.js"></script>

 

Once the jQuery library has been referenced, add the following block of code to the <head> portion of an ASP.NET page that contains one or more TextBoxes. This jQuery code creates an event handler for the copy and paste events for all textboxes on the page. The event handler calls the preventDefault function, which cancels the events default behavior, namely stopping the copy or paste logic from occurring. With the below script in place, you will not be able to copy text from any textbox or paste text into any textbox on the page.

<script type="text/javascript">
   $(document).ready(function () {
      $('input[type=text]').bind('copy paste', function (e) {
         e.preventDefault();
      });
   });
</script>

 

Before we move onto the next example, let's take a quick moment to examine the syntax here. The $(document).ready part defines a function that executes once the page has loaded. The $('input[type=text]') syntax is an example of a jQuery selector. A selector is syntax that references one or more elements on the page. This selector syntax references all <input> elements that have their type attribute equal to "text". The next part, bind('copy paste', function(e) { ... }), creates an event handler for the copy and paste events on each of the elements returned by the selector (namely, all textboxes). When the event fires, the code inside the function executes, calling the preventDefault function and canceling the copy or paste action.

The next example shows how to use jQuery to prevent pasting text into a particular textbox.

<script type="text/javascript">
   $(document).ready(function () {
      $('#id_of_textbox').bind('paste', function (e) {
         e.preventDefault();
         alert("You cannot paste text into this textbox!");
      });
   });
</script>

 

The syntax is similar to the example above, but instead of selecting all textboxes, a particular textbox is selected using the selector syntax $('#id_of_textbox'). Here, id_of_textbox is the id of a particular textbox on the page. For example, if the rendered HTML included a textbox with markup like:

<input name="email" type="text" id="email" />

 

The value of id_of_textbox to use would be "email". Also note that instead of creating event handlers for both the copy and paste events, this example creates an event handler only for the paste event. Also, the event handler has been updated to include a call to the alert function, which displays a modal dialog box explaining to the user that they cannot paste text into the textbox. The following screen shot shows this sample in action when a user attempts to paste text into the Confirm Email textbox. (This presumes that the id attribute of the Confirm Email textbox is used as the value of id_of_textbox in the selector.)

 

A dialog box informs the user that they cannot paste into a textbox.

Putting It Altogether - Prohibiting Copying and Pasting in an Account Registration Form
Now that we have covered the basics of how to stop copying and pasting in a web page using jQuery, let's turn our attention to a working example in ASP.NET. I created a simple registration page that uses the standard ASP.NET Web Forms model to create the user interface, which can be downloaded at the end of this article. There are three TextBox controls on the page - one for the new user's user name, one for his email address, and one to confirm his email address - along with a "Register" Button Web control. Our goal with this page is to prevent the user from copying text from the Email textbox and pasting text into the Confirm Email textbox. (In reality, we could just focus on prohibiting pasting into the Confirm Email textbox, as there really is no reason why we would need to stop the user from copying text from the Email textbox into the clipboard.)

One challenge of using ASP.NET's Web Forms model is that when the Web controls on the page are rendered into HTML their server-side ID value might have additional text prepended to it, depending on whether the control is within a naming container. For example, if you are using Master Pages then any Web controls in the content page will have their server-side ID property values rendered into an HTML id attribute that contains the ID values of the Content control and the Master Page. Specifically, you might have a TextBox whose ID is set to txtEmail, but, when rendered, generates HTML with a client-side id value of ctl00_ContentPlaceHolder1_txtEmail. (Starting with ASP.NET 4, Web Forms developers have more control over how the server-side ID value gets rendered into a client-side id value; see Take Control Of Web Control ClientID Values in ASP.NET 4 for more information.)

The good news is that it is possible to programmatically determine how the server-side ID will be rendered into a client-side id - use the ClientID property. When writing a jQuery selector that references an ASP.NET Web control by its rendered id value, then, do so using the following syntax: $('#<%=<i>WebControlID</i>.ClientID %>).

The following script shows how to use jQuery to disable copy operations on the txtEmail TextBox and how to disable paste operations on the txtConfirmEmail TextBox.

<script type="text/javascript">
   $(document).ready(function () {
      $('#<%=txtEmail.ClientID%>').bind('copy', function (e) {
         e.preventDefault();
      });


      $('#<%=txtConfirmEmail.ClientID%>').bind('paste', function (e) {
         e.preventDefault();
      });
   });
</script>

 

That's all there is to it! With just that sprinkle of JavaScript, we have effectively prevented the user from copying text from the Email textbox and pasting it into the Confirm Email textbox.

The demo available for download at the end of this article adds a bit of flair to the copy and paste event handlers in order to give the user feedback that copying and pasting are disabled for these elements. Specifically, I added a <div> to the page with an id of message and CSS rules that initially hide the <div> from view. When a user attempts to copy or paste, this <div>'s text is set to an appropriate message, it is positioned to the right of the textbox, and is faded in over the course of three seconds, after which it fades out over the course of 1.5 seconds. The jQuery to achieve this follows:

<script type="text/javascript">
   $(document).ready(function () {
      $('#<%=txtEmail.ClientID%>').bind('copy', function (e) {
         e.preventDefault();

         $('#message').text("You cannot copy the text from this textbox...")
                      .css(
                        {
                           left: 20 + $(this).offset().left + $(this).width() + 'px',
                           top: $(this).offset().top + 'px'
                        })
                      .fadeIn(3000, function () { $(this).fadeOut(1500) });
      });


      ...
   });
</script>

 

The following screen shot shows how this message appears when a user attempts to paste text into the Confirm Email textbox (although it does not illustrate the cool fade in/fade out effects).

 

A message informs the user that they cannot paste into the textbox.