最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - detect underline and strike through - Stack Overflow

programmeradmin1浏览0评论

Is there any way to detect with JavaScript/jQuery if an element is strike-through and underlined.

So let's say we have:

<u><s>text here.</s>other text here.</u>

Is it possible to detect if the text within <s> is also underlined?

*Ideally, it would not be allowed to look if <u> has any <s> children.

I've been toying around with it and it seems peculiar that both styles use the same CSS property, which in turn makes me wonder how it even works in the first place.

To make my problem clearer:

I'm playing around with a self-made wysiwyg editor, for usability reasons I'm trying to implement a listener on the text which alters (lights up) editing buttons. e.g. when a part of text is bold the "B" button changes to an active state. I'm currently handling this by getting the element at the cursor and checking if the element is bold or inherits it.

The problem with underline and striketrough is that they are neither overwriting the text-decoration attribute of each other, and are not visible in css

when I put the cursor on a underlined text-fragment, the text-decoration property only shows as underline, while the text is both underline and line-through. In such situations I cannot know what the exact relation is between the <u> element and the <s> element; the <s> element could be 100 parents back as far as I could know.

A lot of text, but I hope it kinda clears up my situation.

Is there any way to detect with JavaScript/jQuery if an element is strike-through and underlined.

So let's say we have:

<u><s>text here.</s>other text here.</u>

Is it possible to detect if the text within <s> is also underlined?

*Ideally, it would not be allowed to look if <u> has any <s> children.

I've been toying around with it and it seems peculiar that both styles use the same CSS property, which in turn makes me wonder how it even works in the first place.

To make my problem clearer:

I'm playing around with a self-made wysiwyg editor, for usability reasons I'm trying to implement a listener on the text which alters (lights up) editing buttons. e.g. when a part of text is bold the "B" button changes to an active state. I'm currently handling this by getting the element at the cursor and checking if the element is bold or inherits it.

The problem with underline and striketrough is that they are neither overwriting the text-decoration attribute of each other, and are not visible in css

when I put the cursor on a underlined text-fragment, the text-decoration property only shows as underline, while the text is both underline and line-through. In such situations I cannot know what the exact relation is between the <u> element and the <s> element; the <s> element could be 100 parents back as far as I could know.

A lot of text, but I hope it kinda clears up my situation.

Share Improve this question edited Oct 19, 2014 at 23:20 David Thomas 254k53 gold badges381 silver badges419 bronze badges asked Oct 19, 2014 at 22:34 RebirthRebirth 1,0118 silver badges14 bronze badges 5
  • You can insert it in any invisible element and check for $('u s').length in it – Cheery Commented Oct 19, 2014 at 22:37
  • what if the bination is <s><u></u></s> or even something like <s><div><u></u></div><p><u></u></p></s> (just to cover my bases). – Rebirth Commented Oct 19, 2014 at 22:39
  • @Rebirth Check my answer. It works even if style is provided through CSS. – redV Commented Oct 19, 2014 at 23:00
  • @Rebirth can you just walk all over the parents and check their text-decorations? – Cheery Commented Oct 19, 2014 at 23:10
  • I probably could but I'm not sure that's a smart move with R posibilities – Rebirth Commented Oct 19, 2014 at 23:12
Add a ment  | 

3 Answers 3

Reset to default 5

Here is the robust way of doing it. @Cheery answer works well but it fails if italic or underline or any other font-style provided through CSS. Credit is given to Tim Down for his numerous answers for these kind of questions.

 function checkState(element, check) {
    var doc = document;
    var text = doc.getElementById(element);

    if (doc.body.createTextRange) { // ms
        var range = doc.body.createTextRange();
        range.moveToElementText(text);
        range.select();
    } else if (window.getSelection) { // moz, opera, webkit
        var selection = window.getSelection();
        var range = doc.createRange();
        range.selectNodeContents(text);
        selection.removeAllRanges();
        selection.addRange(range);
    }

    var range, checked = false;
    if (window.getSelection) {
        var sel = window.getSelection();
        if (sel && sel.getRangeAt && sel.rangeCount) {
            range = sel.getRangeAt(0);
            document.designMode = "on";
            sel.removeAllRanges();
            sel.addRange(range);
        }
    }
    if (document.queryCommandState) {
        checked = document.queryCommandState(check);
    }
    if (document.designMode == "on") {
        document.designMode = "off";
    }
    if (window.getSelection) {
        if (window.getSelection().empty) { // Chrome
            window.getSelection().empty();
        } else if (window.getSelection().removeAllRanges) { // Firefox
            window.getSelection().removeAllRanges();
        }
    } else if (document.selection) { // IE?
        document.selection.empty();
    }
    return checked;
}

alert(checkState('c', 'underline')); // italic, bold etc..
var str = '<u><s>text here.</s>other text here.</u>';
var el = $('<div>').html(str);
alert($('u s', el).length);

what if the bination is or even something like

so what, check inverse too..

var str = '<s><div><u></u></div><p><u></u></p></s>';
var el = $('<div>').html(str);
alert($('u s', el).length || $('s u', el).length);

if the initial string is not a valid html then you do not know how some browsers will behave at its output.

ps: made some simple example, by click..

$(function(){
  $('.wrapper').on('click', '*', function() {
  var styles = ['line-through', 'underline'], counter = [0, 0], tags = ['S', 'U'];
  $(this).parentsUntil('.wrapper').andSelf().each(function() {
    var current = $(this).css('text-decoration'), $tag = $(this)[0];
    $.each(styles, function(index, style) {
        if (current.indexOf(style) > -1 || $tag.tagName == tags[index]) counter[index] += 1;
    });
  });
  var results = [];
  if (counter[0] > 0) results.push('striked');
  if (counter[1] > 0) results.push('underlined');
  alert(results.join(' and '));
  return false;
});
});
.strike {
    text-decoration: line-through;
}

.underline {
    text-decoration: underline;
}
<script src="https://ajax.googleapis./ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<div class='wrapper'>
<div class='strike'>
    striked <u>underlined</u>
</div>

<div class='underline'>
    underlined <s>striked</s>
</div>
</div>

A somewhat horrible approach, but the only way I could see that doesn't involve explicitly checking nesting, or relying on default CSS surviving any theming (<s> won't always, necessarily, have text-decoration: line-through;, similarly <u> won't always, necessarily, have text-decoration: underline;):

// the text-decoration styles you want to find:
var styles = ['line-through', 'underline'];

// finding all elements within the <body>, and
// filtering them:
var underlinedAndLineThrough = $('body *').filter(function() {
    // caching because of re-use:
    var self = $(this),
        decor = self.css('text-decoration');

    // if the 'text-decoration' style is found in the array of styles we're
    // looking for:
    if (styles.indexOf(decor) > -1) {
        // we add that style as a class-name to the current element, and all
        // descendants:
        self.find('*').add(self).addClass(decor);
        // we return the current element (to keep it in the collection):
        return self;
    }
// filtering again:
}).filter(function(){
    // we keep the current element of the collection if it has all the css styles
    // we're looking for:
    return $(this).is('.' + styles.join('.'));
});

console.log(underlinedAndLineThrough);

JS Fiddle demo.

References:

  • JavaScript:
    • Array.prototype.indexOf().
    • Array.prototype.join().
  • jQuery:
    • add().
    • addClass().
    • filter().
    • find().
    • is().
发布评论

评论列表(0)

  1. 暂无评论