简体   繁体   中英

Styling contentEditable lists (<li>) with font-family, font-size, and color

I'm looking for a way to style lists so that they will use formatting set by the user while editing within a contentEditable element. Specifically, I want to be able to style the number/bullet in the same manner as the rest of the <li> content.

From the testing I've done, the browser never styles <li> tags directly (which actually controls the style of the number/bullet) but always places a <font> tag (or <span> if StyleWithCSS ) as the first child node, using it for the formatting. I've tried a few ideas already to get around this, but have not found success:

1. Apply styles to the <li> programmatically

Here I tried listening for 'DOMNodeInserted' and when an <li> tag was inserted into the DOM, I queried the current fontName , fontSize , and foreColor commands and applied them as an inline style on the <li> .

textarea.addEventListener('DOMNodeInserted', function (evt) {
    if (evt.target.nodeName === 'LI') {
        evt.target.style.color = queryCommandValue('foreColor');
        evt.target.style.fontFamily = queryCommandValue('fontName');
        evt.target.style.fontSize = queryCommandValue('fontSize');
    }
}, false);

Even when doing this, as soon as you begin typing in the list item, the browser tries to be "smart" and strips the styles from the <li> , placing them into a <font> (or <span> ) tag. :(

2. Create a rule for the styles to be inserted into the StyleSheet

Based off the attempt above, instead of writing the styles inline, I created a rule for them, gave the <li> node an ID, and inserted the rule into the stylesheet. Now the rule would govern the style of the <li> , and I could use the CSSOM to continually update any particular <li> 's styles.

This seemed to work very well (with a few bugs to solve for), however, it completely breaks the contentEditable undo stack. Since the undo command is only tied to textContent and other formatting commands, there is no way to "undo" the styles you are setting in the stylesheet. (At least not very intuitively, I've thought about how this might be done...)

3. Watch for changes in the <li> 's attributes and retain them

For this attempt, I made use of the newly-available MutationObserver http://www.w3.org/TR/dom/#mutationobserver available in DOM level 4. This observer can watch for changes in a node's attributes, which will be passed back in a MutationRecord. It can even hold the previous attribute values, including style values, so I could find out what was being removed and re-apply it.

var observer = new WebKitMutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
        if (mutation.target.nodeName === 'LI') {
            ...
        }
    })
});

observer.observe(document, {
    attributes: true,
    subtree: true,
    attributeOldValue: true
});

This still suffers from lack of undo support. You will undo other formatting changes but the <li> s will keep their styles.

Any novel ideas out there? Modern-browser only solutions welcomed as well. I'm aware that I could format my own HTML to use for lists but I'm trying to see if this can be done using the standard insertOrderedList and insertUnorderedList commands which use real list tags.

** Update Nov 7 2012 **

Doesn't look like anyone has solved this yet, here is an example JSFiddle to see what I'm describing: http://jsfiddle.net/8LyZR/ . Just try to change the styles of bulleted or numbered lists.

For the project I am working on, we are using our own build of WebKit so we were able to fix this with a native change but I'm hoping there is a way (or will be a way) to do this directly with HTML/CSS/JS.

Here's some interesting CSS trickery. http://jsfiddle.net/GZ3cv/

It basically relies on placing a psuedo-element :before on the inline tags, (which will inhereit the styles), and then attempting to position it on top of the original list bullets/numbers.

I can't decide if I would call this a solution, as it could grow impractical with all the different combinations of nested/inline tags (font,u,b,span,i).

But just playing around with font, size, color, and the list-type controls it seems like it could mimic what you are looking for with some obvious thorough tweaking involved.

I'm curious if this technique is plausible or just ridiculous :) Just throwin it out there..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM