views:

123

answers:

2

Is it possible to change the contents of elements when they, or a part of the text within them, is selected then reverting them back when they are deselected?

The aim being that when they are copied to the clipboard the alternate value is copied.

The html looking something like this:

<p>Today is the <span class="date" value="18/03/2009">18th of March</span>.</p>
+1  A: 

UPDATED: using hover instead (per Scott E. comment)

I like JQUERY and below is a way, albeit not perfect, but should get you started down the path. The reason that its not perfect is because there is a "fluttering" if you mouseover and out on the right side (interestingly) of the span.

Note this is fully functional, but you should get local version of the JQUERY js. Also, after posting this the first time, I discovered I/E does not behave as expected.

See http://docs.jquery.com/Events and http://docs.jquery.com/Core

<html>
  <body>
    <p>Today is the <span class="date"/></p>
  </body>
</html>



<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"&gt;&lt;/script&gt;
<script type="text/javascript">

  $(document).ready(function(){

    // use data object of <span> element with class 'date'.
    // Do this instead of using "value" attribute in <span>
    // which is not normal part of <span> element
    // instead of putting the value directly in <span> above, I'm assigning it here

    $(".date").data("mydates", { selected : "18/03/2009", normal: "18th of March" } );

    // assign the normal value on startup
    $(".date").html($(".date").data("mydates").normal);

    // first function is executed on mouseover
    // second function is executed on mouseout
    $(".date").hover(
        function() {
      $(".date").html($(".date").data("mydates").selected);
        },
        function() {
         $(".date").html($(".date").data("mydates").normal);
        }
    );

  });
</script>
Dan
Just an FYI- the double bind of mouseenter and mouseleave is more easily handled by jquery's hover() function
Scott Evernden
Thanks Scott, other thing I found out was that this is flunky on IE.
Dan
Interesting solution, I'm just about to post my solution that I came up with. On problem with your answer is that if you select the date with other text and copy it you end up copying the 'normal' date. It's a good way to allow people to view an alternate format but a title may be better for that.
Annan
A: 

A solution that I came up with is as follows.

HTML:

<p>Semper mi vitae tellus <span class="date" title="19/03/09" data="19th of March">19th of March</span> quis, augue.</p>

CSS:

.date {
    display:inline-block;
    text-align:center;
}

This stops the text from jumping around when the content is replaced.

Javascript:

var travel = function(node, noChildren){
    if (node.firstChild && !noChildren) {
     return node.firstChild;
    }
    if (node.nextSibling) {
     return node.nextSibling;
    }
    return travel(node.parentNode, true);
};

var onMouseDown = function(event){
    var spans = document.getElementsByClassName(revertClass);
    var i = spans.length;
    while (i) {
     i--;
     spans[i].innerHTML = spans[i].getAttribute('data');
     spans[i].className = window.baseClass;
    }

    var selection = window.getSelection();
    if (selection.rangeCount && event.button === 2){
     var n = selection.rangeCount;
     var k = n;
     do {
      var i = k-n;
      var range = selection.getRangeAt(i);

      var element = range.startContainer;
      var endContainer = range.endContainer;
      do {
       if (element.className === window.baseClass){
        element.style.width = element.offsetWidth;
        element.innerHTML = element.title;
        element.className += ' ' + window.revertClass;
       }
       if (element == endContainer){
        break;
       }
      }
      while (element = travel(element));

      var newRange = document.createRange();
      newRange.setStart(range.startContainer, range.startOffset);
      newRange.setEnd(range.endContainer, range.endOffset);

      selection.removeRange(range);
      selection.addRange(newRange);
     }
     while (--n);
    }
};

var onKeyDown = function(event){
    //Ctrl + C
    if (event.keyCode === 67 && event.ctrlKey){
     event.button = 2;
     onMouseDown(event);
    }
    //Tab to deselect
    else if (event.keyCode === 9){
     onMouseDown(event);
    }
};

window.baseClass = 'date';
window.revertClass = 'date_revert';
window.addEventListener ('mousedown', onMouseDown, false);
window.addEventListener ('keydown', onKeyDown, false);

I purposely didn't use jquery as I'm planning on using this in a greasemonkey script and loading it on every page would slow things down (I think?). I had it working with it automatically changing on selection by binding mousemove after mousedown fired but it ended up being very slow so I decided it was best to focus on my goal of changing what was copied.

About the usage of non standard attributes, I've never found this to be a problem? I'm using title so that people can see the alternative format without copying it and data because it seemed logical.

Annan