i've been working on a project with puppeteer and it was going great so far until a tried to localize div's depending on their text.
I can't use the div id, name or class, i need to find it by the text inside of it.
My idea is to create an array of all the text i need to find and then loop trought the div's to find the ones that match any of the text in the array.
Can anybody help me find a solution? Thank you!
This is relatively straightforward using vanilla javascript (no JS libraries):
// Get an array of all <divs>:
let allDivs = [... document.getElementsByTagName('div')];
// Loop through allDivs, checking the text of each one:
allDivs.forEach((div) => {
let textInsideDiv = div.textContent;
// THE REST OF YOUR CODE HERE
// if (myArrayOfText.indexOf(textInsideDiv) > -1)) { etc.}
}
Related
Hi i am new to javascript and I am using a select element to create a table based on an array of dictionaries. I have the select element acting as a filter for the values. My problem is that when i change the value of the select element and it creates the table I want it to remove the previous table it appended so that It doesnt form a long list of tables. My on change code is as follows:
const filteredTable = document.getElementById("candidates_example");
const newFilteredTable = filteredTable.cloneNode(true);
removeRowsFromTable(newFilteredTable);
const filteredTbody = newFilteredTable.getElementsByTagName('tbody')[0];
const filterSelection = document.getElementById("filterSelect").value;
const selectFilter = filterCandidateBySkill(newCandidates, filterSelection)
addCandidatesToTable(filteredTbody,selectFilter);
document.body.appendChild(newFilteredTable);
I have tried googling the question I have but i do not know enough about javascript terminologies to know what the question is I need to ask. Thanks for any guidance offered.
You can replace the previous table with the new one using replaceChild:
replacedNode = parentNode.replaceChild(newChild, oldChild);
In your case, that would be :
document.body.replaceChild(newFilteredTable, filteredTable);
instead on append use .html() for jquery or document.getElementById('demo').innerHTML = tableVaiable;
You can use the functionality of .replaceWith() jQuery function.
.replaceWith()
I have the following use case using Office.js:
search for some text with body.search()
after finding the text, can be multiple occurrences, iterate through them and replace them with a ContentControl with a different content
The search part is easy, but I'm not sure about the second part. Inserting a ContentControl to the cursor position and manipulating it's HTML content isn't an issue, but I'm not sure if it's possible to programmatically select a string and then replace it with other content. Is it?
Or should I somehow create a ContentControl around the selected text and then just manipulate it's HTML content?
This is my code so far, within Word.run:
const res = context.document.body.search('[{]*[}]', {matchWildCards: true});
context.load(res, 'text');
return context.sync().then(() => {
const citeKeys = [];
for (let i = 0; i < res.items.length; i += 1) {
// iterate through found strings by accessing res.items[i].text
}
// ...
After you searched the strings, body.search will return a collection to you and you can loop the range collection and call range.insertText("...", "replace"). This insertText method will also return a range and then you can call range.insertContentControl on it. I think this will help you achieve the goal.
I am trying to find if a class exists and if not just find the first form element. How do I write :input? This does not seem to work.
$('.focus:not(:hidden):first, :input:not(:hidden):first').focus();
Comma-separated selectors are not hierarchical in the manner you seem to indicate. Your selector will yield the first visible .focus and the first visible input element. You'll need to break this up in two selectors:
var focusElement = $('.focus:visible:first');
if(focusElement.length == 0)
focusElement = $(':input:visible:first');
focusElement.focus();
Or I suppose you could write
$('.focus:visible:first, body:not(:has(.focus:visible)) :input:visible:first').focus();
Your code actually worked for me. Take a look at this jsfiddle. Try removing my class='focus' and it then falls back to selecting the first input field.
I would go for the easy to understand model:
var finder = $('.focus:not(:hidden):first');
finder = finder.length ? finder: $(':input:not(:hidden):first');
finder.focus();
Same result, but likely better given the right to left sizzle re: performance
var finder = $('.focus').not(':hidden').eq(0);
finder = finder.length ? finder: $(':input').not(':hidden').eq(0);
finder.focus();
In the following code, I'm working on a simple timer in JS. The problem is that the resulting code only shows one set of divider colons.
var divider = $('<span>').addClass('divider').text(':');
stopwatchFace = stopwatchFace.append(timeHour).append(divider)
.append(timeMin).append(divider).append(timeSec);
Is there a reason why the first one isn't being picked up? Should I be explicitly defining a divider1 and a divider2 object?
If you append an already-appended element, the result is that it is moved.
You need to clone the element. In vanilla JS, this would be as simple as divider.cloneNode(true).
In jQuery it's simple too: divider.clone(). Thanks Boaz for the info ^_^
Use need to clone divider. as divider is a dom single element cant exist two place at same time.
var divider = $('<span>').addClass('divider').text(':');
stopwatchFace = stopwatchFace.append(timeHour).append(divider.clone())
.append(timeMin).append(divider).append(timeSec);
I have an HTML web page full of divs and span tags identified with class that have lots of data I need in other format. I was wondering what would be the best way to do this with javascript.
Thank you for the help.
The fastest way? jQuery:
$(".myClass").each(function() {
// work with your data here
});
More lowlevel, but should be a lot faster (a lot less overhead):
var myelements = document.evaluate('//div[#class=myClass"]', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for (var i = 0; i < myelements.snapshotLength; i++) {
var dataElement = myelements.snapshotItem(i);
// work with your data here
}
(ok, you'd have to do it twice (once for div and once for span), it's more code and doesn't look as nice, but it should still be faster)
If you are wanting to get at all of the documents with a specific class then you will need to test for the presence of that class on each object. You will want to use a
document.getElementByTagName("*") // This should select everything
and loop through them to detect the proper name.
if (regex test == true) {
// you found an element that matches
// do what you will with it.
}
If you find the elements you need do what you need with them. Now you have processed all elements on the page and found elements that match your criteria. Good luck.