Difference between jquery $('#my_id') and document.getElementById('my_id')? - javascript

I tought $('#my_id1') was the same thing as document.getElementById('my_id1'). But it is parently not. What is the difference?
(function( $ ) {
$.fn.simple_hide_function = function() {
var $t = this;
$t.hide();
};
})( jQuery );
$(window).load(function () {
var $div1 = $('#my_id1');
var $div2 = document.getElementById('my_id2');
$div1.simple_hide_function(); // this is working
$div2.simple_hide_function(); // but this is not working
});
Adding example to make it more clear:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>
<body>
<div id="my_id1" style="height:100px;background:#f00">div1</div>
<div id="my_id2" style="height:100px;background:#f00">div2</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script>
(function( $ ) {
$.fn.simple_hide_function = function() {
var $t = this;
$t.hide();
};
})( jQuery );
$(window).load(function () {
var $div1 = $('#my_id1');
var $div2 = document.getElementById('my_id2');
$div1.simple_hide_function();
$div2.simple_hide_function();
});
</script>
</body>
</html>

Difference is that first one returns a jquery object while the second returns a DOM element.
But these statements are equivalent:
document.getElementById('my_id2') <-> $('#my_id1').get(0)
or
document.getElementById('my_id2') <-> $('#my_id1')[0]

The first returns a jQuery object with that div as its only member. You can use jQuery functions on the object to manipulate it.
The second returns a DOMElement using the browser's built-in methods.

$('#my_id1') // Returns a jQuery object
And
getElementById('my_id1') // Returns a DOM object.
To get the DOM object of a jQuery object, you can call:
$('#my_id1').get()
jQuery can match more than one object with a selector, so to get the second matching DOM element:
$('#my_id1').get(1) // 1 = item #2 (zero-based index)
And to get matching DOM elements from the END of the collection, you can use a negative number, the distance from the end of the matched elements you want to retrieve, so -1 gets the last item.
$('#my_id1').get(-1) // gets the last item of the matched elements

Use my_id1:
var $div2 = document.getElementById('my_id1');

According to me, there is difference in its rendering in Browsers.
As if we do not use document. This will not work in IE browsers.
But only work in other browsers.

Related

Proper Place to Bind Object to Element

Data Attributes are a safe place to store strings onto a DOM element, because you're guaranteed that your property-naming will never collide with a future property that gets added to the DOM specification.
However, what if you want to bind a non-JSON javascript object to an DOM element as a property?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Bind Custom Object to DOM Element</title>
<style>
div{ border: solid #333333 1vmin; padding:1vmin;
display:inline-block; font-size:4vmin}
</style>
<script type="text/javascript">
function main()
{
let obj = {}
obj.name = "Lonnie";
let div = document.createElement("div");
div.textContent = "Click Me";
div.myCustomObject = obj;
div.addEventListener('click',function()
{
alert(this.myCustomObject.name);
});
document.body.appendChild(div);
}
window.addEventListener('load', main);
</script>
</head>
<body>
</body>
</html>
Data attributes are designed to hold strings, not objects. Is it ok to use them for nonJSON object-properties, or does the specification recommend a different location for adding object-properties to DOM nodes?
Data attributes are designed to hold strings, not objects.
But you are not using attributes. Therefore you can store everything you want under a regular property.
Is it ok to use them for nonJSON object-properties,
Sure.
or does the specification recommend a different location for adding object-properties to DOM nodes?
No, it does not. the DOM spec is language neutral, therefore it doesn't really describe how objects in JS behave that implement that spec.
I would use a WeakMap solution using ES6:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Bind Custom Object to DOM Element</title>
<style>
div{ border: solid #333333 1vmin; padding:1vmin;
display:inline-block; font-size:4vmin}
</style>
<script type="text/javascript">
async function main()
{
let obj = {}
obj.name = "Lonnie";
let obj2 = {}
obj2.name = "Mark"
let div = document.createElement("div");
div.textContent = "Click Me";
div.myCustomObject = obj;
const wm = new WeakMap();
wm.set(div, obj);
wm.set(div, obj2);
console.log(wm.get(div)); // "my value"
div.addEventListener('click',function()
{
alert(wm.get(div).name);
});
document.body.appendChild(div);
}
window.addEventListener('load', main);
</script>
</head>
<body>
</body>
</html>
This method ensures there are no clashes between property names.
Personally I don’t see any issue with binding it to an attribute however and there doesn’t seem to be any advice against doing so, it’s the data attributes that are meant to contain strings

Bind methods on appended elements

