Hi,

I have an unusual problem, I am developing within a wordpress environment and using a plugin. To futureproof the plugin I do not want to edit the code that is generated to include HTML tags, because when the plugin is updated it will overwrite my change.

I am looking to write some javascript that is outside of this plugin to replace text within a text node to a h2 header.

The code snippet that I am dealingwith is here:

<div class="wpb_wrapper">
            Log In
<div class="login" id="theme-my-login1">

In here, I would to change the "Log In" text. Is there a way that i can do this?

Any help would be much appreciated.

Kind regards

Darren

If you use jQuery you can use the .text() method to change 'log In' to whatever you want. The following will change 'Log In' to 'New text'.

$(function() {
    $(".wpb_wrapper").text("New text");
});

With vanilla JavaScript you could do something like this:

var text = document.getElementsByClassName("wpb_wrapper");
text.innerHTML = "New text";

Unfortunately, this overwrites the content contained in the div section below wpb_wrapper.

<div class="login" id="theme-my-login1">

Is there a way I can just replace the text in the text nodes without overwriting the HTML?

it would be nice if that div had an ID, but since it can be selected by its class, and assuming there is no other div on the page with the same class, you can try this method...

Basically get the children of the target div, without the text, then save that in a variable.. next insert the new text and append the children. Here is an example...

<div class="wpb_wrapper">
    Log In
    <div class="login" id="theme-my-login1">
    </div>
</div>

<script>

    var temp = $('.wpb_wrapper').children();
    $('.wpb_wrapper').text('New Text').append(temp);

</script>

Indeed! This would change also the text from its children. You don't want that of course :)

Then you could look for an exact match of the word 'Log In' with something like this:

$(function() {
    $(".wbp_wrapper").text(function(i, oldText) {
        return oldText === "Log In" ? "New Text" : oldText;
    });
});

Indeed! This would change also the text from its children. You don't want that of course :)

the sample code i provided doesnt change the text of the child elements.

<div class="wpb_wrapper">
    Log In
    <div class="login" id="theme-my-login1">
      This text doesn't change
    </div>
</div>

@JorgeM - actually your snippet is the one that works beautifully... not mine :( going to look into this.

EDIT: Your solution is the way to go to handle its children!

JavaScript

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
</head>

<body>

<div class="wpb_wrapper">
    Log In
    <div class="login" id="theme-my-login1">
      This text doesn't change
    </div>
</div>


<script>

    this['theme-my-login1'].parentElement.replaceChild
    (   document.createTextNode("Don't Login!"), 
        this["theme-my-login1"].previousSibling 
    );

</script>

</body>
</html>
commented: Why this has been overlooked so far I don't know +15
commented: Javascript master +12

Honestly, if you want it to be clean; add something like this:

<!-- HTML -->
<div class="wpb_wrapper">
    <span id="login-text">Log In</span>
    <div class="login" id="theme-my-login1">
        ...
    </div>
</div>

// JS
$("#login-text").text("Something...");
// or $("#login-text").html("Something...");
// vanilla JS would be this
// document.getElementById("login-text").innerHTML = "Something...";

This is just cleaner IMO, but whatever floats your boat.

commented: Before you answer, just read the thread first becaue this solution was alray given and did not solved it totally +0

@Matrixdevuk - I see now you also changed the HTML by wrapping 'Log In' into span tags, but the OP said he did not wanted to alter the HTML.

commented: Before you add ratings, just read MY REPLY first because the solution provided by me added good practices. -1

Yes, but to keep it clean you'd really need to add it; otherwise it is just messy. Note how I said "Honestly, if you want it to be clean; add something like this" — this is going against the OP's question, yeah, but it's also adding some good practices into their development. Say what you want; but most would prefer this.

Adding a span tag with an ID for the js is not cleaner then without it. The selector engine is a tiny bit quicker with finding 'Log In' like this for sure, but it's certainly not cleaner. Long story short, it's not necessary and it was not an option for the OP to alter the code of the plugin. Otherwise he could and should just change the text directly in the HTML. But say what you want, two others didn't prefer it either.

I talked to a few friends before actually posting my answer and they agreed that it was cleaner which encouraged to post it. A better practice is to eliminate any possibility of selection problems and thus my answer is not bad. I don't see why the OP doesn't want a span tag there, but whatever.

Member Avatar for diafol

I think we shold respect the OP's html "as is" and try to offer a solution pertining to his requirements. "Cleaner" doesn't come into it - it's a distraction. The OP seems to be using a plugin, which means he's not in control of the HTML output. Changing it, as he mentions may lead to future failure if the plugin is updated.

I missed the part where he said it'd overwrite it. My bad.

@ diafol: Why this has been overlooked so far I don't know

that solution is so edgy they were afraid to even look at it!

@TroyIII & @diafol: I saw your solution already which is indeed too edgy, my eyes hurt ;)
Just wanted to react on matrixdevuk solution. Nothing more, nothing less.

