2

Quite an interesting challenge for me was, i have a div block which contains text(content which can contain different number of any elements like <p> <ul> <div> etc, its like edited Article). This Article have been posted already on my site, and i have added another div block which appers after this Article is loaded. What i need is to put this block at the end of Article and this block should wrap text around Article like on image below. At the moment "Also related to this article" - its a block which i want to insert.

Ofcourse i can just append this block before the last <p> element, but last element may be <ul> or another small <div> or <span>, i have different articles, which user can post.

What i think is to get the length of my Article div and subtracted from the current length of the number of characters that will suit me and insert related article <div> there.

So, for examle(Article text is much bigger, but this is just simple):

<div id="article">
  Lorem Ipsum is simply dummy text of the printing and typesetting industry 
  <p>Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It 
</div>

<div id="related_article">
   <ul>
     <li> Item1</li>
     <li> Item2</li>
     <li> Item3</li>
  </ul>
</div>

Jquery code:

$(document).ready(function() {
  var text_length = $.trim($("#article").text()).length;
  var length_before = 30;//for example
  var related = $('div#related_article');
  var content = $('div#article');
  var substract = text_length - length_before;
  //is it possible to put this *related* div
  //into substract point in content at the end of it.  
});

Should i use regex? or is it possible to do like this somehow? maybe i just stupid and miss something, please show me the way of action.

english is not my native, so there might be syntax errors

As people asked i provide an example of how can Article looks like

Here is an example of how can looks like my article it can contain a lot of tags

enter image description here

Petro Popelyshko
  • 1,353
  • 1
  • 15
  • 38

2 Answers2

1
$(document).ready(function() {
    var textLength = 15;
    var currentLength = 0;
    var $lastChild = $("div#article").children(":last-child");
    currentLength = $lastChild.text().length;
    while(currentLength < textLength) {
        $lastChild = $lastChild.prev();
        currentLength = currentLength + $lastChild.text().length;
    }
    var $related = $("div#related_article");
    $related.insertBefore($lastChild);
});

The above script inserts the related article above a particular tag if the text length below them is greater than 15. You can change the textLength as per your need.

The below code goes through all leaf nodes and it inserts the related article at the required index.

var $articleObj = $("div#article");
var $related = $("div#related_article");
var textLength = 15;

function addRelatedArticle($parentObj, currentLength) {
    var $lastChild = $parentObj.children(":last-child");
    currentLength = currentLength + $lastChild.text().trim().length;
    while($lastChild.length > 0 && currentLength < textLength) {
        $lastChild = $lastChild.prev();
        currentLength = currentLength + $lastChild.text().trim().length;
    }
    if ($lastChild.text().trim().length < $lastChild.html().trim().length) {
        addRelatedArticle($lastChild, currentLength - $lastChild.text().trim().length);
    } else {
        if (currentLength == textLength) {
            $related.insertBefore($lastChild);
        } else {
            var lastChildText = $lastChild.text().trim();
            $lastChild.html($related);
            $lastChild.prepend(lastChildText.slice(0,currentLength - textLength));
            $lastChild.append(lastChildText.slice(currentLength - textLength));
        }
    }       
}
addRelatedArticle($articleObj, 0);

I didn't check if the existing article has atleast the required minimum number of characters. The main restriction of the script is that it will search only for the leaf nodes. i.e. It will work fine on the below HTML.

<div>
    <div>Some junk text</div>
    <div> more junk texts</div>
</div>

But it might not work well with the below HTML.

<div>
    Junk text
    <div>More junk</div>
    testing text
</div>
  • Thank you, i know this, but the main problem is, for example if my last element `

    ` contains only two words, `related_article` will appers at the bottom of this text, it will not wrap it, this solution will work in *some cases* but I'm not satisfied

    – Petro Popelyshko Oct 24 '12 at 15:12
  • 1
    The above code will insert the related article just above the

    tag. The final HTML will be like

    Any value that was there in the article
    related articles content

    Need not tob a p tag. It could be any tag like ul or div or anything.

    . If you want it to be different please provide some example.
    – Jothimurugan B Oct 24 '12 at 15:19
  • 1
    i have added link in my post, u can watch, how it can looks like – Petro Popelyshko Oct 24 '12 at 15:29
  • I have edited the solution to give another way of inserting the related article. – Jothimurugan B Oct 24 '12 at 15:59
  • i tried your solution, its work in some cases, but not in all, but anyway thanks – Petro Popelyshko Oct 25 '12 at 07:41
  • Can you be a bit more specific on which cases the solution fails. So that I can change the solution to work :-) – Jothimurugan B Oct 25 '12 at 08:13
  • for example, if last block is `

    ` it has 10characters, before this block i have another `p` with 3 characters, and then i have `

    ` with 20 chars. So this block will be inserted before `
    ` and text in `

    ` elements will be under `Related article` block

    – Petro Popelyshko Oct 25 '12 at 08:57
  • today i tried your solution, first time its broke everything :D, i have fixed it but still this kinda not what i wanted :> – Petro Popelyshko Oct 25 '12 at 20:47
0

Your best bet would be to look in to using the selection handling of the current browsers. You can use the selection to navigate along by a certain number of characters and then insert an element... but as Michal Klouda states - there will be a few tricks involved (i.e. avoiding special tags and situations.. oh and as usual having to be as cross-browser as possible).

Here is my answer showing code on a different subject, I don't have time now to go into detail, but it should give you a few things to look into.

The following code works based on the user click event... however it could be reversed to target a specific element and a certain character offset. You mainly should look into the methods available to the objects returned by window.getSelection or document.selection and the related Range objects provided by the different browsers.

TextRange offsetLeft and offsetTop broken in Internet Explorer 8 Standards Mode (IE8)

Community
  • 1
  • 1
Pebbl
  • 34,937
  • 6
  • 62
  • 64
  • no worries - when I get a second I'll build up an example, bit rushed off my feet at the moment tho :) – Pebbl Oct 24 '12 at 17:48