-1

So i have a phone number i need to dynamically change on the DOM of my site. This was no problem until i encounter this:

enter image description here

I was able to change the inner Text of the element but since the style on CSS has "0810-222-1XXX" as content im not able to overwrite this.

Is there a way?

Marco
  • 1,112
  • 1
  • 14
  • 34
  • relevant ? https://stackoverflow.com/questions/5041494/selecting-and-manipulating-css-pseudo-elements-such-as-before-and-after-usin – sol Jan 31 '18 at 17:26
  • @sol already seen it, not useful sadly – Marco Jan 31 '18 at 17:31
  • [**Do not post images of code or errors!**](https://meta.stackoverflow.com/q/303812/995714) Images and screenshots can be a nice addition to a post, but please make sure the post is still clear and useful without them. If you post images of code or error messages make sure you also copy and paste or type the actual code/message into the post directly. – Rob Feb 01 '18 at 13:07
  • You are required to post the markup or code that you have tried here within your question: [mcve] – Rob Feb 01 '18 at 13:09

2 Answers2

3

Only by applying a CSS rule that's at least as specific and later in the CSS, or more specific. You can't via .style on the element (because that style isn't applied to that element, it's applied to the pseudo-element before it, which cannot be accessed at all).

For example:

// Say we want to target the second one
var idAllocator = 0;
setTimeout(function() {
  var target = document.querySelectorAll("#header .number")[1];
  if (target) {
    if (!target.id) {
      target.id = "__unique__id__" + idAllocator++;
    }
    var style = document.createElement("style");
    style.type = "text/css";
    style.textContent = "#" + target.id + ".number::before { content: 'UPDATED'; }";
    document.querySelector("head").appendChild(style);
  }
}, 800);
#header .number::before {
    content: '0810-222-1XXX';
}
<div id="header">
  <div class="number">a</div>
  <div class="number">b</div>
  <div class="number">c</div>
  <div class="number">d</div>
</div>

You could take that further by giving the style element an ID derived from the element's ID so you could update it subsequently if desired:

var idAllocator = 0;
function updateBeforeContent(target, content) {
  if (!target.id) {
    target.id = "__unique__id__" + idAllocator++;
  }
  var styleId = "__style__for_" + target.id;
  var style = document.getElementById(styleId);
  if (!style) {
    style = document.createElement("style");
    style.type = "text/css";
    style.id = styleId;
    document.querySelector("head").appendChild(style);
  }
  style.textContent = "#" + target.id + ".number::before { content: '" + content + "'; }";
}
// Say we want to target the second one
var target = document.querySelectorAll("#header .number")[1];
if (target) {
  setTimeout(function() {
    updateBeforeContent(target, "UPDATE1");
  }, 800);
  setTimeout(function() {
    updateBeforeContent(target, "UPDATE2");
  }, 1600);
}
#header .number::before {
    content: '0810-222-1XXX';
}
<div id="header">
  <div class="number">a</div>
  <div class="number">b</div>
  <div class="number">c</div>
  <div class="number">d</div>
</div>
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • You may want to specifically mention _!important_ as a shortcut. With the caveat that it's generally not advised in larger projects or when a Project is not under the thumb of a single Developer. – zfrisch Jan 31 '18 at 17:34
  • @zfrisch: No need for `!important` here. :-) – T.J. Crowder Jan 31 '18 at 17:36
  • You were pretty close but not quite, here is what happens with your code. https://imgur.com/O1JXDQw – Marco Feb 01 '18 at 12:45
  • @Marco: It's just a trivial omission (`style.id = styleId;`), easily diagnosed and corrected (and now fixed). (You can edit answers, FWIW, when something that trivial comes up.) – T.J. Crowder Feb 01 '18 at 13:05
0

The actual solution i used was to create a new element, apply all the needed styles. Hide the unwanted element with:

element.style.display = "none"

And finally append the new element as a child of the father of the old (basically a brother).

Hope it helps!

Marco
  • 1,112
  • 1
  • 14
  • 34
  • Beware that *replacing* the element (which isn't what you asked about) means that if there is any event handler on that element, it won't be on your new element; if the code in the page has a reference to that element, it will still have a reference to the old one, etc. Whereas if we just change the :before text it has (what you asked about), event handlers and references remain valid. – T.J. Crowder Feb 07 '18 at 14:20
  • @T.J.Crowder Yes but strictly changing the :before text from javascript only is actually not possible ... Anyway this was a temporal solution only. – Marco Feb 07 '18 at 18:33
  • Um, it's both possible, and I demonstrated doing it! :-) But never mind... – T.J. Crowder Feb 07 '18 at 18:53