Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to change text from a div

I have a script that translates a Russian forum word by word using TreeWalker, but there are one kind of div element that I couldn't change its text and that's my question, how do I change that? As the forum requires registration I'm going to try to provide every detail of code I can below.


the webpage specific code where I'm trying to change the text:

<div class="sp-wrap">
    <div class="sp-head folded clickable">Скриншоты</div> //once clicked unhide the div below to show images and by clicking it again hides.
    <div class="sp-body inited" title="" style="display: none;"> //hidden div
        <div class="clear"></div>
        <h3 class="sp-title">Скриншofы</h3>
        <span class="post-align" style="text-align: center;">
        <div class="clear"></div>
        <div class="sp-fold clickable">[свернуть]</div>
    </div>
</div>
  • I'm trying to change Скриншоты for Images from the class sp-head, which is the one I click to show the images.

the CSS code for that class:

.sp-head {
    border-width: 0;
    color: #2a2a2a;
    cursor: pointer;
    font-size: 11px;
    font-weight: bold;
    line-height: 15px;
    margin-left: 6px;
    padding: 1px 14px 3px;
}

my code below:

//... header
// @require     https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js
// @grant       GM_addStyle
// ==/UserScript==

$('div.sp-wrap > div:first').each( function (){ //div:contains("Скрин") div.sp-head.folded.clickable

    var jThis = $(this);
    var jText = jThis.textContent;
    var jhtml = jThis.html();

    console.log(jText);
    console.log(jThis);
    //console.log(jhtml);

    jText = jText.replace(/Скрин(лист|шоты)/ig, "Images");

});

var textWalker   = document.createTreeWalker (
    document.body,
    NodeFilter.SHOW_TEXT,
    {   acceptNode: function (node) {
        // Skip whitespace-only nodes
        if (node.nodeValue.trim() )
            return NodeFilter.FILTER_ACCEPT;

        return NodeFilter.FILTER_SKIP;
    }
    },
    false
);

var textNode;

while (textNode  = textWalker.nextNode() ) {
    var oldText  = textNode.nodeValue;
    var newText  = oldText.replace (/Главная/ig, "Home");
    newText      = newText.replace (/Скрин(лист|шоты)/ig, "Images");
    newText      = newText.replace (/Последние поблагодарившие/ig, "Last Who Thank");
    //...
    //repeats word by word until ends at the line below     
    textNode.nodeValue = newText;
}

What I've tried

I've already tried a bunch of jQuery filters that could get that div child, but it is as it was not there.

When I select the div itself using:

$('div.sp-head.folded.clickable')

The console result is blank.

When I run the code I've posted here (under my code below header) the result is

console log

for jText and jThis vars respectively

And finally when I try

$('div.sp-wrap div:contains("Скрин")').each( function (){ 

    var jThis = $(this);
    var jText = jThis.text();
    jThis.text("Images");

});

I get the word Images replacing the real Images

wrong result

Also fails when I tried to use

$('div.sp-wrap div:contains("Скрин")').each( function (){ 

    var jThis = $(this);
    var jText = jThis.text();
    jThis.parent().text("Images");

});

Resulting in a destroyed wrap

wrong result again


As it is a text like the other ones replaced, I could not figure it out why TreeWalker does not "see" that kind of div text.


  • Added for clarify comments

image about the suggestion made in comments

All span tags looks closed, even the one wrapped on the image is closed.

like image 217
Commentator Avatar asked Nov 09 '22 12:11

Commentator


1 Answers

Yesterday I figured out the solution and couldn't post here before. The wrap content is AJAXed, for that reason the element to be selected is not ready when the script runs. In order to handle that, I've used WaitForKeyElements(). I was able to detect the issue after analyzing the "last who thanked" list and could not believe I haven't seen it before.

Solution:

//...header
// @require     https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js
// @require     https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant       GM_addStyle
// ==/UserScript==


waitForKeyElements ("div.sp-head.folded.clickable", translateDiv);


function translateDiv (jNode) {

    var jText  = jNode.text();
    var reg    = /Скрин(лист|шоты)/ig;

    if (reg.test (jText) ) {

        jNode.text( jText.replace(/Скрин(лист|шоты)/ig, "Images") );

    } else if (jText.indexOf("Последние поблагодарившие") != -1) {

        jNode.text("Last Who Thanks");

    }

}
like image 65
Commentator Avatar answered Nov 14 '22 22:11

Commentator