How to obtain a domNode by searching using classname instead of id? - javascript

I want to get a result exactly like dom.byId() returns, a domNode. However I cannot use id on my domNode. So my only other option is to search for it by class name instead of by id.
I tried
query(".classname").first()
because i know there is only one domNode that implements this class name
However I cannot use the result (which is a NodeList) in any subsequent functions in dojo that expect a domNode for example dojo/dom-geometry::position()

Well, If you want to access the nodes using class name.
below is the working code -
require(["dojo/query", "dojo/NodeList-traverse", "dojo/NodeList-dom", "dojo/domReady!"], function(query) {
query(".className").first().style({
"backgroundColor": "#FF0"
});
});
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"
data-dojo-config="async: true"></script>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css">
<ul>
<li class="className">First</li>
<li class="className">Second</li>
<li class="className">Third</li>
</ul>
JS Fiddle : https://jsfiddle.net/vikash2402/jfwsLnd4/
Feel free to shoot your further queries.
Hoping this will help you :)

Related

JQuery: dynamically update HTML so that it is recognized by JQuery

So, first of all, I am a newbie in Web (html/js)
What I want to achieve:
I have a custom tree and I want to be able to dynamically (using jquery) create children for that tree:
Html:
<ul>
<li>
Item
<input type="button" value="+" class="childAdder">
<ul class="childrenList"></ul>
</li>
</ul>
JS:
$(".childAdder").click(function() { // add child which is the same as root
$(this).parent().children(".childrenList").append(
'<li>Item</li>\
<input type="button" value="+" class="childAdder">\
<ul class="childrenList"></ul>'
);
});
And as you can see, I know how to add a child (more or less, an advice is always welcomed). The problem is, however, that this code only works for items that are "predefined" in html --> everytime I dynamically(via JS) add a child, this code just does not execute for this newly created element (tried to do alert('Hello'); - nothing is seen)
Question:
I assume I need to somehow "properly" add my new child to the DOM(?) of HTML or whatever, so that it is then recognized by JS, right? (but that seems to be only achieved trough HTML static page, no?)
Anyway, how do I make this thing work: add new child so that the same JS code that is executed for HTML element is executed for the element created by JS
is there a solution or the whole implementation is just wrong?
You need to use event delegation for this to work. This is done by using the on JQuery method for event wiring and modifying the parameters.
Also (FYI), a <ul> element can only contain <li> elements as children. Your bullet/nested list structure is invalid.
Lastly, in the HTML string you were appending included random \ characters, which are not needed and are actually invalid at those locations.
Here's the correct implementation with the HTML corrected to be valid.
// JQuery event delegation requires the use of the "on" method and then you
// bind the event to an object that is sure to always recieve the event (document
// works well here because of event bubbling). Then you specify the target element
// that the actual event will be triggered from.
$(document).on("click", ".childAdder" ,function() {
// add child which is the same as root
$(this).parent().children(".childrenList").append("<li>Item<br><input type='button' value='+' class='childAdder'><ul class='childrenList'></ul></li>");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<!-- <ul> and <ol> elements can only have <li> elements as thier children (aside from
comments like this one). To properly nest lists, organize the HTML as follows: -->
<li>Item<br>
<input type="button" value="+" class="childAdder">
<ul class="childrenList"></ul>
</li>
</ul>

Difference between .checked and .attr(checked,boolean)

I'm completely new in js and jquery. While trying to understand it, I've came up with an issue. But before that, I would like to apologise if my question contains subquestions.
First of all, I saw in this question that, .checked should be used with DOM objects while .attr() needs to be used with jquery objects. Now my question:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
</head>
<body>
<ul>
<li>List element 1</li>
<li>List element 2</li>
</ul>
checkbox1:<input type='checkbox' id='checkbox1'/>
checkbox2:<input type='checkbox' id='checkbox2'/>
<script>
var checkboxes=$('input');
checkboxes[1].checked=true;
</script>
</body>
</html>
IN here, Does checkboxes variable is a jquery object or dom element ? I was thinking that $() returns a jquery object (as stated here) but when I try, checkboxes.attr('checked',true) rather than checkboxes[1].checked=true; , I got error. My another assumption is that, may be checkboxes variable is a jquery object and checkboxes[1] is an dom element? Am I right?
Edit
One more question, when I want to learn type of a variable, I'm writing browser's console this statement : typeof(VariableName). Unfortunatelly, When I write typeof(checkboxes) or typeof(checkboxes1), I got always Object result. But just know I learn that one of them is Jquery object and the other is DOM object. Is there any function which gives me these differences?
one of them is Jquery object and the other is DOM object. Is there any
function which gives me these differences?
You can use:
obj instanceof jQuery
If you want more universal way you can use:
Object.prototype.toString.call(myVariable);

Storing object ID in HTML document: id vs data-id vs?

I would like to have an opinion on storing RESTful object IDs in document for accessing it later from JavaScript.
Theoretically speaking using id for addressing elements in HTML doesn't cut it anymore. Same element can be repeated twice on the page say in "Recent" and "Most Popular" queries which breaks the main point of using id.
HAML even has this nice syntax sugar:
%div[object]
becomes:
<div class="object" id="object_1">
But like I said, seems that it is not a good approach. So I am wondering what is the best way to store objects id in DOM?
Is this the current proper approach?
<div data-id="object_1">
An ID is intended to uniquely identify an element, so if you have a case where you want to identify two or more elements by some common identifier, you can use ID but it may not be the best option in your case.
You can use IDs like:
<div id="d0">Original Div</div>
<div id="d0-0">Copy of original div</div>
<div id="d1">Another original Div</div>
<div id="d1-0">Another copy of original div</div>
<div id="d1-1">Another copy of original div</div>
and get all the d1 elements using:
document.querySelectorAll('[id^=d1]');
or just d1 divs:
document.querySelectorAll('div[id^=d1]')
You could also use a class:
<div id="d0" class="d0">Original Div</div>
<div id="..." class="d0">Copy of original div</div>
<div id="d1" class="d1">Another original Div</div>
<div id="..." class="d1">Another copy of original div</div>
<div id="..." class="d1">Another copy of original div</div>
and:
document.querySelectorAll('.d1')
Or use data- attributes the same way. Whatever suits.
You can also have a kind of MVC architecture where an object stores element relationships through references based on ID or whatever. Just think outside the box a bit.
The purpose why data-selectors where introduces is because the users neednt want to use class or anyother attributes to store value.Kindly use data-selectors itself. In order to make it easy to access them use attributes selector i.e. [attribute='value']. PFB the fiddle for the same and also the example
jsfiddle
<!DOCTYPE html>
<html>
<head>
<script src="//code.jquery.com/jquery-git2.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body onload="call()">
<div id="1" data-check='1'></div>
<div id="2" data-check='1'>sdf</div>
<div data-check='1'>sdf</div>
<div data-check='1'>sdf</div>
<div data-check='1'>sdf</div>
</body>
</html>
function call()
{
$("#1").html($('[data-check="1"]').length);
$("#2").html( document.querySelectorAll('[data-check="1"]').length);
}
Output: 5 5 sdf sdf sdf
#RobG is right by using 'class' you can get array of elements in JavaScript as-
var divs=document.getElelementsByClassName("className");
\\And you can loop through it(`divs[i]`).
AND according to #RobG and #Barmar data-* attribute is also a good option.
But here is some point(just point, not negative or positive, its totally depends on your application need) I want to discuss:
1] data-* element is HTML5's new attribute. Documentation
2] To retrieve elements in javascript, You need to use jQuery or more bit of JavaScript, coz all direct function available have specific browser support:
Like document.querySelector("CSS selector"); IE8+
document.getElementsByClassName("className"). IE9+
document.querySelectorAll("CSS selector"); etc.
So, basically for this point you need to choose according to your app need and browser compatibility.
3] Performance issue is also there on selecting by data-* attribute... Source
But, generally and if we go for latest application and selecting HTML5, data-* attribute + jQuery is a good option.
I was wondering about this too. Here's my POV using an example component.
CSS - styling across all buttons
Elements should not be referenced in JS using CSS classes because if you have multiple buttons that need to function differently, adding unique CSS classes for each component will get messy.
<div class="my-component">
JS - Grab the component when it can only appear once on a page
While browsers may handle multiple id okay, it would harm maintenance since this would be unexpected behavior from an id.
<div id="my-component">
const myComponent = document.querySelector('#my-component')
JS - Grab the component when it can appear multiple times on a page
ref or data-id could both work. ref has been popularized by React and Vue, so it may be more familiar to developers.
<div ref="my-component">
const myComponents = document.querySelectorAll('[ref="my-component"]')
or
<div data-id="my-component">
const myComponents = document.querySelectorAll('[data-id="my-component"]')

Extract all classes from body element of AJAX-ed page and replace current page's body classes

I am in the process of AJAX-ing a WordPress theme with a persistent music player. Wordpress uses dynamic classes on the <body> tag. The basic structure is as follows:
<html>
<head>
</head>
<body class="unique-class-1 unique-class-2 unique-class-3">
<div id="site-container">
<nav class="nav-primary">
Other Page 01
Other Page 02
</nav>
<div class="site-inner">
<p>Site Content Here</p>
</div>
</div>
<div id="music-player"></div>
</body>
</html>
I am currently successfully loading the content of /other-page-01/, /other-page-02/, etc, using load('/other-page-01/ #site-container'). However, I need to extract all <body> classes from the AJAX loaded page and replace the current page's <body> classes with them dynamically.
Note: Replacing the entire <body> element is not an option due to the persistent <div id="music-player">. I've tried jQuery.get(), but couldn't get it to work.
How do I extract the <body> classes from the AJAX requested page and replace the current page's <body> classes with them?
I am not very familiar with jQuery or Javascript, so the exact code would be extremely helpful. Any help is greatly appreciated.
Thanks,
Aaron
My typical solution would have been to tell you to throw the AJAX code in to a jQuery object and then read it out like normal:
$(ajaxResult).attr('class');
Interestingly though, it appears you can't do this with a <body> element.
I'd say the easiest solution (if you have control over the resulting HTML) is to just use some good ol' regex:
var matches = ajaxResult.match(/<body.*class=["']([^"']*)["'].*>/),
classes = matches && matches[1];
I say "if you have control over the resulting HTML", because this relies on the HTML being reasonably well formed.
The other method would involve parsing it as a DOMDocument and then extracting what you need, but this would take a lot more and is usually overkill in simple cases like this.
Convert the body within your returned html to a div with a specific ID, then target that id to get the classes of the body (which is now a div.)
modifiedAjaxResult = ajaxResult.replace(/<body/i,'<div id="re_body"')
.replace(/<\/body/i,'</div');
$(modifiedAjaxResult).filter("#re_body").attr("class");
Of course, if the body has an id, this will conflict with it, so an arbitrary data attribute might be less likely to break.
modifiedAjaxResult = ajaxResult.replace(/<body/i,'<div data-re-id="re_body"')
.replace(/<\/body/i,'</div');
$(modifiedAjaxResult).filter("[data-re-id=re_body]").attr("class");
http://jsfiddle.net/N68St/
Of course, to use this method, you'll have to switch to using $.get instead.
$.get("/other-page-01/",function(ajaxResult){
var modifiedAjaxResult = ajaxResult.replace(/<body/i,'<div data-re-id="re_body"')
.replace(/<\/body/i,'</div');
alert($(modifiedAjaxResult).filter("[data-re-id=re_body]").attr("class"));
// the following line replicates what `.load` was doing.
$(someElement).append( $("<div>").html(ajaxResult).find("#site-container") );
});

