jQuery.contains() does not work properly - javascript

I should get an "alert" in the following case, but I am not getting any "alert". I am trying a simple example of jQuery.Contains().
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script>
$(document).ready(function() {
var alpha = $.contains('body','p') {
alert(alpha);
});
</script>
</head>
<body>
<p>This is a paragraph.</p>
</body>
</html>

As per the jQuery documentation the API takes only element nodes (not JavaScript/jQuery objects or selectors)
Check to see if a DOM element is a descendant of another DOM element.
Only element nodes are supported; if the second argument is a text or
comment node, $.contains() will return false.
Note: The first argument must be a DOM element, not a jQuery object or plain JavaScript object.
you should change the code to
$(function () {
alert($.contains(document.body, $("p")[0])) //alerts true
alert($.contains(document.body, document.getElementsByTagName("p")[0])); //alerts true
})

Try this:
$(document).ready(function(){
var alpha = $.contains(document.body,$("p")[0])
if (alpha) {
alert(alpha);
}
});
DEMO
Arguments are always DOM elements, not simple text.
For more details, see this.

jQuery.contains only returns boolean and doe not have a callback.
Try this code.
$(document).ready(function(){
alert($.contains(document.body,$('p')[0]));
});

Use this code you have error on this line (var alpha = $.contains('body','p'){)
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script>
$(document).ready(function(){
var alpha = $.contains('body','p');
alert(alpha);
});
</script>
</head>
<body>
<p>This is a paragraph.</p>
</body>
</html>

Related

Using document.addEventListener breaks document.getElementById

really hope someone can help me out here. Cutting a very long story short, on a few replies on this site I've seen people write that we should move away from:
<body onLoad="init();">
In the HTML to:
document.addEventListener("DOMCONTENTLOADED", init, false);
In the JavaScript file so we aren't mixing interactive code with content code etc.
But by switching to this method my code breaks, I can no longer access the DOM tree, here is an example:
function Tester(){
this.value1 = 10;
this.container = document.getElementById("fred");
this.list = this.container.childElementCount;
this.in_func = function(){
alert(this.value1+" "+ this.list);
};//end of this.in_func
}//end of function Tester
function init(){
var alpha = new Tester();
alpha.in_func();
}//end of function init
document.addEventListener("DOMCONTENTLOADED", init(), false);
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
</head>
<body><!--onLoad="init();"-->
<section id="fred">
<section id="elem1"></section>
<section id="elem2"></section>
<section id="elem3"></section>
<section id="elem4"></section>
<section id="elem5"></section>
</section>
</body>
</html>
The this.container is always null so the childElementCount generates an error of:
"Uncaught TypeError: Cannot read property 'childElementCount' of null"
Yet when I comment out the event listener and use the onLoad technique it works, am I just doing something stupid? I've tried using a variable instead of using this.list, tried using querySelector instead of getElementById, I've tried "load" instead of "DOMCONTENTLOADED" but nothing seems to work.
I know it will be something really simple but I cannot find the solution anywhere online, maybe I am just searching for the wrong thing.
Please put me out of my misery.
thanks
Zen
This is the correct way of doing it:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<script>
function Tester(){
this.value1 = 10;
this.container = document.getElementById("fred");
this.list = this.container.childElementCount;
this.in_func = function(){
alert(this.value1+" "+ this.list);
};//end of this.in_func
}//end of function Tester
function init(){
var alpha = new Tester();
alpha.in_func();
}//end of function init
document.addEventListener("DOMContentLoaded", function(event) {
init();
console.log("DOM fully loaded and parsed");
});
// document.addEventListener("DOMContentLoaded", init(), false);
</script>
</head>
<body>
<section id="fred">
<section id="elem1"></section>
<section id="elem2"></section>
<section id="elem3"></section>
<section id="elem4"></section>
<section id="elem5"></section>
</section>
</body>
</html>
In you code you called init() and then passed it, but you should passed it as a function! document.addEventListener("DOMContentLoaded", init, false);
That's why
document.addEventListener("DOMCONTENTLOADED", init(), false);
Problem 1
You are calling init immediately and trying to use its return value as the event handler.
Remove the ().
Problem 2
Event names are case sensitive. It is DOMContentLoaded not DOMCONTENTLOADED

How do I count the number of elements in a sortable div?

I have multiple divs in an HTML document with smaller divs within them that can be sorted among each other. When the document is loaded, a random amount of those smaller divs are appended to #boxtop.
Here's my HTML:
<html>
<body>
<head>
<title></title>
<script link src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<link rel="stylesheet" href="jquery-ui.min.css">
<link rel = "stylesheet" type" type="text/css" href = "style.css">
<script src="jquery-ui.min.js"></script>
<div id = "boxtop" class = "dragInto"></div>
<button type="button" id="button">My Children!!!</button>
<div id = "eqbox"></div>
<div id = "box1" class = "ansBox"></div>
<div id = "box2" class = "ansBox"></div>
<div id = "box3" class = "ansBox"></div>
</head>
</body>
</html>
Here's my relevent jQuery
$(document).ready(function()
{
$("#boxtop").sortable
({
connectWith: ".ansBox"
});
$(".ansBox").sortable
({
connectWith: ".ansBox"
});
});
$(document).ready(function()
{
$("dragInto").droppable
({
accept: ".box"
});
});
var numChild = $("#boxtop").length;
$(document).ready(function()
{
$("#button").click(function()
{
console.log(numChild);
});
});
My question is: How can I get the number of elements in a sorted div. I currently try and print that value to the console using numChild but that prints "1". And if I were to drag a bunch of elements from #boxtop to .box1, how could I get the number of elements inside .box1?
The .length property tells you how many elements belong to the jQuery object you call it on. So given that $("#boxtop") matches one element, $("#boxtop").length will be 1.
To find out how many elements are inside #boxtop you have to select all of its descendants and then check the .length:
// All descendants:
$("#boxtop").find("*").length // or:
$("#boxtop *").length
// Or count immediate children only:
$("#boxtop").children().length
In your case I think checking immediate children is probably what you want. But don't set a global variable like:
var numChild = $("#boxtop").children().length;
...because that will set numChild to the length when the page first opens, before the user has started interacting with it. You need to check $("#boxtop").children().length or $(".box1").children().length at the point where the value is needed.
As an aside, you don't need three separate $(document).ready(...) handlers: combine all of your code into a single ready handler, or if you put your <script> element at the end of the body you don't need a ready handler at all.
You need to catch update or stop event from sortable instance. Detailed document just right there
https://api.jqueryui.com/sortable/#event-stop
https://api.jqueryui.com/sortable/#event-update
Live Demo And Working Code

One-( keypress-)event-delay between javascript input and output

The following snippet reproduces the input text in the webpage using simple javaScript and jQuery.
I am wondering, though, how come there is a one character (or more precisely : one keystroke) latency between the input and the output
eg :
I type 'abcde'
the output is 'abcd'
however if I press the Insert key, the ultimate 'e' prints.
My code :
<!doctype html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<input type="text" name="enteredText" id="myTextInput" />
<p id="myTextOutput">
blabla
</p>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
$("#myTextInput").keypress(function( ){
var theText = $("#myTextInput").val();
$("#myTextOutput").html(theText);
});
$( "html" ).click(function( event ) {
var value = $("#myTextInput").val();
$("#myTextOutput").html(value);
});
</script>
</body>
</html>
Any idea ? Thanks
If you want to get rid of tat latency. use keyup or keydown instead of keypress:
$("#myTextInput").keyup(function( ){
var value = $("#myTextInput").val();
$("#myTextOutput").html(value);
});
Here is the DEMO
The most likely reason is that the keypress event handler is executed before the content of the input field is updated. When you read the content, you still read the old content, not the updated one.
From jQuery's keypress docs:
Note: as the keypress event isn't covered by any official specification, the actual behavior encountered when using it may differ across browsers, browser versions, and platforms.
Using keyup instead fixes the issue:
$("#myTextInput").keyup(function() {
var theText = $("#myTextInput").val();
$("#myTextOutput").html(theText);
});
$("html").click(function(event) {
var value = $("#myTextInput").val();
$("#myTextOutput").html(value);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" name="enteredText" id="myTextInput" />
<p id="myTextOutput">
blabla
</p>
You're grabbing the value before you've allowed the event to propagate up to where the text field has been updated. You can add an infinitesimal delay to get the full value:
$("#myTextInput").keypress(function( ){
setTimeout(function() {
var value = $("#myTextInput").val();
$("#myTextOutput").html(value);
}, 0);
});

detect element where the function was called from

I need to know where my jQ function was called from...
In head:
function call_pl2(){
$(this).text('some text');
}
in Body:
<p> <script> call_pl2(); </script> </p>
<!-- OR -->
<div> <script> call_pl2(); </script> </div>
I got your point, I'm afraid you cannot get from the function the element that your js function is there, but each time that your function is called you can use another function and search your html content to see where this function is inside. I assume that this function is called ones from the html code when this is loaded.
Instead of trying to determine which element contains the the script tag (and, by extension, a particular call to call_pl2()) you could explicitly pass the containing element to call_pl2() as a parameter:
$(function() {
var call_p12 = function(element) {
if ($(element).is('p')) {
$(element).text('here is some text added to a paragraph');
}
if ($(element).is('div')) {
$(element).text('here is some text added to a div');
}
}
$('div, p').each(function() {
call_p12($(this));
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<p></p>
<div></div>
It would be relatively easy to modify the call_p12() function to swap in a more specific selector in the jQuery is(). For example is('.someclass') to check for a class value instead of a tag name.

call a javascript function inside a div

I would like to create a webpage which contains several divs each containing the same draw function with different implementation (like a generic interface). After loading the page I want to iterate through all the divs and call each draw function one after the other.
My page so far looks like this:
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<script language="javascript" type="text/javascript" src="jquery-1.8.2.js"></script>
</head>
<body>
<script type='text/javascript'>
$( document ).ready( function() {
// Draw all slots
$('div.slot').each(function(i, d) {
console.log('slot found: ' + d.id);
// d.draw() does not work
draw();
});
});
</script>
<div class="slot" id="slot1">
<script type='text/javascript'>
function draw() {
console.log('Here we draw a circle');
};
</script>
</div>
<div class="slot" id="slot2">
<script type='text/javascript'>
function draw() {
console.log('Here we do something totally different and draw a rectangle');
};
</script>
</div>
</body>
</html>
Unfortunately I don't know how to call the draw function of the selected div "d".
Right now it only calls the last defined draw function.
Update:
Mind you that I can not combine the different draw methods into one which would get a parameter like shape handed in. The draw methods will be totally independent from each other.
Why are you defining scripts in the divs?
Do your logic all in one script block:
<head>
<script language="javascript" type="text/javascript" src="jquery-1.8.2.js"></script>
</head>
<body>
<script type='text/javascript'>
$( document ).ready( function() {
// Draw all slots
$('div.slot').each(function(i, d) {
console.log('slot found: ' + d.id);
// d.draw() does not work
draw();
});
});
function draw(behavior) {
console.log(behavior);
}
</script>
<div class="slot" id="slot1" data-behavior="drew 1">
</div>
<div class="slot" id="slot2" data-behavior="drew 2">
</div>
</body>
</html>
If you're looking to do something more complicated, you should consider building an object oriented javascript application, with each block's functionality derived from a class "slot".
https://developer.mozilla.org/en-US/docs/JavaScript/Introduction_to_Object-Oriented_JavaScript
You can call it like
HTML:
<div class="slot" id="slot1">Draw1</div>
<div class="slot" id="slot2">Draw2</div>
JS:
function draw()
{
console.log('Drawed! '+$(this).attr('id'));
}
$(document).ready( function() {
$('div.slot').each(function(i, d) {
console.log('slot found: ' + d.id);
draw.call($(this));
});
});
An Example.
​
The reason that is happening is because you keep overwriting the draw function. Why don't you have a script page where you hold an array of function pointers to the right function like so:
var array = (draw1, draw2, draw3, ...);
function draw1()
{
//do your thing on div1
}
...
function drawn()
{
//do your n thing on divn
}
Now for your first div you need to call draw1 which is located at index 1 of the array.
HTML:
<div id="draw1">
</div>
....
<div id="drawn">
What do ya think. Note sytax has not been tested.
<html>
<head>
<script>
$(document).ready(
function() {
$('#show').call(callfun());
});
</script>
</head>
<body>
<h:form>
<div id="show" align="center">
<script>
function callfun(){
var data = "hi";
alert(data);
}
</script></div>
</h:form>
</body>
</html>
I think it may work.
Problem
You keep overwriting window.draw() every time you redefine it. You either need to namespace each one (that is, attach it to an (otherwise empty) object), or to give each and every function a distinct name. There is no "div-scope" in Javascript ;)
Solution
You can name each function according to the div's id and call it dynamically using the object["methodName"]() syntax to call it.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<script language="javascript" type="text/javascript" src="jquery-1.8.2.js"></script>
</head>
<body>
<script type='text/javascript'>
$( document ).ready( function() {
// Draw all slots
$('div.slot').each(function(i, d) {
console.log('slot found: ' + d.id);
// d.draw() does not work
window[d.id];
});
});
</script>
<div class="slot" id="slot1">
<script type='text/javascript'>
function slot1() {
console.log('Here we draw a circle');
};
</script>
</div>
<div class="slot" id="slot2">
<script type='text/javascript'>
function slot2() {
console.log('Here we do something totally different and draw a rectangle');
};
</script>
</div>
</body>
</html>
http://jsbin.com/mogeluzicu/1/edit?html,console
The easiest way I've found to go 'real OOP' in this case is to dispatch all on events on document level :
create a simple object and load this object in the main and the views like :
var events = {someCustomEventFromMain:'someCustomEventFromMain', someCustomEventFromView:'someCustomEventFromView'}
Now you can trigger events on document with jQuery like
$(document).trigger(events.someCustomEventFromMain, somedata);
And you can listen from any view or div or else
$(document).on(events.someCustomEventFromMain, function(__e, __data){
//___e is the event emitted from __e.target
//__data is the data object you wish to pass with the event
//do something when event occurs
});
So if every subscript listens to some event at document level, in your case 'drawEvent',that should do the trick. You can even pass a parameters in the data of the event, like 'circle'.
Hope this helps.

Categories

Resources