I have an AgentClass with the method this.move. It's working with static objects but when I create new HTML Objects via .append(), I can't use them with my this.move method.
All the new objects have an ID and I want to animate them with the move method.
I often read "live, on, ..." but they all need an event... I don't have such an event on them. They move directly. I tried something like that:
$('.agents').on("load", Agent.move());
But that isn't working... Any ideas?
Codesinppet:
var Agent = function(agentType, xTarget, yTarget) {
...
this.move = function() {
var id = this.agentId;
$('.agent#'+id).animate({
left:"200px"
}, 1000);
}
}
And I append them after this like this:
for (deployed = 0; deployed <= agents; deployed++) {
$('.agents').append('<div class="agent" id="'+deployed+'"></div>');
}
It would be awesome if someone could help me!?
You can use .clone(true)
A Boolean indicating whether event handlers and data should be copied along with the elements. The default value is false.
var agents = 6;
for (deployed = 0; deployed <= agents; deployed++) {
$element = $('<div class="agent" id="'+deployed+'"></div>').clone(true);
$('.agents').append($element);
}
.agent {
height:50px;
width:50px;
background-color:yellow;
margin-bottom:10px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<title>Agent</title>
</head>
<body>
<div class="agents">
</div>
</body>
</html>
But for maximum optimization event is better to use an event handler "on" to monitor the items that will be added after reloading the DOM .
This allocates less memory

how to fix the closure bug in my jQuery code

the page always alert "btn2" ,whenever I click btn1 or btn2. it's seem the problem caused the "click" closures.but I don't know how to fixed it.
thanks in advance.
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>untitled</title>
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<script>
(function(){
$.fn.test = function(){
F.init.apply(this,arguments)
};
var F ={
that:null,
init:function(){
F.that = this;
$(F.that).click(function(e) {
F.method();
});
},
method:function(){
var text =$(F.that).html();
alert(text);
}
}
})();
$(function(){
$("#btn1").test(); //alert btn2---bug
$("#btn2").test(); //alert btn2
});
</script>
</head>
<body>
<button id="btn1">btn1</button>
<button id="btn2">btn2</button>
</body>
</html>
You have referred to your object class F by that name from within the class.
Your line F.that = this is effectively therefore creating what would in other OO languages be considered a "static member" of the class, so both #btn2 and #btn1 ended up sharing the same that member.
Furthermore, your click handler is trying to call F.method() - in effect also a static method call.
You'll need to create a new object of type F each time you wish to wrap it around an element. Only then will you get a separate this for each element.
I suggest using an off-the-shelf jQuery plugin model such as http://jqueryboilerplate.com/ instead of trying to invent your own. See this extract from that code:
$.fn[ pluginName ] = function ( options ) {
return this.each(function() {
if ( !$.data( this, "plugin_" + pluginName ) ) {
$.data( this, "plugin_" + pluginName, new Plugin( this, options ) );
}
});
};
Note how it uses new Plugin to create the plugin instance, and then stores it on the element using $.data, but only the first time the plugin is invoked against each element.
1)F is a static Object
2)So F.that is also static
3)so
F.that = this
line will set 'this' to F.that.
4)first time you call
$("#btn1").test();
then F.that will be equal to $("#btn1");//this will be equal to $("#btn1")
5)Next time you call
$("#btn2").test();
then F.that will be equal to $("#btn2");//this will be equal to $("#btn2")
6) So finally to F.that you are setting $("#btn2")
7)hence the $(F.that).html(); is essentially $($("#btn2").html()) which is further same as $("#btn2").html()
8)Hence alert is showing "btn2"

How to add click event to an element?

