How to hide specific sentence on page load with Javascript - javascript

I need to hide a specific sentence "The leader of tomorrow, are great" from the content below without calling any class or div.
Example:
<p>The leader of tomorrow, are great leaders</p>
<br>
The leader of tomorrow, are great leaders of tomorrow.
Any solution to this would be appreciated.

Why does jQuery('*:contains("sentence to hide")') not work on this scenario?
It will match all elements that contain the sentence. So it will match the closest node but in addition all parent nodes all the way up. So instead of matching element eg in this case the "P-node" it will also match for body, html and even the script itself if it is inline because it also contains the sentence! And if the element that actual contains the sentence to hide is wrapped by lets say:
<div id="_1">
<div id="_2">
<div id="_3">
<p id="_4">sentence to hide</p>
</div>
</div>
</div>
Then with jQuery('*:contains("sentence to hide")') you will get a jQuery collection with [{html}, {body}, {#_1}, {#_2}, {#_3}, {#_4}]
Here is another approach...
jQuery( document ).ready(function(){
jQuery('body').html(function(iIndex, sHtml) {
return sHtml.replace(/The leader of tomorrow, are great/g, '');
});
});
Or to have more control you can wrap the sentence and style the wrapper as you like...
jQuery( document ).ready(function(){
var sNeedle = 'The leader of tomorrow, are great';
jQuery('body').html(function(iIndex, sHtml) {
return sHtml.replace(
new RegExp(sNeedle, 'g'),
'<span class="hide-specific-sentence">' + sNeedle + '</span>'
);
});
});
and then in your CSS:
.hide-specific-sentence{
display: none;
}
NOTES:
I would not recommend to treat web content like this but if you have to for whatever reason you can do it this way
narrow the selcetor to the closest possible parent that actual contains the sentence(s) maybe ".content" or whatever
make shure that you do this action before anything else because
attached event handlers could get lost (depending on the way they are bound)
If you try the code as SO snippet you will get an error. This is propably due to some internal restrictions (I guess). But I tried it local and it works like a charme or you can try with this working PEN that also works like a charme...

jQuery has the contains-method. Here's a snippet for you:
<script type="text/javascript">
$(function() {
var result = $('*:contains("The leader of tomorrow, are great")');
});
</script>
The selector above selects any element that contains the target string. The result will be a jQuery object that contains any matched element. See the API information at: http://docs.jquery.com/Selectors/contains#text
One thing to note with the '*' wildcard is that you'll get all elements, including your html and body elements, which you probably don't want. That's why most of the examples at jQuery and other places use $('p:contains("The leader of tomorrow, are great")')

Related

jQuery selector is overlooking elements from a separate context

I'm making an ajax request to a page on my site with this element as a direct child of the body tag:
<div class="container" id="wantme"><div class="content"></div></div>
There's only one .container, and I want to grab its ID which I don't know.
As far as I can tell, this code should do what I want:
$.get('/page', function(data) {
id = $('.container', data).attr('id');
});
But the .container selector fails to find anything.
I did find these two workarounds. I can find .content, and I can climb up the tree like this:
id = $('.content', data).parent().attr('id');
But I can't leap directly there.
I found this workaround elsewhere on StackOverflow that works:
html = $('<div></div>').html(data);
id = html.find('.container').attr('id');
But why is it that the seemingly obvious answer doesn't work?
UPDATED ANSWER: I'll leave my original answer at the bottom, however I'm concerned it may misbehave depending on browser. jQuery's .html() makes use of Javascript's innerHTML - some browsers choose to strip <head> and <body> tags when using innerHTML, whereas others do not.
The safest method to achieve what you're after may still be the workaround you mentioned, like so:
var data = '<!doctype html><html><body><div class="container" id="findme"><div class="content"></div></div></body></html>';
var $container = $("<div />").html(data).find(".container");
var id = $container.attr("id");
console.log(id);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
More information as to the browser-related issues can be found here.
PREVIOUS ANSWER:
When you pass HTML to a jQuery element, it will ignore the <body> tags, as well as anything outside of them. Given the data string in your JSFiddle, $(data) will create something that looks like this:
<div class="container" id="findme">
<div class="content"></div>
</div>
As you can see in the HTML above, your .container isn't inside of $(data) - it is $(data).
Because $(data) is representing your .container element, you should just be able to do $(data).attr("id") to retrieve what you're after.
var data = '<!doctype html><html><body><div class="container" id="findme"><div class="content"></div></div></body></html>';
var id = $(data).attr('id');
console.log(id);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
You are not getting the ID from $('.container', data).attr('id'); is because you are setting the value of the second parameter. What you want to do is this: $('.container ' + data).attr('id');.
Update:
If data is a string then you should convert it into a DOM element: $('.container', $(data)).attr('id');

Replace every instance of a word in the dom with Javascript

I am trying to parse with a chrome extension I am making, and replace ever instance of one word with another. This is what I have that is not working for me
function jamify() {
$("body").html().replace(/James/g,"Jamie");
}
The quick and rather dirty replacement of .html() has a couple of downsides.
it will actually replace the entire DOM structure, removing any event bindings if these are not bound 'live' on an element higher up the hierarchy
it will replace a lot more than you may expect. You should be safe with 'James' to 'Jamie', but it may get funky when 'em' wants to be named 'emmy' and suddenly certain italic texts get straightened out.
A better way is to replace only strings in actual text nodes, as jQuery is not (currently) a tag on the question, I assume vanilla javascript is a proper option.
var walker = document.createTreeWalker(
document.body,
NodeFilter.SHOW_TEXT, {
acceptNode: function(node) {
return NodeFilter.FILTER_ACCEPT;
}
},
false
);
while (walker.nextNode()) {
walker.currentNode.data = walker.currentNode.data.replace(/James/g, 'Jamie');
}
<!-- James -->
<div data-name="James" class="James">
James
</div>
This example will only touch the actual text element(s), the comment and both the attributes (data-name and class) will not get replaced, so it remains safe to have javascript and/or css referring to these.
If the words are in the textContent you can try:
var all = document.querySelectorAll('.test')
//using .test as a wrapper section, try using body in production as selector (in the snippets it breaks)
all.forEach(x => x.textContent = x.textContent.replace(/James/gi, "Jamie"))
// keep in mind forEach for nodes has limited support, tested in chrome
<div class="test">
<p>James is here</p>
<div >this div is James</div>
</div>
I am showing it this way to show that you have to call some function to reset the html to the newly replaced string
NOTE: This will destroy any DOM event you had attached before the replace
you can shorten this by nesting the call all into one if you wanted
function jamify() {
var str = $(".test").html();
console.log('jamify', str);
str2 = str.replace(/James/g,"Jamie");
$(".test").html(str2);
//to simplify it could be done this way too
//$(".test").html($(".test").html().replace(/James/g,"Jamie"))
}
$(document).ready(function(){
//alert('ready');
$('.inner').click(function(){console.log('inner click')})
//Yea!, my click event is all good.
jamify();
//Now all your inner click EVENT is broken so this is not good
//solution if there are any events attached in your DOM
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="test">
<p>James is here</p>
<div class="inner">this div is James</div>
</div>

javascript replace text after the page has loaded

I want to remove/hide a piece of text that loads on my page.
The element doesn't have an id to relate to so I want to use a text-specific method.
Let's say the text is:"remove this line of text".
The html looks like this:
<div class="aClassName">
<p>
<strong>remove this line of text</strong>
... the rest of the content.
</p>
I have tried the following:
jQuery(document).ready(function($){
document.body.innerHTML = document.body.innerHTML.replace('remove this line of text', '');
});
Didn't work. So I tried this:
jQuery(document).ready(function($){
$("body").children().each(function () {
$(this).html( $(this).html().replace(/remove this line of text/g,"") );
});
});
Didn't work. The idea is that after the page is loaded it removes the line.It doesn't produces any errors as well. Not even in the firebug.
Anyone?
Target Elements Based On Their Content
You could accomplish this using the :contains() pseudoselector in jQuery that would allow you to target certain elements based on their contents :
$(function(){
// This will remove any strong elements that contain "remove this line of text"
$('strong:contains("remove this line of text")').remove();
});
You can see a working example of this here.
Broader Approach (Just Targets Elements Based On Selectors)
If you wanted a more simply target it by a more general selector (i.e. any <strong> tags that appear beneath a class called aClassName :
$('.aClassName strong').remove();
You can see an example of this approach here.
I guess you can use find() and text(), i.e.:
$('.aClassName').find('strong').text("123");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="aClassName">
<p>
<strong>remove this line of text</strong>
... the rest of the content.
</p>
Or simply:
$('strong:contains("remove this line of text")').text("New text");
Update:
After analyzing the link supplied on the comments, you can use the following:
$('.payment_method_mollie_wc_gateway_ideal').find('strong').text("");

jQuery "add" Only Evaluated When "appendTo" Called

this has been driving me crazy since yesterday afternoon. I am trying to concatenate two bodies of selected HTML using jQuery's "add" method. I am obviously missing something fundamental. Here's some sample code that illustrated the problem:
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
</head>
<body>
<p id="para1">This is a test.</p>
<p id="para2">This is also a test.</p>
<script>
var para1 = $("#para1").clone();
var para2 = $("#para2").clone();
var para3 = para1.add(para2);
alert("Joined para: " + para3.html());
para3.appendTo('body');
</script>
</body>
</html>
I need to do some more manipulation to "para3" before the append, but the alert above displays only the contents of "para1." However, the "appendTo appends the correct, "added" content of para1 and para2 (which subsequently appears on the page).
Any ideas what's going on here?
As per the $.add,
Create a new jQuery object with elements added to the set of matched elements.
Thus, after the add, $para3 represents a jQuery result set of two elements ~> [$para1, $para2]. Then, per $.html,
Get the HTML contents of the first element in the set of matched elements or set the HTML contents of every matched element.
So the HTML content of the first item in the jQuery result ($para1) is returned and subsequent elements (including $para2) are ignored. This behavior is consistent across jQuery "value reading" functions.
Reading $.appendTo will explain how it works differently from $.html.
A simple map and array-concat can be used to get the HTML of "all items in the result set":
$.map($para3, function (e) { return $(e).html() }).join("")
Array.prototype.map.call($para3, function (e) { return $(e).html() }).join("")
Or in this case, just:
$para1.html() + $para2.html()
Another approach would be to get the inner HTML of a parent Element, after the children have been added.

Is there a cross-browser css way to decorate only last word in a span block?

I need to show user's list which should look like in the example below:
Helen Burns Edward
Fairfax Rochester Bertha
Antoinetta Mason Adèle
Varens
Is there a way to achieve this without using javascript? Each row should be one span, i.e. <span>Helen</span><span>Burns</span> is not acceptable.
No, there is not. You are going to have to use some form of scripting to accomplish this if you don't want your last names to be in their own tags.
To the browser, each row is an element, and the "words" themselves have no separate meaning as far as CSS is concerned. You must place the words in different tags in order to do what you want.
The browser does not automagically know what part of the name is the last name so you have to add extra markup to achieve what you want.
There's no solution for common used browser for know using only CSS. You should use javascript or HTML + CSS as you already made.
without pure css this is impossible (as you don't want a separation in the markup)...
<span>Monty Burns</span><br />
<span>Bart Simpson</span>
<script type="text/javascript">
$(document).ready(function() {
var spans = $('span');
spans.each(function(index, element) {
var span = $(element);
var spanText = span.text();
var spanTextArray = spanText.split(' ');
var spanTextArrayLength = spanTextArray.length;
var lastName = spanTextArray[spanTextArrayLength -1];
spanTextArray.pop();
var firstName = spanTextArray.join(' ');
span.text(firstName);
var spanLastName = $('<span/>');
spanLastName.css('font-weight', 'bold');
spanLastName.css('margin-left', '5px');
spanLastName.appendTo(span);
spanLastName.text(lastName);
});
});
</script>
working demo.
edit: if you do not want an extra span-tag in there, just change
var spanLastName = $('<span/>');
spanLastName.css('font-weight', 'bold');
to
var spanLastName = $('<strong/>');
I don't think this is possible with CSS because your example doesn't show any order:
Helen Burns
Edward Fairfax Rochester
Bertha Antoinetta Mason
Adèle Varens
I don't know why you might desire not to have an extra tag surrounding the last name (as other answers and comments have suggested), but if you are looking simply for minimalist mark-up, this works (no span even used):
Html:
<body>
First Middle <strong>Last</strong>
First Middle <strong>Last</strong>
First Middle <strong>Last</strong>
</body>
Css:
strong:after {content:' '; display: block;}
Which creates "rows" with your desired styling without anything more than a single tag (which could be a span rather than a strong if you desired).
Edit: Of course, this will not work for IE7 or under.

Categories

Resources