views:

141

answers:

4

html

<div contentEditable="true">testing....</div>

jQuery

$(document).ready(function(){
   $('[contenteditable]').removeAttr('contenteditable');
});

above codes is fine and working. you can feel it here.

Now, try this

$('[contentEditable]').removeAttr('contentEditable'); 
// notice the CamelCase of the string contentEditable

in FF 3.6, it gives an error on the console

An invalid or illegal string was specified" code: "12
elem[ name ] = value;

and the div is still editable.

I suspected it was the jQuery selector, but is not. By further inspection, it was the argument passed on the .removeAttr('contentEditable');. It works when all small letters. So, I thought it should be all small letters. I'm curious so I tried adding CLass as an attribute and do .removeAttr('CLass');. But then it works without error.

So, how come contentEditable is giving me that error?


update

from Kobi, it seems that it actually accept any case except, contentEditable (I did try too).

CamelCase

+2  A: 

This isn't about small letters, but about the exact casing. Any other casing than contentEditable works, for example: removeAttr('ConTentEditable');.
I can't find the exact source of the problem, I guess it's a Firefox restriction.

It seems jQuery sets the attribute to an empty string before removing it, which is what's causing the error. This seems to work better:

$('[contentEditable]').attr('contentEditable', false);
Kobi
+2  A: 

You could call it a bug, but really the framework is designed this way. removeAttr, along with other attr functions, points to jQuery.attr() to set the attribute's value. After setting the attribute to "", it then attempts to remove it. The code for attr() specifically checks to see if the given string is a property name on the object first using the in operator:

// If applicable, access the attribute via the DOM 0 way
if ( name in elem && notxml && !special ) {

(from jQuery 1.4, line 1452-1453)

Since you're supplying the camelCase property name, it uses that instead of elem.setAttribute(), which is specifically the cause of the problem. For any other case, name in elem would return false (because property names are case sensitive), which is why it's successful then. jQuery does this mostly to work around cross browser issues with setAttribute().

It looks like Firefox has a problem with setting the property to an empty string, unless you have the same problem in other browsers. You could try and file a bug either on the jQuery site or MDC.

Andy E
+1. Because of traditional IE bugs, jQuery's `attr` functions try to hide the difference between an HTML attribute (`contenteditable`) and a DOM property (`contentEditable`). With confusing results, as usual when you try to hide an important difference.
bobince
A: 

contentEditable seams to be a special attribute: http://www.whatwg.org/specs/web-apps/current-work/multipage/editing.html#contenteditable

JochenJung
A: 

The contentEditable property (not attribute, since that isn't what attr() and friends usually deal with) expects a string value, one of "true", "false" and "inherit". I wouldn't use jQuery to turn off contentEditable, but I imagine the following would work:

$('[contenteditable]').attr("contentEditable", "false");

Or you could bypass jQuery for setting the actual contentEditable property:

$('[contenteditable]').each(function() {
    this.contentEditable = "false";
});
Tim Down