I'm a beginner developer. I'm trying to hide a div that is dynamically added to the page by a 3rd party JavaScript for aesthetic purposes.
The problem is that the div has no id
attribute; is this even possible? Do divs have any inherent attributes based on the order in which they load? Or is there any way to search for a string of text and hide the element?
For example, removing <div>happy New year</div>
based on its text happy New year
.
You can select the relevant elements first and iterate through them until you find what you want.
In JQuery it can be done like this:
// select relevant elements
var elements = $('div');
// go through the elements and find the one with the value
elements.each(function(index, domElement) {
var $element = $(domElement);
// does the element have the text we're looking for?
if ($element.text() === "happy New year") {
$element.hide();
// hide the element with jQuery
return false;
// jump out of the each
}
});
Note that the code is a bit brittle and completely depends on the contents of the elements. Here are the relevant JQuery api docs:
$(...)
)jQuery.each()
- for going through the jquery objects arrayjQuery.text()
- for getting the value (there are small but noticable discrepancies between the browsers on how you do this in plain javascript)jQuery.hide()
- for hiding the element with CSS style display: none
Note that you can be more specific with your selection say you have the following code:
<div class="message">
<div>happy New year<div>
</div>
You can select the element with:
var domElement = $('.message div')[0]; // hopefully it only happens once
I thought I'd offer a plain-JavaScript alternative, which could be improved (quite a bit), particularly the passing of Booleans as strings (which feels hideous):
function hideByText(text, opts) {
if (!text) {
return false;
}
else {
var defaults = {
// the element we look within, expects:
// 1: node reference, eg the result of: document.getElementsByTagName('div')[0]
// 2: an element's id, as a string, eg: 'test'
'within': document.body,
// the element type, eg 'div', 'span', 'p', defaults to *everything*
'elemType': '*',
// case-sensitivity, as a string:
// 'true' : is case sensitive, 'Some' will not match 'some',
// 'false' : is case insensitive, 'Some' will match 'some'
'sensitive': 'true',
// 'absolute' : 'some text' will not match 'some text.'
// 'partial' : 'some text' will match 'some text.'
'match': 'absolute',
// 'true' : removes white-space from beginning, and end, of the text,
// 'false' : does not remove white-space
'trim': 'true',
// the class to add to elements if a match is made,
// use CSS to hide, or style, the matched elements
'matchedClass': 'hasText'
},
opts = opts || {};
for (var setting in defaults) {
if (defaults.hasOwnProperty(setting)) {
opts[setting] = opts[setting] || defaults[setting];
}
}
var within = opts.within.nodeType == 1 ? opts.within : document.getElementById(opts.within),
elems = within.getElementsByTagName(opts.elemType),
flags = opts.sensitive == 'true' ? 'i' : '',
needle = opts.trim == 'true' ? text.replace(/^(\s+) || (\s+)$/g, '') : text,
haystack,
reg = new RegExp(needle, flags);
if (opts.match == 'absolute') {
for (var i = 0, len = elems.length; i < len; i++) {
if ((elems[i].textContent || elems[i].innerText) == text) {
elems[i].className = opts.matchedClass;
}
}
}
else if (opts.match == 'partial') {
for (var i = 0, len = elems.length; i < len; i++) {
if ((elems[i].textContent || elems[i].innerText).match(reg)) {
elems[i].className = opts.matchedClass;
}
}
}
}
}
hideByText('some text', {
'match': 'partial',
'sensitive': 'true',
'elemType': 'p',
'matchedClass' : 'hasText'
});
JS Fiddle demo.
A previous answer will hide a node based on the combined text content (see .text()
behavior). The following test cases will illustrate this:
should stay: <div><em>happy New year</em></div><br>
should stay: <div>happy New years</div><br>
should stay: <div>happy New <em>year</em></div><br>
should stay: <div>Something else entirely</div><br>
should hide: <div>happy New year</div>
Shown here: jsFiddle
Depending on the details of your situation, this more general behavior may be what you want as it will ignore descendant structure and only match against the combined text. But, if you need to hide the <div>
that specifically contains the text, something like the following will hide only the last <div>
from the test cases:
var tx = 'happy New year';
$('div:contains(' + tx + ')').filter(function(){
var $content = $(this).contents();
return $content.length === 1 &&
$content[0].nodeType === 3 &&
$content.text() === tx;
}).hide();
Shown here: jsFiddle
The initial selector can be modified to hide anything that contains the specific text. This more general approach will hide the <em>
element in the first case and the <div>
element in the last case:
$(':contains(' + tx + ')').filter(// etc...
You might consider removing the element from the DOM instead of only hiding it.
:contains()
jQuery selector
.filter()
jQuery method
.contents()
jQuery method
nodeType
Node property
.remove()
jQuery method
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With