HTML DOM check if the text of an element includes specific text? - javascript

How to check if an element's innerHTML includes "as me to" (the whole phrase and not just if it includes one of the words)?
I know that it is pretty short, but the question is already stated in the title.

you can use indexOf()
var str = $('some selector id').innerHTML();
var result = str.indexOf("as");
if result is -1 then there is no instance of "as" in the given string.

You can check it using RegExp. If the element has given string, the test() function will return true or false if it's not.
function check(elem, str) {
var element = document.getElementById(elem).innerHTML,
rg = new RegExp(str, 'g'),
res = rg.test(element);
console.log(`Does the ${elem} element contains ${str} - ${res}`);
return res;
}
check('p', 'as');
check('p', 'something');
<p id='p'>ashamed</p>

Try this!
HTML
<div id="source">this word as </div>
JAVASCRIPT
var sourceEl = document.getElementById('source');
if (sourceEl.textContent.includes('as'))
{
alert("Exist");
}
https://jsfiddle.net/n3zkzy1g/5/

Related

Find and replace character in multiple HTML tags

I'm trying to loop through multiple HTML elements, to replace a character in those elements.
I managed to do it with only one element
HTML
<h2>test</h2>
JS
var test = document.querySelector("h2");
var text = test.textContent;
var arr = [];
for(i=0;i<text.length;i++){
arr.push(text[i]);
}
for(j=0;j<arr.length;j++){
if(arr[j] === "t"){
arr[j] = "z";
}
}
var newText = arr.join('');
test.innerHTML = newText;
but how would I go about looping through multiple h2s? The idea is to replace the letter "t" with "z", then push the new word into the HTML.
HTML
<h2>test</h2>
<h2>teeth</h2>
<h2>trent</h2>
I tried document.querySelectorAll, but not sure how to appropriately use textContent in this case.
Thanks in advance!
This should do the trick:
const replaceInSelection = (target, replacement, selector) => {
const t = new RegExp(target, 'g')
document.querySelectorAll(selector).forEach(
el => el.textContent = el.textContent.replace(t, replacement)
)
}
<h2>test</h2>
<h2>teeth</h2>
<h2>trent</h2>
<button onclick="replaceInSelection('t', 'z', 'h2')">t -> z</button>
<button onclick="replaceInSelection('z', 't', 'h2')">z -> t</button>
That is because querySelector only retrieves a single element (the first that matches the selector). Fortunately there is querySelectorAll method that allows to retrieve all matching elements.
In addition to that, you can simplify your code quite a bit: since your goal is to replace any occurence of the letter t with the letter z then you should do just that. An element's textContent will always be a string, therefore you can use String#replace to do your operation.
document
.querySelectorAll("h2")
.forEach(elem => {
/*
You can assign the result to elem.innerHTML or
elem.textContent depending on your needs
*/
elem.innerHTML = elem.textContent.replace(/t/g, "z");
});
function replaceElementsText(selector, substr, newSubstr){
if(!selector || !substr || !newSubstr){
return;
}
const elems = [...document.querySelectorAll(selector)];
elems.forEach(el => el.innerText = el.innerText.replace(new RegExp(substr, "g"),newSubstr))
}
replaceElementsText('h2', 't','z')
var hs = document.querySelectorAll('h2');
hs.forEach(h => {
h.textContent = h.textContent.replace(/t/g /*target*/, "z"/*new char*/);
});
good luck! D;

How can I create a syntax like vue js in vanilla JavaScript?

<div id="">
<span>{{msg}}</span>
</div>
Let's think msg is variable of JavaScript and now I want to get the parent tag of {{msg}} and push a new value by innerHTML, here {{msg}} working as an identity.
demo JavaScript example:
<script>
var msg = "This is update data";
{{msg}}.parentElement.innerHTML=msg;
</scritp>
This is not actual JavaScript code, only for better understanding.
You can use jquery easily to find that element and then replace the text
var msg = "This is update data";
$(`span:contains(${msg})`).html("Its New");
In javascript:
var spanTags = document.getElementsByTagName("span");
var msg = "This is update data";
var found;
for (var i = 0; i < spanTags.length; i++) {
if (spanTags[i].textContent == msg) {
found = spanTags[i];
break;
}
}
Now, you have found that element in found and you can now change its text
if (found) {
found.innerHTML = "New text";
}
The simplest approach is to treat the entire document as a string and then re-parse it when you're done.
The .innerHTML property is both an HTML decompiler and compiler depending on weather you're reading or writing to it. So for example if you have a list of variables that you want to replace in your document you can do:
let vars = {
msg: msg, // pass value as variable
test_number: 10, // pass value as number
test_str: 'hello' // pass value as string
};
let htmlText = document.body.innerHTML;
// find each var (assuming the syntax is {{var_name}})
// and replace with its value:
for (let var in vars) {
let pattern = '\\{\\{\\s*' + var + '\\s*\\}\\}';
let regexp = new RegExp(pattern, 'g'); // 'g' to replace all
htmlText = htmlText.replace(regexp, vars[var]);
}
// Now re-parse the html text and redraw the entire page
document.body.innerHTML = htmlText;
This is a quick, simple but brutal way to implement the {{var}} syntax. As long as you've correctly specified/designed the syntax to make it impossible to appear in the middle of html tags (for example <span {{ msg > hello </ }} span>) then this should be OK.
There may be performance penalties redrawing the entire page but if you're not doing this all the time (animation) then you would generally not notice it. In any case, if you are worried about performance always benchmark your code.
A more subtle way to do this is to only operate on text nodes so we don't accidentally mess up real html tags. The key to doing this is to write your own recursive descent parser. All nodes have a .childNodes attribute and the DOM is strictly a tree (non-cyclic) so we can scan the entire DOM and search for the syntax.
I'm not going to write complete code for this because it can get quite involved but the basic idea is as follows:
const TEXT_NODE = 3;
let vars = {
msg: msg, // pass value as variable
test_number: 10, // pass value as number
test_str: 'hello' // pass value as string
};
function walkAndReplace (node) {
if (node.nodeType === TEXT_NODE) {
let text = node.nodeValue;
// Do what you need to do with text here.
// You can copy the RegExp logic from the example above
// for simple text replacement. If you need to generate
// new DOM elements such as a <span> or <a> then remove
// this node from its .parentNode, generate the necessary
// objects then add them back to the .parentNode
}
else {
if (node.childNodes.length) {
for (let i=0; i<node.childNodes.length; i++) {
walkAndReplace(node.childNodes[i]); // recurse
}
}
}
}
walkAndReplace(document.body);

Remove selector criteria in variable value

I'm creating an online shop, with specific links to products e.g. (http://example.com/products/phones/nexus-5).
I'm using the following code,
var get_product_availability_classname = $("[class$='_availability']").attr('class');
which selects (creates a variable with the value of) the element that has a class ending in "_availability".
Every product page has a different piece of text just before the _availability, like GOOGLENEXUS5_availability, SAMSUNG4KTV_availability, whatever_availability...
What I have to do now is to essentially remove the criteria I used to get that whole class name (i.e. class$='_availability'); using the example above it'd be trimmed from SAMSUNG4KTV_availability to SAMSUNG4KTV.
Possible solutions
I haven't figured how to, but we could use JavaScript's substring() or substr().
You will be best off using Regex in this situation. The following will look for the _availability in the classes string and if it finds it it will capture what came before.
var get_product_availability_classname = $("[class$='_availability']").attr('class');
var matches = /([^\s]*)_availability\b/g.exec(get_product_availability_classname)
if(matches.length > 1){
var your_id = matches[1];
}
Use attr() method with a callback and update the class name using String#replace method with word boundary regex.
Although use attribute contains selector since there is a chance to have multiple classes, in that case, the class can be at the start or between two classes.
var get_product_availability_classname = $("[class*='_availability '],[class$='_availability']");
get_product_availability_classname.attr('class',function(i,v){
return v.replace(/_availability\b/g,'');
});
var get_product_availability_classname = $("[class*='_availability '],[class$='_availability']");
get_product_availability_classname.attr('class', function(i, v) {
return v.replace(/_availability\b/, '');
});
console.log(document.body.innerHTML);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="abc_availability"></div>
<div class="abc_availability class"></div>
<div class="class abc_availability"></div>
<div class="class abc_availability class1"></div>
If there will only ever be a single _ in the class name
var get_product_availability_classname = $("[class$='_availability']").attr('class')
.split(' ') // split the class to individual classes
.filter(function(cls) { // filter ones with _availability
return cls.split('_').pop() == 'availability');
})[0]; // use first match
var product = get_product_availability_classname.split('_')[0]
.split('_') creates an array ["PRODUCT", "availability"] and the [0] selects the first item of this array
alternatively you could also
var product = get_product_availability_classname.split('_availability')[0]
this does the same thing, except it splits on the string _availability, and it doesn't matter how many _ in the prefix
If your string is always in the form x_y, where x and y don't contain an underscore, then you can use the split function to split on the underscore.
var str = "SAMSUNG4KTV_availability";
var result = str.split("_")[0];
console.log(result);
The split function returns an array of strings containing the substring in between each underscore, you use [0] to select the first element in the array.

Javascript: string regex

I am calling a function getParentElm(idStr,element) which accepts an id and an element, and searches up the html tree until it finds a parent element which has an id equal to idStr.
Calling code:
var s = "someId";
var el = getParentElm(s,element);
I would like the idStr parameter to work with strings that match to "someId", for eg "someId123".
I tried :
var s = "/someId/";
but it did not work. Ideally, i do not want to touch the getParentElm function.
Update: Thanks vbranden.
I tried: var s = /someId/ and that worked. I upvoted your comment. Thanks all :)
no regex needed.
use closest to traverse up the dom, and id* to match id's which contains your idStr.
function getParentElm(idStr,element){
return $(element).closest('[id*="' + idStr + '"]');
}
Here, this should work :
function getParentElm(idStr,element) {
var patt = new RegExp(idStr +".*");
while(element.parentNode)
{
if(patt.test(element.parentNode.id))
return element.parentNode;
element=element.parentNode;
}
return false;
}
And just call the function in this way :
var el = getParentElm("someId",document.getElementById('foo'));

Replacing a substring of an element's text with another string

The Problem
I'm trying to use the JavaScript string replace method to replace some text in a div if it contains a certain string. However, my code does not replace the string inside that div.
The Javascript
function john(){
var NAME = "Johnny Buffet,";
var val = $("div#like-list-").text();
if ( val.indexOf(NAME) !== -1 ){
val.replace(NAME, '');
}
}
It doesn't work because .replace() is a String function and not a jQuery function; Strings in JavaScript are immutable, so .replac() returns the modified String which you then have to reassign to your element.
That said, you can use .text(fn) to perform the replacement in a single step:
$("div#like-list-").text(function(i, val) {
return val.replace(NAME, '');
});
Btw, I've removed the .indexOf() condition as well, because if NAME doesn't occur inside your string, the .replace() function will just return the original string.
You're editing the string, then simply throwing it away. Take the edited val and put it's contents back into the HTML element using a parameterized call to the text method.
function john(){
var NAME = "Johnny Buffet,";
var val = $("div#like-list-").text();
if ( val.indexOf(NAME) !== -1 ){
$("div#like-list-").text(val.replace(NAME, ''));
}
}
replace() is javascript not jQuery and you need to reset the value to variable after replace as replace() returns the updated text;
ie;
val = val.replace(NAME, '');
so try:
function john(){
var NAME = "Johnny Buffet,";
var val = $("div#like-list-").text();
if ( val.indexOf(NAME) !== -1 ){
val = val.replace(NAME, '');
}
}

Categories