-1

I'm using the following code to create fractions:

<script type='text/javascript'>
$(document).ready(function () {
$('.fraction').each(function(key, value) {
    $this = $(this)
    var split = $this.html().split("/")
    if( split.length == 2 ){
       $this.html('<span class="top">'+split[0]+'</span><span class="bottom">'+split[1]+'</span>')
}    
});
});
</script>

If I have the following code in my body, it successfully formats as a fraction:

<span class="fraction">4/1</span>

If, however, I include a tag, as illustrated below, the function no longer works

<span class="fraction"><strike>4</strike>/1</span>

How can I fix this? Thanks!

J Doe Math
  • 31
  • 5
  • 5
    because the tag has a "/" – epascarello Apr 28 '16 at 01:16
  • Specifically your split call would return an array of length 3 and so the if below it will evaluate to false – karina Apr 28 '16 at 01:21
  • Do you have any recommendations regarding how I can fix this in the code? I don't know how to modify the fraction code to account for this. – J Doe Math Apr 28 '16 at 01:21
  • I'm thinking that it might be possible to write an if condition to state that if the / occurs within a tag, it should be ignored, but I don't have the skill level to begin to tackle this. – J Doe Math Apr 28 '16 at 01:23
  • 5
    `$this.html()` -> `$this.text()`? – Amadan Apr 28 '16 at 01:24
  • Depends how flexible you want to get. Maybe have a `if length == 3` part as well? Can you have more tags in there? Also, I guess you need to preserve the `strike` in the output? – Thilo Apr 28 '16 at 01:24
  • @Amadan: Good call. But they probably want to preserve the `strike` tag in the output. Or maybe not? – Thilo Apr 28 '16 at 01:26
  • Possible duplicate of [Using regular expressions to parse HTML: why not?](http://stackoverflow.com/questions/590747/using-regular-expressions-to-parse-html-why-not) –  Apr 28 '16 at 01:31
  • 1
    `` is an element not supported in HTML5, use `` or ``...These elements will put a line right thru that 4. It won't look like `4/1`. – zer00ne Apr 28 '16 at 01:35
  • Changing $this.html() -> $this.text() doesn't help, unfortunately. The tag still invalidates the fraction format. – J Doe Math Apr 28 '16 at 01:35
  • `` is HTML4 if you are asking jQuery to parse a string as if is HTML, perhaps you should use valid tags. See my last comment. – zer00ne Apr 28 '16 at 01:43
  • @JDoeMath It works for me. See this [JSFiddle](https://jsfiddle.net/mtvct215/). – 4castle Apr 28 '16 at 01:48
  • 1
    @JDoeMath i have a question. why are you doing this in javascript? basically do you have control over the page before it is served up? or are you scraping some other page you have no control over? – karina Apr 28 '16 at 02:04

2 Answers2

4

Use .text() to strip away the html tags and just get the text.

var split = $this.text().split("/")

JSFiddle

If you want to keep the html markup in your result, an easy solution would be to use a different delimiter for your fraction, like a double slash //, a backslash \, or a pipe |. JSFiddle

Using this answer you could also use regex to verify that it only splits if the character isn't found inside <..>. JSFiddle

var split = $this.html().split(/\/(?=[^>]*(?:<|$))/)
Community
  • 1
  • 1
4castle
  • 32,613
  • 11
  • 69
  • 106
  • The alternative delimiter solution is perfect - thanks! – J Doe Math Apr 28 '16 at 02:33
  • If you control the server-side enough to change to an alternative delimiter, why not just output the HTML you actually want directly (without the Javascript post-processing on the client)? – Thilo Apr 28 '16 at 04:48
1

If you want to do it correctly (while preserving your markup), it gets a bit complicated due to the fact that you need a slash that is in a text node that is a direct child of the .fraction element; and jQuery doesn't deal with text nodes well. So:

$(function() {
  $('.fraction').each(function(_, e) {
    var offset = 0, html = '<span class="top">', found = false;
    $.each(e.childNodes, function(_, c) {
      if (c.nodeType == Node.TEXT_NODE) {
        if (m = c.textContent.match(/(.*)\/(.*)/)) {
          found = true;
          html += m[1] + '</span>/<span class="bottom">' + m[2];
        } else {
          html += c.textContent;
        }
      } else {
        html += c.outerHTML;
      };
    });
    if (found) {
      e.innerHTML = html + '</span>';
    }
  });
});
.top {
  color: red;
}
.bottom {
  color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="fraction"><strike>1</strike>/2</span>
<span class="fraction">2/2</span>
Amadan
  • 191,408
  • 23
  • 240
  • 301