Limiting the jQuery search scope correctly? - javascript

I've stumbled up this code and I'm wondering if its just limiting the scope or selecting both of the elements at the same time.
container = jQuery("#test", parent.document);
jQuery("param[name=scale]", another.object)
Can anyone shed some light on this?
Edit: the full example:
<script type="text/javascript">
jQuery = parent.jQuery;
container = jQuery("#test", parent.document);
another = {
targetw: container.width()
};
function onEnd(){
container.slideUp();
}
function onStart(){
another.object = jQuery("object", document);
another.w = another.object.attr("width");
another.h = another.object.attr("height");
another.targeth = Math.floor(another.targetw * another.h / another.w);
jQuery("div>iframe",container).width(another.targetw);
jQuery("div>iframe",container).height(another.targeth);
another.object.css("width", another.targetw+"px");
another.object.css("height", another.targeth+"px");
another.object.attr("width", another.targetw);
another.object.attr("height", another.targeth);
jQuery("param[name=scale]",another.object).attr("value","exactfit");
another.object.parent().attr('style', function(i,s) { return s + 'background:none; width: '+another.targetw+'px !important; height: '+another.targeth+'px !important;' });
}
document.write('*snipped code*');
</script>
`

That appears to be the context argument from the jQuery selector jQuery(selector[,context]).
From http://api.jquery.com/jquery/
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" ).

It is a child - parent selector. The search starts within the parent instead of the whole DOM.
$('childNode', parent)
It is same as
$(parent).find('childNode')
Considering container = jQuery("#test", parent.document);
As #test is an ID based selector just jQuery('#test') wont make any difference as IDs are unique across the DOM elements.

Related

Remove class from parent element javascript

I have a container that opens via an onclick function. I then have a cross within the container that should close the parent element however I receive a
TypeError: undefined is not an object (evaluating 'parent.id')
Code is here
<div class="post" onclick="postClick(el)">
...
...
</div>
JavaScript
function postClick(el) {
document.getElementById(el.id).classList.add("read");
}
function postClose(event) {
var parent = this.parentNode;
console.log(parent.id);
parent.id.classList.remove("read");
}
Use event.target to get the reference to the HTML element.
And you have an extra .id in the parent.id.classList expression.
function postClick(event) {
const el = event.target;
document.getElementById(el.id).classList.add("read");
}
function postClose(event) {
const el = event.target;
const parent = el.parentNode;
console.log(parent.id);
parent.classList.remove("read");
}
<div class="post" onclick="postClick(event)">
...
...
</div>
One way of doing this is using pure Javascript and bind the event listener like this
document.querySelector('#toggle').addEventListener('click', function (e) {
console.log(this.parentNode.classList.remove('read'))
});
div {
padding: 20px 50px;
}
div.read {
background-color: red;
}
<div class="read">
<button id="toggle">Remove Parent Class</button>
</div>
Jut use this and you are done : 😊
element.parentNode.classList.remove("class-name");
if the project is complex and needs interactivity more than often then you use jquery library for the interactivity.
//to remove class
$( "p" ).removeClass( "myClass yourClass" )
$("#div123").toggle(); //if you want to temp hide elements
as your code suggests the 'read' items must be disabled, you can toggle them once an event handler is wrapped over the toggle method. you can pass this or $(this) in case you want to do stuff with the owner of the function call.
well i agree some adept devs didnt like this answer, it will be surely of some help to some beginner dev in future who is looking for an alternative option to hide elements or remove classes

jQuery traversing. Find siblings including itself

I'm using jQuery traversing to jump between DOM elements.
First of i have a onClick function:
$(document).on('keyup', '.size, .ant', function(){
Inside of this function I send data about what's clicked, to another function.
sulorTableRowWeight( $(this) );
function sulorTableRowWeight(thisobj){
Now, I'd like to traverse from the clicked element $(this) to its parent. I'd like to find the parent's siblings and then traverse down to a specific sibling.
var inputSize = $(thisobj).parent().siblings('.sizeTd').children('.size');
My problem is when I want to traverse back down to the element I came from, it is not listed as a sibling because it isn't a sibling...
var inputSize = $(thisobj).parent().siblings(); console.log(inputSize)
console will give me the siblings, but not the one U came from...
So, when a user clicks ".size" I'd like to traverse up to the parent and back to size.... When a user clicks ".ant" I'd like to traverse up to the parent and then down to ".size"...
I tried to hardcode the traversing:
var inputSize = $(thisobj).parent().siblings('.sizeTd').children('.size');
But it won't work because it is not actually a sibling.
So what is it? And how can I get back to it?
If it is not possible, I have to run some if/else statements, U guess...
UPDATE
$(document).on('keyup', '.size, .ant', function(){
//Find changed <select> .tbody
var tbodyId = $(this).parent().parent('tr').parent('tbody').attr('id');
//Check <tbody> #id
if(tbodyId === "cpTableBody"){
}
else if(tbodyId === "sulorTableBody"){
sulorTableRowWeight( $(this) );
}
else if(tbodyId === "konturTableBody"){
konturTableRowWeight( $(this) );
}
else if(tbodyId === "kantbalkTableBody"){
kantbalkTableRowWeight( $(this) );
}
})
//Function sulorTableRowWeight
function sulorTableRowWeight(thisobj){
//Find the selected data-weight
var selectedWeightmm3 = $(thisobj).parent().siblings('.selectTd').children('.select').find(':selected').data('weightmm3');
//Find input .size value
var inputSize = $(thisobj).parent().siblings('.sizeTd').children('.size'); console.log(inputSize)
PROBLEM
My var inputSize will return undefined when I click a ".size" element. That´m's because it is not listed as a sibling to itself.
I know it's keyup, not click...
e.target will select the current input
$(document).on('keyup', '.size, .ant', function(e) {
inputSize = $(e.target);
if($(e.target).is('.ant')) {//test if the element is .ant
inputSize = $(e.target).parent().find('.size');//get .size based on .ant
}
console.log(inputSize[0]);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<input class="size x1" placeholder="x1">
<input class="ant x1" placeholder="x1 ant">
</div>
<div>
<input class="size x2" placeholder="x2">
<input class="ant x2" placeholder="x2 ant">
</div>
Hmm, if you're passing in $(this) as thisObj I don't think you need to be nesting thisObj in a $(). (See note below)
Anyway, you could try using .parents('<grandparent>').find('<child>') so basically you're traversing one higher level up the tree with <grandparent>, then getting all the descendants that match the child selector. That should include the branch of the three that $(this) represents. But it's hard to say for sure without seeing your HTML.
** A good practice when assigning jQuery objects to variables is to use $ syntax, ie var $this = $(this) so you know anything prepended with a $ is a jQuery object.
inside sulorTableRowWeight , you should have the reference to the clicked element in thisobj variable.

Where do I put $(this) in the function?

Since I want to use classes instead of id's in these functions(I have three of the same function with different things I want to .append) I am sure I need to put $(this) in those functions somewhere to only trigger only ONE function on button click and not all three of them. but I am not sure because I am a total beginner in jquery/js, so I would appreciate some help.
$(document).ready(function () {
$(".onclick").click(function () {
$('#favorites').append('<div data-role="main"class="ui-content"><div class="ui-grid-b"><div class="ui-block-a">Arrow</div><div class="ui-block-b">More Info</div><div class="ui-block-c">Unfavorite</div></div></div>');
});
});
http://codepen.io/anon/pen/JYxqEw - HTML And the Jquery Code
$('.onclick') selects all the elements with a class of onclick. That means that, whenever something with class="onclick" is clicked, that function will fire.
If you want all of those elements to append that exact HTML to the #favorites element, then you can leave your code as-is.
However, if what you're trying to do is append that html to the clicked element, that is when you'd use $(this) -- that selects the element you clicked with jQuery, then you can append directly to that element ie:
$(document).ready(function () {
$(".onclick").click(function () {
// this will append the HTML to the element that triggered the click event.
$(this).append('<div data-role="main"class="ui-content"><div class="ui-grid-b"><div class="ui-block-a">Arrow</div><div class="ui-block-b">More Info</div><div class="ui-block-c">Unfavorite</div></div></div>');
});
});
EDIT
so to insert the contents of each .onclick into #favorites, you'll need to use the innerHTML value of the DOM node. example fiddle:
http://jsbin.com/qazepubuzu/edit?html,js,output
When you select something with jQuery, you're actually getting back not just the DOM node, but a jQuery object -- this object contains both a reference to the actual DOM node ([0]), as well as a jquery object ([1]).
So to select the DOM node with $(this), you target the node: $(this)[0]. Then you can use .innerHTML() to grab the HTML contents of the node and do as you like.
Final result:
$(function () {
$('.onclick').click(function () {
$('#favorites').append( $(this)[0].innerHTML );
});
});
So the building blocks are not that complex, but I think you're a novice jQuery developer and so you may not be clear on the difference between jQuery and JS yet.
$(selector, context) allows us to create a jQuery collection for a CSS selector which is the child of a current context DOM node, though if you do not specify one there is an automatic one (which is document.body, I think). Various functions iterating over jQuery collections make the particular element available as this within the JavaScript. To get to the strong element from the .onclick element in the HTML fragment you need to travel up in the hierarchy, then to the appropriate element. Then, we can collect the text from the element. We can do this in either JS or jQuery.
To do this with simply jQuery:
// AP style title case, because Chicago is too crazy.
var to_title_case = (function () { // variable scope bracket
var lower_case = /\b(?:a|an|the|and|for|in|so|nor|to|at|of|up|but|on|yet|by|or)\b/i,
first_word = /^(\W*)(\w*)/,
last_word = /(\w*)(\W*)$/;
function capitalize(word) {
return word.slice(0, 1).toUpperCase() + word.slice(1).toLowerCase();
}
function capitalize_mid(word) {
return lower_case.exec(word) ? word.toLowerCase() : capitalize(word);
}
return function to_title_case(str) {
var prefix = first_word.exec(str),
str_minus_prefix = str.slice(prefix[0].length),
suffix = last_word.exec(str_minus_prefix),
center = str_minus_prefix.slice(0, -suffix[0].length);
return prefix[1] + capitalize(prefix[2]) + center.replace(/\w+/g, capitalize_mid)
+ capitalize(suffix[1]) + suffix[2];
};
})();
$(document).ready(function() {
$(".onclick").click(function () {
var text = $(this).parents('.ui-grid-a').find('.ui-block-a').text();
var html = '<div data-role="main"class="ui-content">'
+ '<div class="ui-grid-b"><div class="ui-block-a">'
+ to_title_case(text) + '</div><div class="ui-block-b">More Info</div>'
+ '<div class="ui-block-c">Unfavorite</div></div></div>';
$("#favorites").append(html);
});
});

Adding event listeners to elements cloned from the template tag

I am creating a lot of DOM elements (each has the same HTML structure) with the <template> tag:
<template id="weapon-template">
<div class="button">
<div class="button-price" data-price ></div>
<img class="button-image" data-image >
<div class="button-name" data-name ></div>
<div class="button-damage" data-damage></div>
<div class="button-amount" data-amount></div>
</div>
</template>
... and a few lines of JavaScript:
var clone;
var template = document.getElementById( "weapon-template" );
template.content.querySelector( "[data-image]" ).src = data.prev;
template.content.querySelector( "[data-price]" ).innerHTML = data.cost + "$";
template.content.querySelector( "[data-name]" ).innerHTML = data.name;
template.content.querySelector( "[data-damage]" ).innerHTML = data.damage;
template.content.querySelector( "[data-amount]" ).innerHTML = 0;
clone = document.importNode( template.content, true )
this.container.appendChild( clone );
I would love to add some event listeners on the cloned elements. I could not find nothing from internet and tired a couple of things my self, like:
template.content.querySelector( "[data-price]" ).addEventListener( "click", action, false );
clone.querySelector( "[data-price]" ).addEventListener( "click", action, false );
... none of these worked. I could simply do something like:
var child = this.container.childNodes[ 0 ];
var target = child.querySelector( "[data-price]" );
target.addEventListener( "click", action, false );
... but I wonder if there is another, simpler way similar to those that has not worked for me.
Until you 'activate' template using document.importNode, its content are inert nodes which are not part of DOM.
As per addEventListener docs:
The event target may be an Element in a document, the Document itself,
a Window, or any other object that supports events (such as
XMLHttpRequest).
Therefore adding event listeners in your example won't work until you clone template contents and add them to an existing node in document.
If you are ready to use jQuery, there is a workaround. You can use event delegation using jquery on method to bind events to parent element.
something like this:
$(this.container).on('click', '[data-price]', action);
What this will essentially do that any click which is being triggered from children of this.container will bubble up till parent. If it satisfies the selector criteria of [data-price] action will triggered on it.
If you can get around using a for your list rows, then your document.getElementById(...) will return an actual DOM element instead of just the DocumentFragment that it does right now. This means that importNode(...) will return you real DOM nodes on which you can call addEventListener and hook up events!

How to change style of div #id that contain selected .class

I'm trying to change style of div #info_frame that contain class nazwa_klasy_display and I can't fix it.
$('.box').mouseenter(function() {
//show up scores
$( this ).children( '.scores' ).css( 'display', 'block' );
nazwa_klasy = $( this ).attr('class').split(' ')[1];
nazwa_klasy_display = nazwa_klasy.split('_')[1];
if ($('#info_frame').has(nazwa_klasy_display))
{
$('#info_frame .'+nazwa_klasy_display).style.display ="block";
}
});
you're mixing jQuery with plain Js:
either you use
/* chain a jQuery method, e.g. show() */
$('#info_frame.'+nazwa_klasy_display).show()
or
/* access to the dom node before using plain js */
$('#info_frame.'+nazwa_klasy_display).get(0).style.display = "block";
If my understanding is correct, you are looking for a <div> that has the id of info_frame and the class of nazwa_klasy_display then you do need to fix your CSS selector. you have a space in there when it shouldn't be.
$('#info_frame.'+nazwa_klasy_display)
the selector #info_frame .[nazwa_klasy_display] will be looking for anything that has the class nazwa_klasy_display that is a descendant of *#info_frame
$("#info_frame").hasClass('.'+nazwa_klasy_display).css('display','block');
try this

Categories

Resources