But off course you saw it (it's not invisible) yet overlooked it with pride like, something that could never, ever, even have a chance to work.
But it does! Perfectly, despite the firsthand unexpected and unpredictable underestimating prejudice. And of course it is edgy but on the better side of its meaning. Which is termed - advanced!

Member Avatar for diafol

I have to admit I didn't understand it at first Troy. I was on my second nosebleed when I finally got what was going on. But I like it.

No, it was not like that. I wouldn't dare to underestimate your JS/JQuery skills, because I noticed already your deep understanding of this. I looked at your snippet several times trying to understand what was going on there and wanted to ask you about it, but got distracted and I didn't want to hijack the OP's thread.

But since the OP is not here for a while now. I will ask :)
I don't get the 'previousSibling' bit?
this["theme-my-login1"].previousSibling
If I read the first part of your snippet, then I would say that would be enough, but that's obviously because I don't get it.

To tell you the truth, I dont have any jQuery skills - and since the main reason of using it, was W3C's blunt of introducing the lamest ever

var myElement = document.getElementById("myElement");

severe coder-hostile syntax, with something like $("myElement") function, - I never bothered using it (for it was heavy and slow and somewhat uglier than conventional myElement call), since I already had my own super lightweight solution, which I overcame with a simple one-liner like:

var _ = document.all || document.getElementsByTagName("*");

placed on the document head or anywhere on the script, wherein a lot faster and cleaner syntax like this was possible:

_.myElement

which also made it possible of accessing broken token id's like id="my element", with:

_['my element']

syntax, without calling a function to do that.

and it was easier to refresh and re-enable old coded pages with myElement calling syntax (which were rendered obsolete and dysfunctional by this W3C assault), using _. prefix than anything else.

And it still is.

Now to answer your question:
That's where we are targeting/referencing the text-node we are about to replace, without disturbing the environment of its nest. With a similar technique supported by advanced HTML5 and old versions of IE.

As you can see the "theme-my-login1" previous sibling is exactly the text-node we want to change with a standard well supported DOM.replaceChild syntax.

Regards.

My bad with the jQuery... I got you mixed up with another member of the forum I guess.

Interesting aproach with the uderscore var storing all elements from the document. The first thing that comes to mind is that this would be a performance hit and slower because of the wild card selector, but I'm a JS noob so I'm not going into debate with you :)
I just started with writing my own simple functions with jQuery, because jQuery is easier to grasp and to read for my designer brain.

Thanks for the clarification. That makes sense.

Cheers!

You have a wrong understanding on the case here, because there's no other call and no wild card selector! You are simply obtaining a reference to an allready existing DOM colection Object. And once you get hold of it - and you can obtain it long before any page elements have been parsed, there's no possible sweat going on there.

You can, however, do all kind of tests to see if it's faster invoking a custom JavaScript function; do all if and else's in a row and return the match for every single turn you have to reference an element, only to confirm that a simple element picking is the fastest possible method. And it's no brainer in comprehending that: simply picking the required element from the hash without any processing, is by orders of magnitude faster than any other.

It's as fast as myobj[prop] call that nothing can compete with. Not even a pure "document.getElementById" method. Especially not a syntax that needs to:

  1. locate function object;
  2. pas an argument;
  3. process its value for request identification in several steps;
    3.1. invoke the built-in getElementById function;
    3.2. which in turn, once again needs to call and get hold of "document" element;
    3.3. which owns the "getElementById" function;
    3.4 and is (also)a window property;
    3.5. of the same level as any other element with an ID.

Which means that "_.myElement" syntax is as fast as calling for "window.document"!

Regards.
p.s.:
With HTML5 back in town, jQyery's basic functions (and the main reason people started using it) are finally rendered obsolete. Of course, other jQuery plugins supplements are still awesome.

I really thought that the asterix (*) stood for selecting all HTML elements in the document, just like in CSS, so I didn't get that line either :)
Thanks for the thorough explanation!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.