I would like to add a click event in plain JavaScript (without using jQuery) to an element like this, so I don't have an id but a class:
Yummy
If you don't have an id and don't have any selector library and you want it to work in older browsers, then it takes a bit more work. If you can put an id on it, it's quite simple. If not, it takes more code:
var links = document.getElementsByClassName("MyClass");
links[0].onclick = function() {
// put your click handling code here
// return(false) if you don't want default click behavior for the link
}
Since getElementsByClassName is not universally available in older browsers, you would need a shim to implement it when not present. Or, you could get all the links in your document with:
var links = document.getElementsByTagName("a");
and then cycle through that list until you find the one you want (perhaps checking the class name).
If you can put an ID on the link:
<a href="http://braza.com/share" id="specialLink" class="MyClass" >Yummy</a>
Then, it just takes this code:
document.getElementById("specialLink").onclick = function() {
// add code here
}
If you're going to do this regularly, the adding an event listener is a little more extensible than using the onclick property, but if you don't have any framework, then you need a function for adding an event listener that handles older versions of IE.
There can be several ways of doing this.
One is you add the click event right in the anchor
as: <a href='' onclick='yourFunct()'> Yummy </a>
The other way can be using document.getElementsByTagName('a') you can get reference to all the href's as array then you can chose that particular href and add click event to it.
like: document.getElementsByTagName('a')[0].click = function(){ }
here 0 is just symbolic if u know the exact place in array you can give that index.
The third way can be you can write a custom. document.getElementsByClassName function in javascript and use it similiarly. You can find a number of implementations of getElementsByClassName by searching google.
look at http://robertnyman.com/2005/11/07/the-ultimate-getelementsbyclassname/ one of the implementation.
You simple use like below
<a href="http://braza.com/share" class="MyClass" onclick='return somefunction()'>Yummy</a>
<script>
function somefunction()
{
// do your stuff.
// return true, if you want to open the link, or false to cancel
return true;
}
</script>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Untitled</title>
<style type="text/css">
td { border: 1px solid #ccc; }
.findMe { color: gold; }
.youFoundMe { color: green; }
</style>
<script type="text/javascript"><!--
var aryClassElements = new Array();
function doSomething() {
aryClassElements.length = 0;
getElementsByClassName( 'findMe', document.body );
for ( var i = 0; i < aryClassElements.length; i++ ) {
aryClassElements[i].className = 'youFoundMe';
}
}
function getElementsByClassName( strClassName, obj ) {
if ( obj.className == strClassName ) {
aryClassElements[aryClassElements.length] = obj;
}
for ( var i = 0; i < obj.childNodes.length; i++ )
getElementsByClassName( strClassName, obj.childNodes[i] );
}
//--></script>
</head>
<body onload="doSomething();">
<h1>Heading 1</h1>
<div>
This code is inside my div.
<span>This code is inside a span inside the div. Link inside the span inside the div.</span>
Link inside the div.
</div>
<p>
<h2 class="findMe">My Paragraph's Heading 2</h2>
<table>
<tr>
<td class="findMe">My first cell.</td>
<td>My second cell. Link inside the cell inside the row inside the table.</td>
</tr>
</table>
</p>
</body>
</html>`

jQuery, call class before addClass and removeClass

The code works well, but I have no control of my layout. It toggles between two button states correctly once the link is pressed. How do I call the 'plus class' before the link is pressed? Please help. Also, I've tried divs and spans to organize it, but it needs some tweeking
Thanks,
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js"></script>
</head>
<style type="text/css">
#h6{font-size: 12px; padding-right: 0px;}
.plus{left:0px;height:33px;width:32px; background:url('sprite.gif') 0 0px;}
.minus{left:0px;height:33px;width:32px; background:url('sprite.gif') 0 -34px;}
</style>
<h6 id="deToggle">Larger</h6>
<script language="javascript">
var click = 0%2;
var fontSizes = [14, 16]
$('#deToggle').toggle(
function(){
var sprot = $('#deToggle');//
var tog = $('#deToggle');
tog.html('Larger');
$('#OurText').css('fontSize', fontSizes[1] + 'px');
$(this).val("-");
tog.addClass('plus');
tog.removeClass('minus');
},
function(){
var tog = $('#deToggle');
tog.html('Smaller');
$('#OurText').css('fontSize', fontSizes[0]+ 'px');
$(this).val("+");
tog.removeClass('plus');
tog.addClass('minus');
});
</script>
<p id="OurText">My Text!!!</p>
</html>
sprit.gif rollover image
I reply 2 days before something like this
see here
ask for help
DEMO
Do you mean you want to apply the class on the initial page load?
Call the code to add the plus class on the initial page load. I've also refactored your code into functions and put it all in jQuery's document.ready function
$(document).ready(function(){
Plus();
$('#deToggle').toggle(function(){
Plus();
}, function(){
Minus();
});
});
function Plus(){
var sprot = $('#deToggle');//
var tog = $('#deToggle');
tog.html('Larger');
$('#OurText').css('fontSize', fontSizes[1] + 'px');
$(this).val("-");
tog.addClass('plus');
tog.removeClass('minus');
}
function Minus(){
var tog = $('#deToggle');
tog.html('Smaller');
$('#OurText').css('fontSize', fontSizes[0]+ 'px');
$(this).val("+");
tog.removeClass('plus');
tog.addClass('minus');
}
You need to add doctype for css to work. Add this before the head tag
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
This is because you didn't set the initial size. you can use either css or javascript for that.
Recommended way is to use CSS. Add this to your style
#OurText {
font-size: 14px;
}
See Demo. http://jsfiddle.net/RV5LE/
I have cleaned your code a bit. and next time post your question with a copy on jsfiddle
css('fontSize', fontSizes[0]+ 'px');
Should be:
css('font-size', fontSizes[0]+ 'px');
↑
That fontSize is used in animate().
Also you do not need that + 'px' all numeric css values can be given as numeric.

Categories