I'd need to search the DOM, possibly inside a div with id="#box", to avoid searching the whole document, for the recurrence of given "<div><br></div>"
and delete all of em if any.
I'm trying with:
$('#box').html($('#box').html().replace(/<div><br><\/div>/g,''));
...but I have the impression it's deleting all divs whatsoever.
I also don't like the idea of using a regex for this.
You could use remove() instead along with a filter that checks for only a single child <br>
Something like
$('#box div').has('br').filter(function(){
return $(this).children().length === 1;
}).remove()
Related
I am selecting a group of table rows by using the following line of JS:
document.getElementById('tab1_content').contentDocument.documentElement.getElementsByClassName("data1_smaller")
These represent entries in a table of contents. I want to return only those above which also contain the word 'CHAPTER', so I was attempting to use the jQuery :contains() selector to accomplish this and attempted to convert the entire thing into a single jQuery selector; so, to begin with, I tried converting the following invalid line:
document.getElementById('tab1_content').contentDocument.documentElement.getElementsByClassName("data1_smaller").$(":contains('CHAPTER')")
to this:
$("#tab1_content > contentDocument > documentElement > .data1_smaller:contains('CHAPTER')")
The selector above doesn't give an error but it fails to find anything. Does anybody know the correct way to do this?
You can achieve what you want with pure vanilla js just like you tried in the beginning. You just need to do some small adjustments to your code. You can use querySelectorAll() to query all elements matching a selector inside your ID. Something like this should work just by looking at your example, but might need some small adjustments.
[...document.getElementById('tab1_content').querySelectorAll(".data1_smaller")].filter((node) => node.textContent.includes('CHAPTER'))
// Edit, saw in the comments that you're accessing content in an iframe
[...document.getElementById('tab1_content').contentWindow.document.querySelectorAll(".data1_smaller")].filter((node) => node.textContent.includes('CHAPTER'))
I found this solution based on Anurag Srivastava's comments:
$("#tab1_content").contents().find(".data1_smaller:contains('CHAPTER')")
The issue was that I was trying to select things that are inside of an iframe and the the .contentDocument.documentElement that I used to access the iframe in JS has to be changed to .contents() in jQuery in order for it to work.
Neither contentDocument or documentElement are valid HTML tags. Try to select by id or class name.
I've been trying to search for a word and add a span to it in order to give it some styling and functionality, and I've found a method of doing this, but it isn't very effective.
I have a content script that is searching for the word searching and then I replace the innerHTML with an added span to the keyword.
This is my JS file:
function getText(){
return document.body.innerText
}
if(getText().indexOf("searching") > -1) {
document.body.innerHTML = document.body.innerHTML.replace(new RegExp("searching", "g"),"<span class='spanDetected' id='spanDetected'>"+
'searching'+"</span>");
console.log("true");
}
And this is what the outcome is:
So it seems to work on some level, but then the problem arises that it also changes URLS and Textboxes, like so:
What is a better way of styling and adding functionality to a word?
Using Regex to parse [X]HTML is a terrible idea. Imagine the following HTML:
<div id="searching">A searching inspection</div>
Your program would replace both instances of the phrase 'searching', which is not what you want. You need to parse the page and replace the nodes intelligently. Perhaps ignore hyperlinks or use an overlay div for the hyperlink nodes
You have two options:
Traverse through all nodes recursively.
Use XPath to select the nodes that contain a specific text.
Something like this can get you all the nodes that contain the phrase 'searching'.
//text()[contains(., 'searching')]
Then you can loop through all the nodes and replace the one you want. Since you are developing a Chrome extension you can use $x to get the array of nodes that meet your XPath conditions:
$x("//text()[contains(., 'searching')]")
Read this answer to learn how you can loop through the items in the array.
I'd like to hide (remove) all <div> that contain a certain string. Like a filter. Think of it having the functionality of a browser add-on.
Basically anything that is
Within a tag within the div, or
Immediately inside the div (but not a tag)
Any ideas of how to best do this efficiently? Ideally I'd like a way to have the browser respond well to this by not only hiding the div, but removing it in such a way that the page has no large blank spaces.
I'm really not super fluent in javascript, so thought I'd see if I could get some pointers here. (And is better to use straight JS or JQuery?)
thanks!
First, make a plan:
Find all the nodes that have the phrase. This SO Q will help.
For each node you find, go up the dom tree until you find the first enclosing div to remove. See JQuery dom transversal helpers
Then remove the appropriate divs. You may want to animate their removal, use jquery for that too.
Re: Use jquery? Up to you. If you want your code to work on multiple browsers then jquery will help. Your problem can be solved with or without jquery.
Good luck.
Try my JQuery plugin searchEngine
Syntax
$(selector).searchengine(textFilter,action,caseSensitive)
For your case , invoke it as following :
var myTxt="dfvdf...."
$('div').searchengine(myTxt,'remove',false);
If you want to remove also all <p> that contains myTxt :
$('div,p').searchengine(myTxt,'remove',false);
if you want to hide it instead of removing it :
$('div').searchengine(myTxt,'hide',false);
if you want to show it after that :
$('div').searchengine(myTxt,'show',false);
and so forth
Demo : http://jsfiddle.net/abdennour/k3x53/1/
Hacked together from this answer: Get all visible DIVs on a page with javascript?
This is fairly simple with jQuery, but you requested non-jquery so I will give it a quick go:
function removeDivs(withString) {
var divs = document.getElementsByTagName("DIV");
for(var i = 0; i < divs.length; i++) {
div = divs[i];
if (div.style.display != "none" && div.innerHTML.indexOf(withString) > -1) {
div.style.display = "none";
}
}
}
I would note that you said "phrase inside them", but did not specify the level to which you wanted to find out that the phrase is inside. In the case of nested divs, this will hide all the divs as far up as it can go that have the phrase in their innerHTML. In other words, since innerHTML contains all the contained divs, any div containing a div that has the phrase in it will also be hidden, and so forth on up the tree.
Another note, this is not efficient at all in that it probably will end up redundantly hiding divs that don't need to be hidden.
If I were to do it, I would use jQuery and try to get something a little more efficient...it would be re-inventing the wheel not to IMHO (unless there are technical restrictions or browser restrictions that prevent jQuery from running).
I want to write a select something like...
#window_4 > content > p:eq(0)
I think I have this correct, but I have a few selectors that are all similar but I can't test them all at once.
Am I right in saying this is selecting an element, who is the fist p tag child of a content tag that is a child of a tag with id 'window_4'
If I have gotten this wrong, can you give me some pointers. Would love to be able to simplify this code, I have more code selecting the tag I am after then actually doing stuff with them.
Looks good to me, although you can make it a bit more readable by substituting p:eq(0) for p:first.
Edit for comment:
jQuery always returns an array of elements, no matter whether 0, 1 or many elements were found. On these elements, yes, you can perform JS functions, such as innerHTML. You can access each element returned by jQuery just as if you would any other array:
$(".red")[0].innerHTML = "Glen Crawford";
More info: http://groups.google.com/group/jquery-ui/browse_thread/thread/34551a757f139ae1/20111f82c2596426
Is there any direct way in JavaScript or jQuery to check if an element is within another one.
I'm not referring to the $(this).parent as the element I wish to find can be a random number steps lower in the tree of elements.
As an example, I would like to check if < div id="THIS DIV"> would be within < div id="THIS PARENT">:
<div id="THIS_PARENT">
<div id="random">
<div id="random">
<div id="random">
<div id="THIS_DIV">
(... close all divs ...)
So in pseudo code:
if($("div#THIS_DIV").isWithin("div#THIS_PARENT")) ...
If there isn't any direct way I'll probably do a function for this but still it's worth asking.
You could do this:
if($('#THIS_DIV','#THIS_PARENT').length == 1) {
}
By specifying a context for the search (the second argument) we are basically saying "look for an element with an ID of #THIS_DIV within an element with ID of #THIS_PARENT". This is the most succint way of doing it using jQuery.
We could also write it like this, using find, if it makes more sense to you:
if($('#THIS_PARENT').find('#THIS_DIV').length == 1) {
}
Or like this, using parents, if you want to search from the child upwards:
if($('#THIS_DIV').parents('#THIS_PARENT').length == 1) {
}
Any of these should work fine. The length bit is necessary to make sure the length of the "search" is > 0. I would of course personally recommend you go with the first one as it's the simplest.
Also, if you are referring to an element by ID it's not necessary (although of course perfectly okay) to preface the selector with the tag name. As far as speed, though, it doesn't really help as jQuery is going to use the native getElementById() internally. Using the tag name is only important when selecting by class, as div.myclass is much, much faster than .myclass if only <div> elements are going to have the particular class.
With jQuery >=1.4 (2010) you can use the very fast function jQuery.contains()
This static method works with DOM elements, not with jQuery elements and returns true or false.
jQuery.contains( container, descendant )
Example: To check if a element is in the document you could do this:
jQuery.contains( document.body, myElement )