I've got this Regex /<h([2-4])>(.+)<\/h[2-4]>/g
It matches all h2,h3,h4 and captures the level and heading-text.
Is it good enough or do you see room for improvement in terms of speed and robustness?
Do not use regex on HTML. You can use Element.querySelectorAll. Replace Element with a reference to the DOM-element from which you like to select the headings.
var heading = document.querySelectorAll("h2, h3, h4");
QuerySelectorAll (and his brother querySelector) use CSS selectors to select elements from the DOM. You can supply multiple selectors using commas. This will select all h2-4 elements. You can loop them with this code:
Array.prototype.map.call(heading , function(element){
//do something with the element here.
console.log(element.textContent); //EXAMPLE, display the text in the element.
});
Since querySelectorAll returns a node list (which is an arrayish object) we can pass it to Array.map (though not directly). We use Array.prototype.map.call to pass the node list to the map function as array. Map loops over every element in the node list.
Make your regex to do a non-greedy match. And also make the regex to do back-referencing.
/<(h[2-4])>([^<>]+)<\/\1>/g
OR
/<(h[2-4])>((?:(?!<h\d+\b).)+?)<\/\1>/g
DEMO
Related
In our project, there is a different functionality when one Dollar sign used $() in Chrome console vs two Dollar signs $$(), besides the known difference that $$() return an array an $() return the first element.
For example, selector for specific element, with one dollar and two dollar queries:
$$(".my-class[my-attribute='trump']") //works
$('.my-class[my-attribute=sanders]') //works
$$('.my-class[my-attribute=trump]') //not work
What is the source and explanation for this behavior?
From Chrome Developer Tools documentation:
Selecting Elements
There are a few shortcuts for selecting elements. These save you valuable time when compared to typing out their standard counterparts.
$() Returns the first element that matches the specified CSS selector.
It is a shortcut for document.querySelector().
$$() Returns an array
of all the elements that match the specified CSS selector. This is an
alias for document.querySelectorAll()
$x() Returns an array of
elements that match the specified XPath.
When you use querySelector (or $), the result is an element or null. When you use $$, the result isn't an element but an Array which can be easily iterated over. This differs from the native querySelectorAll where it returns a NodeList which is slightly harder to go over all the entries.
Regarding the quote: of course it works the same. See:
Conclusion: It's useless to quote trump. You might also end insane.
Problem: using JQuery on HTML elements with Ids containing special characters.
Any special characters can be present anywhere within the Id. In 90% of the cases those are going to be spaces, full stops and dashes.
I think I found a Possible solution but can’t find any documentation that would support this.
Let’s say sElementId is an html element Id that has special characters in it.
Using the following syntax doesn’t work:
$('#'+sElementId).addClass("pointer");
but adding a pair of square brackets works like a charm:
$(['#'+sElementId]).addClass("pointer");
My question is. Is this the correct use of square brackets inside the selector?
Actually, it doesn't work, and does something you didn't expect.
From jQuery documentation:
jQuery( object )
object
Type: PlainObject
A plain object to wrap in a jQuery object.
So if you call $(["#a b"]) (or just $(["a"])) you'll get a jQuery wrapper object for that array-of-string. It looks like a typical jQuery selector object, but it isn't. addClass has no effect on that object.
$([1]).addClass("pointer") // no operation
To select the object, just use $(document.getElementById("a b")) ($() to convert it to a jQuery object).
Alternatively:
if there are multiple elements with the same id (note that this is invalid): javascript - Get multiple elements by Id - Stack Overflow
escape the id to use $(String.raw`#a\ b`) (or equivalently $("#a\\ b")): https://stackoverflow.com/a/4823616/5267751
In our project, there is a different functionality when one Dollar sign used $() in Chrome console vs two Dollar signs $$(), besides the known difference that $$() return an array an $() return the first element.
For example, selector for specific element, with one dollar and two dollar queries:
$$(".my-class[my-attribute='trump']") //works
$('.my-class[my-attribute=sanders]') //works
$$('.my-class[my-attribute=trump]') //not work
What is the source and explanation for this behavior?
From Chrome Developer Tools documentation:
Selecting Elements
There are a few shortcuts for selecting elements. These save you valuable time when compared to typing out their standard counterparts.
$() Returns the first element that matches the specified CSS selector.
It is a shortcut for document.querySelector().
$$() Returns an array
of all the elements that match the specified CSS selector. This is an
alias for document.querySelectorAll()
$x() Returns an array of
elements that match the specified XPath.
When you use querySelector (or $), the result is an element or null. When you use $$, the result isn't an element but an Array which can be easily iterated over. This differs from the native querySelectorAll where it returns a NodeList which is slightly harder to go over all the entries.
Regarding the quote: of course it works the same. See:
Conclusion: It's useless to quote trump. You might also end insane.
I stumbled upon this form of selector. Notice the quotes, its two attributes.
$('#item1','#item2')
It seems to return only first element, which is different from $('#item1, #item2') result. I couldn't find any documentation on what exactly this does. Can somebody explain this or link to documentation with examples please
It's called context, and it's the same as find(), so this:
$('#item1','#item2')
would equal :
$('#item2').find('#item1');
in other words, it searched inside #item2 for an element with the ID #item1
To select both elements with ID's #item1 and #item2, you would do:
$('#item1, #item2')
notice the difference in quotes.
Selector in Jquery $(param) supports single string parameter and then it split parameter string and then do work for selecting element..
$('#item1','#item2') //treat first one param
$('#item1,#item2') //treat one param and splits passed string and will select both
You can specify any number of selectors to combine into a single result.
This multiple expression combinator is an efficient way to select disparate elements.
multiple-selector
multiple-selector-2
var list = $("div,p,span").map(function () {
return this.tagName;
}).get().join(", ");
$("b").append(document.createTextNode(list));
I have a jQuery code as follows;
var favorites = $("#favorites");
var favoritesFooter = $("#favoritesFooter",favorites);
I am not sure what does the comma mean in the 2nd statement $("#favoritesFooter",favorites);
Also what would the following statement do or represent in the above case;
favoritesFooter.prev().after(newHTML);
It's the second parameter to $(). As explained in the documentation:
Selector Context
By default, selectors perform their searches within the DOM starting at the document root. However, an alternate context can be given for the search by using the optional second parameter to the $() function. For example, to do a search within an event handler, the search can be restricted like so:
$('div.foo').click(function() {
$('span', this).addClass('bar');
});
When the search for the span selector is restricted to the context of this, only spans within the clicked element will get the additional class.
Internally, selector context is implemented with the .find() method, so $('span', this) is equivalent to $(this).find('span').
The second statement means "search for element with ID of favoritesFooter inside the jQuery object favorites".
As you're dealing with ID which should be unique, it's pointless - $("#favoritesFooter") is the best practice.
Regarding favoritesFooter.prev() it's also pointless, assuming the ID is unique so you have collection with only one element thus prev() will return empty jQuery collection.
The .prev() will take the previous DOM element - in your case, it will push newHTML right before the favoritesFooter element.