Getting :before content and printing special characters from content - javascript

I would like to get the content from my :before tag. I know some will say it's not a real (pseudo) element but there is a way in JS but can some one help me do it in JQ because I have multiple tags and I want to iterate with $.each...
Here is how I got the content in JS
window.getComputedStyle(document.querySelector('i'), ':before').getPropertyValue('content')
How can I do this in JQ?
Here is what I tried:
$.each($('div'),function(){
$(this).find('i:before').css('content');
});
Print a special char?
When I get the content I would like to print it, the problem is it's a special character and I would like to get a real code.
My content has a code like this: \e002. So I would like to print it like that not .

Iterate $.each($('div i') instead of $.each($('div'), so you can avoid using find() within the iterator.
You can then use your window.getComputedStyle() code on this:
window.getComputedStyle(this, ':before').getPropertyValue('content')
You'll then be left with a Unicode string, which brings us to the second part of your question.
You can use charCodeAt() to view this string character by character, which gives the following for \e002:
34
57346
34
The 34s represent double-quotes, which you can ignore.
57346 is the decimal equivalent of hexadecimal e002. You can use toString(16) to convert it to hex.
All that's left is to prepend the \ in front.
So our code becomes:
$.each($('div i'),function() {
var s = window.getComputedStyle(this, ':before').getPropertyValue('content'),
char = '\\' + s.charCodeAt(1).toString(16);
console.log(char); // \e002
});
Snippet:
$.each($('div i'),function() {
var s = window.getComputedStyle(this, ':before').getPropertyValue('content'),
char = '\\' + s.charCodeAt(1).toString(16);
console.log(char); // \e002
});
i:before {
content: '\e002';
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<i>Our italic node</i>
</div>

Related

Replace only first occurrence with javascript

I have a string that comes from HTML without tags but with escaped symbols, like:
abc&symbol1;def&symbol2;ghi&symbol3;jkl...
In JavaScript or TypeScript, how can I replace all sequences like &symbolN; with one fixed character like X so I get:
abcXdefXghiXjkl...
(by the way, the target is to get the length of a string with distinct HTML escaped characters like £ so that each one of them is counted like one character)
Update: maybe I've not explained accurately: symbol1, symbol2,... do not mean that "symbol" string repeats, but completely distinct symbols that DO NOT repeat, e.g. "abc£def ghi€..." So no way to use a repeating textual pattern like "&symbol;"
Just to calculate length, you can cheat, as you say:
html.replace(/&[^;]+;/, 'X').length
To convert HTML into text properly, one should use a HTML parser, not regexp. For example, in browser,
let e = document.createElement('div');
e.innerHTML = html;
let text = e.textContent;

escape characters not working with innerHTML

I have a string containing HTML escape characters (for <and >) that I am trying to render inside a div using innerHTML. the escaped characters are not supposed to be rendered like normal html, but rather as text. However, they still do, so is there a work around for this?
NOTE: the objective is to display a few (meaning not all) tags as normal text.
Here is an example implementation:
var string = "<div>yolo</div>";
string = string.replace(/</g, '<'); //replaces all '<' with its escape character
string = string.replace(/>/g, '>'); //replaces all '>' with its escape character
string = string.replace(/(=|%|\/|\*|-|,|;|\+|<|>)/g, "<span class=\"sc\">$1</span>");
//the last line adds special formatting
//to certain characters using CSS (not shown)
//and a span tag with class, "sc".
//this is the reason that I cannot just simply
//use innertext instead of innerhtml
document.body.innerHTML = string;
P.S. please give an answer in pure JavaScript. I do not care if you add a jQuery solution, I just need a pure javascript one.
It doesn't work properly because you're replacing the ;s with <spans>. Try replacing the whole < first to prevent your span-replacer from breaking the entities.
e.g.
var string = "<div>yolo</div>";
string = string.replace(/</g, '<'); //replaces all '<' with its escape character
string = string.replace(/>/g, '>'); //replaces all '>' with its escape character
string = string.replace(/(<|>|=|%|\/|\*|-|,|;|\+|<|>)/g, "<span class=\"sc\">$1</span>");
//the last line adds special formatting
//to certain characters using CSS (not shown)
//and a span tag with class, "sc".
//this is the reason that I cannot just simply
//use innertext instead of innerhtml
document.body.innerHTML = string;
.sc {
color: red;
font-weight: bold;
}
If you use jQuery, you may want to deal with text() instead of innerHTML().

Is there any way for me to work with this 100,000 item new-line separated string of words?

I've got a 100,000+ long list of English words in plain text. I want to use split() to convert the list into an array, which I can then convert to an associative array, giving each list item a key equal to its own name, so I can very efficiently check whether or not a string is an English word.
Here's the problem:
The list is new-line separated.
aa
aah
aahed
aahing
aahs
aal
aalii
aaliis
aals
This means that var list = ' <copy/paste list> ' isn't going to work, because JavaScript quotes don't work multi-line.
Is there any way for me to work with this 100,000 item new-line separated string?
replace the newlines with commas in any texteditor before copying to your js file
One workaround would be to use paste the list into notepad++. Then select all and Edit>Line Operations>Join lines.
This removes new lines and replaces them with spaces.
If you're doing this client side, you can use jQuery's get function to get the words from a text file and do the processing there:
jQuery.get('wordlist.txt', function(results){
//Do your processing on results here
});
If you're doing this in Node.js, follow the guide here to see how to read a file into memory.
You can use notepad++ or any semi-advanced text editor.
Go to notepad++ and push Ctrl+H to bring up the Replace dialog.
Towards the bottom, select the "Extended" Search Mode
You want to find "\r\n" and replace it with ", "
This will remove the newlines and replace it with commas
jsfiddle Demo
Addressing this purely from having a string and trying to work with it in JavaScript through copy paste. Specifically the issues regarding, "This means that var list = ' ' isn't going to work, because JavaScript quotes don't work multi-line.", and "Is there any way for me to work with this 100,000 item new-line separated string?".
You can treat the string like a string in a comment in JavaScript . Although counter-intuitive, this is an interesting approach. Here is the main function
function convertComment(c) {
return c.toString().
replace(/^[^\/]+\/\*!?/, '').
replace(/\*\/[^\/]+$/, '');
}
It can be used in your situation as follows:
var s = convertComment(function() {
/*
aa
aah
aahed
aahing
aahs
aal
aalii
aaliis
aals
*/
});
At which point you may do whatever you like with s. The demo simply places it into a div for displaying.
jsFiddle Demo
Further, here is an example of taking the list of words, getting them into an array, and then referencing a single word in the array.
//previously shown code
var all = s.match(/[^\r\n]+/g);
var rand = parseInt(Math.random() * all.length);
document.getElementById("random").innerHTML = "Random index #"+rand+": "+all[rand];
If the words are in a separate file, you can load them directly into the page and go from there. I've used a script element with a MIME type that should mean browsers ignore the content (provided it's in the head):
<script type="text/plain" id="wordlist">
aa
aah
aahed
aahing
aahs
aal
aalii
aaliis
aals
</script>
<script>
var words = (function() {
var words = '\n' + document.getElementById('wordlist').textContent + '\n';
return {
checkWord: function (word) {
return words.indexOf('\n' + word + '\n') != -1;
}
}
}());
console.log(words.checkWord('aaliis')); // true
console.log(words.checkWord('ahh')); // false
</script>
The result is an object with one method, checkWord, that has access to the word list in a closure. You could add more methods like addWord or addVariant, whatever.
Note that textContent may not be supported in all browsers, you may need to feature detect and use innerText or an alternative for some.
For variety, another solution is to put the unaltered content into
A data attribute - HTML attributes can contain newlines
or a "non-script" script - eg. <SCRIPT TYPE="text/x-wordlist">
or an HTML comment node
or another hidden element that allows content
Then the content could be read and split/parsed. Since this would be done outside of JavaScript's string literal parsing it doesn't have the issue regarding embedded newlines.

How can I add html in a div repeatedly, but keep pre-existing html?

Using Javascript of jQuery I want to swap a string of text for an html tag, over and over, without losing the previous html.
FIDDLE
<p>This is <i id="text">text</i> and more text</p>
This is text and more text
function rep() {
var t = $('p').text().replace('text', '<b>html</b>');
$('p').html(t);
}
Ideally it would look like:
<p>This is <i id="text"><b>html</b></i> and more <b>html</b></p>
This is html and more html
I DONT want to change the pre-existing html. <i id="text"> should remain in the html, no matter how many times I run the function. .html().replace(.. wouldn't work because it will grab the id="text". Thanks.
You need to get the old value using .html(), not .text(), since the latter leaves out all the HTML markup. You can do it in a single call, using a function to calculate the replacement from the old value:
function rep() {
$('p').html(function(i, oldhtml) {
return oldhtml.replace(/(<[^>]*)?text/g, function($0, $1) {
return $1 ? $0 : '<b>html</b>';
});
});
}
Notice that you have to use a regular expression with the g modifier to perform multiple replacements in a string. Negative lookbehind would be the normal way to exclude id="text", but this is not available. I used the workaround from Javascript: negative lookbehind equivalent?
Tell me if this code fits with your needs (I reuse input multiple times for convenience) :
function rep(input) {
input = RegExp.escape(input); // http://stackoverflow.com/q/3561493/1636522
input = new RegExp(input + '(?![^<]*?>)');
input = $('p').html().replace(input, '<b>html</b>');
$('p').html(input);
}
A little help about (?![^<]*?>) (roughly : "some text not followed by >") :
(?!...) not followed by
[^<]* any char except "<", zero or more times
?> until next ">"
More on regular expressions : http://www.javascriptkit.com/javatutors/redev.shtml.

Convert a string containing HTML entities to uppercase

In JavaScript, how can I convert a string containing HTML entities to uppercase. Take the string 'Cafés & Bars' for example:
Cafés & Bars
It needs to be converted to:
CAFÉS & BARS
If toUpperCase() were used, it would destroy both the entities. If the text were to be uppercased and then text between & and ; were lowercased then the acute E would remain lowercase.
In my particular case, I am unable to solve this using the text-transform: uppercase style.
function decodeEntities(string){
var elem = document.createElement('div');
elem.innerHTML = string;
return elem.textContent;
}
Then simply do something like decodeEntities('Cafés & Bars').toUpperCase();
But note that when you do, your returned text won't be CAFÉS & BARS it will be CAFÉS & BARS
I'm hoping there's enough examples in this fiddle to solve things for you. FYI, you don't mention if you are using jQuery or not, I can update this if you need just vanilla JS.
http://jsfiddle.net/hafichuk/APNWh/
If you have control of the text representation, you can use (or convert text-named entities to) decimal HTML entities; they don't get converted to uppercase, because numbers have only one case.
So:
Instead of & use &
Instead of < use &#60
Instead of " use "
etc.

Categories

Resources