Create new element from selector? - javascript

How can I create a new element using just a selector? (e.g. .myclass, #myid or a:not(.someclass)) Basically there is no way for you to tell if the element is a div, span, li, an anchor, if it's a div with a class or with an id and so on.
In jQuery I know you can do $(selector) to get a usable DOM object. But how can this be done in JavaScript?

In jQuery I know you can do $(selector) to get a usable DOM object...
Not to create one. jQuery will do a search in the DOM for existing matches. You can do $("<div>") and such (note that's HTML, not a CSS selector) to create elements, but jQuery doesn't have a feature for creating elements from CSS selectors.
But how can this be done in JavaScript?
You'll have to parse the selector, and then use document.createElement with the tag name, and then set any classes or other things the selector describes on the new element.
CSS selectors aren't very hard to parse. You'll be able to find a lib that does it. (jQuery has Sizzle, which is a selector engine, built in and Sizzle is open source. It will naturally have code to parse selectors.)

Mootools does this.
new Element('#name.class')
yields
<div id=​"name" class=​"class">​</div>​

The answer appears to be that there is no built-in way of doing this. Maybe there’s a library which does the job.
However, it’s not to hard to write a function to create an element from a simple selector:
/* createElementFromSelector(selector)
================================================
Usage: element#id.class#attribute=value
================================================ */
function createElementFromSelector(selector) {
var pattern = /^(.*?)(?:#(.*?))?(?:\.(.*?))?(?:#(.*?)(?:=(.*?))?)?$/;
var matches = selector.match(pattern);
var element = document.createElement(matches[1]||'div');
if(matches[2]) element.id = matches[2];
if(matches[3]) element.className = matches[3];
if(matches[4]) element.setAttribute(matches[4],matches[5]||'');
return element;
}
var testitems = [
'div#id.class#attribute=value',
'div#id.class#attribute',
'div',
'div#id',
'div.class',
'#id',
'.class',
'#id.class',
'#whatever'
];
testitems.forEach(item => {
var element = createElementFromSelector(item);
console.log(element);
});
The tricky part is the regular expression. You can see it in detail here: https://regex101.com/r/ASREb0/1 .
The function only accepts selectors in the form element#id.class#attribute=value with the any of components being optional, as you see in the test items. I think including pseudo classes is probably pushing the friendship, but you might like to modify it to include multiple real classes.

Related

How do we convert jQueryn $li.find('div.element:first') in VanillaJS

Does querySelectorAll() accept ('div.element:first') this type of argument? I need to convert below jQuery method in VanillaJS
jQUery :
$li = $(this)
$li.find('div.element:first')
Vanilla :
var li = event.target;
li.querySelectorAll('div.element:first');
But the Vanilla script is not working as same as jQuery. Someone please suggest any better solution
jQuery's :first reduces the set of matched elements to the first in the set.
In other words, you get the first element matching div.element.
To do the same in plain javascript, all you have to do is call querySelector without the All part
var first = li.querySelector('div.element');
As querySelector will return the first element that matches the specified selector anyway
This of course only works if li is a single element, querySelector doesn't work on collections the way jQuery's find() does.
If li is not a single element, you have to iterate, but since you're only looking for the first element, you could just do
var first = li[0].querySelector('div.element');

Select the child[ren] of an element as one would select the descendant[s]

Say I have an HTMLElement:
var hoop = otherLibrary.getHoop()
I can select its descentant[s] that are .stripey:
var stripedOnes = hoop.querySelectorAll('.stripey')
This is like the CSS rule:
#hoop .stripey {
However, how do I do the same for child[ren], without using jQuery?
var stripedChildren = hoop.querySelectorAll('> .stripey')
Doesn't work, although in jQuery/Sizzle it does. What would be the JS equivalent of this CSS rule?
#hoop > .stripey {
Well, the most straightforward way would be to use the full selector inside querySelectorAll()
document.querySelectorAll("#hoop > .stripey");
But, if answering your specific question...
I believe the fanciest way to select an element's children based on a selector is:
turn the .children collection into an array
Filter each element testing it against a selector using .matches()
So:
var hoop = document.getElementById("hoop");
var stripedChildren = [].slice.call(hoop.children).filter(function(element) {
return element.matches(".stripey");
});
You can use following -
document.querySelectorAll("#hoop > .stripey");

How to use css selector on SVGjs

I try multiple javascript libraries to work with svg
now i play with svgjs.dev
but i don't know how to use css selector like snapsvg
var result1 = Snap.select('#id_select');
var result2 = Snap.select('.class_selector');
what is the solution for svgjs ?
i can select childrens but i need make a loop to compare properties for every child :(
what is the shortcut fot get some element inner svg document?
thanks for your attention
You would use the get() method as per doc for id, or use jquery if needing a class
var element = SVG.get('my_element')
element.fill('#f06')
From SVG.js v2 it is possible to use selectors. It's what you would expect it to be:
var elements = SVG.select('rect.my-class').fill('#f06')
You can also search within a parent element:
var elements = group.select('rect.my-class').fill('#f06')
But as #Ian suggested, jQuery or Zepto are options as well. This is all described in the docs:
https://svgdotjs.github.io/referencing/#using-css-selectors

Selector ignoring elements contained in a specific element

I am currently working on a software plugin which scans a page for links in order to edit them. But there is a problem: I dont want to edit links that are contained in a specific element (in this case: an edit box). The elements contained in this edit box can also be nested, so parent might not be appropriate.
Is there any way to exclude elements via selector that are contained in a specific element?
You can run this plain JavaScript, it returns all elements with the matching pattern not in the container you specify.
var anchors = document.querySelectorAll('*:not(.editBox)>a.link');
Assuming your not wanted container has a class of "editBox" and you can change the matching "link" class to be any query selector you want, can be a plain 'a' for all anchor elements. I created a JSFiddle as a demo.
This doesn't all have to be on one selector. You could very simply use your regular selector to catch all the elements, and then execute a not() function to trim down the elements to only those you need.
var elems = $( "a" ); // all anchor links
elems = elems.not( ".ignore_me" ); // remove all links with the "ignore_me" class.
You could even combine these two into one command using function chaining:
var elems = $( "a" ).not( ".ignore_me" );
A third option that I feel is a little less readable would be something like this:
var elems = $( "a:not( .ignore_me )" );
References:
:not()
not()

What approach should I apply if I want to manipulate HTML/CSS without jQuery?

I'm trying to do some html/css manipulation without the help of a large library such as jQuery.
I'm using this code to know when the dom is ready, and call my functions from within that:
domready(function () {
functionOne();
})
How would I do changes to the DOM, e.g. remove/add classes to an element, and let it be aware of it such that I can do the following (on last line):
<div id="myElement" class="active"></div>
var linkElement = document.getElementById("myElement");
linkElement.className.replace(" active", " unactive");
elementByClass = document.getElementsByClassName("unactive")[0];
The answer depends on what browsers you want to support. The latest browsers already implement many jQuery features natively (querySelector, classlist, etc).
Your code is a good start but it doesn't work because replace doesn't change the string in place, it returns a new one.
<div id="myElement" class="active"></div>
var linkElement = document.getElementById("myElement");
linkElement.className = linkElement.className.replace(" active", " unactive");
elementByClass = document.getElementsByClassName("unactive")[0];
Take a look at classList to check a much more robust implementation of working with classes:
https://developer.mozilla.org/en-US/docs/Web/API/Element.classList
If your browser(s) supports Array extras and classList, do this:
elements = document.getElementsByClassName('existingClass');
elements.forEach(function(elem){
elem.classList.remove("existingClass");
elem.classList.add("newClass");
elem.classList.add("foo","bar");
});
Hope that helps.
You need to reassign the the DOM property that's it.
for example you can assign the classname property of DOM element as
document.getElementById("myElement").className = "myClassName";
You can useElement.setAttribute for setting all other Dom elements attributes.
try this code to assign class name to your DOM element.
document.getElementById("myElement").className = "myClassName";

Categories