get method isn't returning results

I'm trying to simply reproduce what is on the jquery site for the .get method:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
</head>
<body>
<ul>
<li id="foo">foo</li>
<li id="bar">bar</li>
</ul>
<script type="text/javascript">
alert($('li').get());
</script>
</body>
</html>
It should return
[<li id="foo">, <li id="bar">]
But all I get is [object HTMLLIElement],[object HTMLLIElement]
Does anybody know what I might be doing wrong here?
Everything is alright:
The .get() method grants us access to the DOM nodes underlying each
jQuery object.
Get returns the DOM elements hold by the jQuery variable.
And when you output DomElements they become the form "HTMLLIElement".
But that's what .get does! It will retrieve the HTML DOM elements matched by the selector. If you want the jQuery objects, you should use just $('li').
Simple, select the ul element and display it's content with the html function:
alert($('ul').html());
html docs:
Description: Get the HTML contents of the first element in the set of matched elements.
You're not necessarily doing anything wrong.
What you're getting is the actual result of calling toString (which alert will do for you) on an array with 2 <li> DOM objects in it:
[object HTMLLIElement],[object HTMLLIElement]
However, what's mentioned in the API Documents isn't a string representation of the array, but is meant as a description of the array's current state in memory:
[<li id="foo">, <li id="bar">]
It was meant just as a shorter way of saying something like this:
The result is an array with 2 DOM objects that represent the <li id="foo"> and <li id="bar"> elements, respectively.
Now, if you actually want to get the markup in the alert, you'll have to get the outer HTML of the elements. Then try:
alert($('li').map(function () { return $(this).outerHTML(); }).get());
Example: http://jsfiddle.net/cmpwM/

Categories