I have a div with id #test that contains lots of html, including some youtube-embeds etc.
Somewhere in this div there is this text: "[test]"
I need to replace that text with "(works!)".
The normal way of doing this would of course be:
document.getElementById("test").innerHTML = document.getElementById("test").replace("[test]","(works!)");
But the problem is that if i do that the youtube-embeds will reload, which is not acceptable.
Is there a way to do this?
You will have to target the specific elements rather than the parent block. Since the DOM is changing the videos are repainted to the DOM.
Maybe TextNode (textContent) will help you, MSDN documentation IE9, other browsers also should support it
Change your page so that
[test]
becomes
<span id="replace-me">[test]</span>
now use the following js to find and change it
document.getElementById('replace-me').text = '(works!)';
If you need to change more than one place, then use a class instead of an id and use document.getElementsByClassName and iterate over the returned elements and change them one by one.
Alternatively, you can use jQuery and do it even simpler like this:
$('#replace-me').text('(works!)');
Now for this single replacement using jQuery is probably overkill, but if you need to change multiple places (by class name), jQuery would definitely come in handy :)
Related
I am looking for a way to apply new CSS to only part of the element.
For example. The original HTML looks like
<p>123456</p>
I want to make only 456 into bold.
Of course, I can do it by adding another tag into 456 like
<p>123<b>456</b></p>
But in my application, I do want not to change the original DOM structure. By adding a new tag, I changed the DOM structure.
To do that, I am thinking of adding new custom attribute to the existing tag like
<p data-wms="e-3">123456</p>
Here data-wms means that there are special part and e-3 means that from index 3 character (it is 4 here) to the end will have a special attribute (like bold in this example)
Now I have all the information about where to change inside the element.
But still, how can I do that with javascript without adding a tag, without changing dom.
Thanks
You can use the span element to do so, it's made specifically to handle inline styling while mantaining the overall structure.
An example would be:
<p>123<span class="bold-highlight">456</span></p>
Thanks to everyone's advice, I researched more, especially about nth-letter.
Though nth-letter is exactly what I want, I found that it is still just proposal, not implemented in any browser.
Thus, there is no way to applying different css letter by letter in one text element without embracing each letter with span tag at this moment (2021-March). I hope that there will be nth-letter in the near future.
I think that I have to re-design my project...
if it's a static page and you want to change a style for specific text in a specific tag like the following case
<p>11111</p>
<p>22222</p>
<p>33333</p>
<p>44444</p>
let's say you want just style the third element, you can change it by the following code using jQuery for sure you can use JavaScript but jQuery will help you to make your code shorter
$( "p:nth-child(3)" ).css("color","#f00");
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 have the following javascript working to insert AJAX responses into a div with id results:
document.getElementById("results").innerHTML=xmlhttp.responseText;
However, this adds all new elements after those already present. I need for the new elements to be inserted before everything else.
I know this is probably very trivial but I can't seem to find anyway to do it myself.
Thanks for any help!
With modern js you can utilize the prepend method. Currently caniuse.com says only of IE, Edge, and OperaMini are not supported.
ParentNode.prepend(nodesToPrepend);
e.g.,
ParentNode.prepend(newDiv);
Also, it automatically converts text into a text node so you could do the following for your use case:
document.getElementById("results").prepend(xmlhttp.responseText);
You want either this
results.insertAdjacentHTML( 'beforebegin', xmlhttp.responseText );
or this
results.insertAdjacentHTML( 'afterbegin', xmlhttp.responseText );
(the variable results of course being a reference to the DOM element)
So, the first one will insert the new content before the element itself (as a previous sibling), and the second one will insert it inside the element before any other children).
I don't remember the exact syntax, but it something like:
var newDiv = document.createElement("div");
newDiv.innerHTML=xmlhttp.responseText;
document.getElementById("results").childNodes.addAt(0,newDiv);
if you can use jQuery, it's just simple as:
$("#results").prepend(xmlhttp.responseText);
I have been reading more lately about the efficiency of the different selector engines. I know that jQuery uses the Sizzle engine and this blog post about some jQuery stuff mentioned that the Sizzle engine will break apart your selector into an array then parse left to right.
It then, from right to left, begins deciphering each item with regular expressions. What this also means is that the right-most part of your selector should be as specific as possible — for instance, an id or tag name.
My question is whether it is more efficient to run a selector with just the ID specified or the tag name as well:
var div = $('#someId');
//OR
var div = $('div#someId');
Since I write my CSS in the div#someId form I tend to do my selectors the same way, am I causing Sizzle to perform extra work (assuming QuerySelectorAll is unavailable)?
jQuery and Sizzle optimize the #id selector [source] to document.getElementById(id). I think they aren't able to optimize it like this with the tag#id.
The first is faster.
BTW specifying the tag name for an #id selector is over-specifying, as there can be only one tag with a given id on the document. Over-specifying is slower even in CSS.
Rather than speculating, let's measure it!
Here's a test case with this page loaded, then matching a random element with both methods.
Make sure you scroll right down to the bottom.
http://jsperf.com/which-jquery-sizzle-selector-is-faster#runner
As you might expect, a plain id is faster than a tag qualified one (reduction to getElementByID). This is the same when using classes.
Selecting by ID is massively faster than selecting by class, mainly as IDs are guaranteed to be unique.
If you are using jQuery, you can assume a browser with getElementById. $('#someId') can be converted to document.getElementById('someId'). $('div#someId') won't be, so it will be faster to lose the tag name.
jsPerf demonstrating this. The difference is enormous.
var div = $('#someId'); //should be faster
jQuery will use getElementById() for the above selector
var div = $('div#someId'); //would probably preform slower due to finding all the divs first
jQuery will use getElementsByTagName(), then iterate though the array of elements for the above selector
You should also remember, tag names should definately be used with class selectors (whenever possible)
var div = $('div.myclass') //faster than the statement below
versus
var div = $('.myclass') //slower
JsPerf: http://jsperf.com/jquery-id-vs-tagname-id
The first one is going to be faster because it only has to check the id. The second one runs the same check AND has to make sure the tagname is correct. div#id won't give you the element with id id unless it is a div
You can see from the source code here: http://code.jquery.com/jquery-1.6.2.js in the function init.
The fastest selector is $('') which just returns an empty jQuery object immediately.
$('body') is next, which jQuery converts to document.body
The next is $('#id') which uses document.getElementById('id').
Any other selector such as $('div#id') will just become a call to $(document).find('div#id'). find() is very complex compared to any of those other solutions and uses Sizzle JS to select the div.
First post on stackoverflow. Hope everything is right!
I'm thinking of attaching an ID value to the HTML element itself via JavaScript, instead of using the HTML id attribute.
For instance, say that JavaScript variable htmlElement is a div. So htmlElement.cssName would tell us its CSS class.
Now, how about doing
htmlElement.idProperty = "someValue"
in JavaScript instead of doing <div id="someValue">? Then I can use the idProperty in say event handlers.
this.idProperty
That simple!
Is there something wrong in doing so?
EDIT: Thanks for yor answers! Very helpful and instructive. I wish I could check green on all of them!
no, you can do it the way you like it, if you are dynamically creating this item you should use this method, if you are doing this inside html I recommend you to just put the name of the id in html too.
However a small note. Use element.id instead of idProperty.
element.id = 'my-id';
You can use the createAttribute method to add an id to the element like this:
id = document.createAttribute('id');
id.value = "someValue";
htmlElement.setAttributeNode(id);
What you're doing there is adding a runtime property (in your case, called idProperty) to an HTMLElement object instance. You can get away with doing that in your JavaScript code (the Prototype library does it all the time). Makes me uncomfortable, but it does work on all major browsers.
If you want to be able to specify these in HTML markup as well, though, I'd use attributes instead. You can create attributes with any names you want, although to be careful I'd use names like data-xyz (e.g., use a data- prefix) as that's the HTML5 standard way of using your own attributes. Then you use getAttribute to get the value and setAttribute to set/update the value.