this.$el and jQuery - javascript

I'm trying to do something deceptively simple -- adding a class to the active backbone element. The code I want to use is:
this.$el.addClass('classIWant');
However, this doesn't work all the time. Sometimes it seems to, but not all the time. However, this always works.
var id = this.$el.attr('id');
$('#' + id).addClass('classIWant');
Obviously I don't want the second example, as it relies so heavily on HTML and the DOM. Is there any reason why the first shouldn't work, or am I missing something else?

Seems this points to something wrong. If you are running this code in function myFunc, then just add to initialize next line:
_.bindAll(this, 'myFunc');
And got with you first approach, this.$el.addClass('classYouWant').

This code should work:
this.$el.addClass('classIWant');
but only if it is present within your onRender() function or any functions that are called after onRender() is. If you have this code in your initialize function then it will not work as the dom for that view has not yet been generated

Related

LitElement rendering template without values

I've got a simple example demonstrating what I'm seeing: https://stackblitz.com/edit/lit-element-example-3pdnwk?file=index.js.
Basically when the first child element renders, the text property is set correctly. However on the second render, the text property is undefined first and then updated to be the correct value.
This breaks being able to depend on _firstRendered() to have the correct values assigned to the properties.
Am I doing something really off here?
Update: Here is a better example using a similar method provided in the lit-html documentation: https://stackblitz.com/edit/lit-element-issue?file=index.js
Am I doing something really off here?
maybe? :) Hopefully you can help me to understand why you chose your implementation and I can look into it further.
The part I'm stuck on is why you create and replace the child element inside the parent element like this:
this._child = html`<child-element text="${text1}"></child-element>`;
From what I understand so far, that code uses a lit-html helper function to create a lit-html TemplateResult. You then replace it with another one in the timeout callback:
this._child = html`<child-element text="${text2}"></child-element>`;
So instead of just re-drawing only the stuff that changed (a string), your code creates a new TemplateResult and redraws that. This also calls the child element constructor again and causes the text node to go undefined for a moment as you noted. Here is console output added to your impl to show when the constructor and render functions get called for parent and child:
https://stackblitz.com/edit/lit-element-example-ftlbz7?file=index.js
From inspecting the DOM tree, your example produces this DOM structure:
<parent-element>
#shadow-root
<div>
<child-element>
#shadow-root
<div>
Suppose I need to produce that same DOM structure and have the same text node update in response to the timeout callback, I would probably handle it in the parent render function:
_render({ parenttext }) {
return html`<div><child-element text="${parenttext}"></child-element></div>`;
}
which ensures that the child constructor is only called once, and only the data that actually changes gets redrawn.
If I understand correctly, that's how lit-element is designed to be used (expressing an app or element's render as a function of its data). That way we can rely on the browser to just redraw any changes to the data. This should theoretically be faster (altho I haven't tested it).
Code sample here:
https://stackblitz.com/edit/lit-element-example-exrlxw?file=parent-element.js
Lmk what I'm missing from your tests and I can look into it more.
Edited to add:
I noticed that overriding _shouldRender to prevent the element from rendering with undefined props prevented the element from rendering with undefined props, but it didn't fix _firstRendered, which was still firing when props were undefined.
_firstRendered, unlike _didRender, is not specifically called as a result of _render; it is called from the ready() callback, which is inherited from Polymer's properties-changed mixin. In Polymer, ready() fires when the element is added to the DOM. I thought properties should be initialized by then, so this is still pretty weird.
Anyways, this means it is possible to create an element that never renders (i.e _shouldRender always returns false), but _firstRendered still fires. Lol. Sample: https://stackblitz.com/edit/lit-element-first-rendered?file=index.js.
I'm not honestly sure what to make of any of this. I'll raise an issue on the lit-element github when I've read a few more things from the documentation (or you can, if you get there first).
This is no longer an issue as of 0.6.0-dev.5

JavaScript Function Arguments in jQuery. Does This Work?

EDIT Helping people understand the question better
Can you call a argument and then use it in jQuery? I was thinking something like:
// Notice the "test" argument in the "foo" function
function foo(test) {
$("#randomDiv").click(function(){
$(test).toggle();
});
}
Would something like this work?
Yes, it will work. But it depends on what you want to achieve.
Your code will be something like a "instant-binder", eg: this code will bind toggling of the element when the document is parsed.
As far as you can bind many listeners for one event, following calls of the same functions will be executed in order.
You should run foo at the beginning of the html file. On that way you will be sure that the function document.ready would run wait until all the DOM is loaded.

jquery basic of dollar sign - named vs anonymous

I have a couple of interview questions
What is the different between $(function(){}); and $(document).ready(function(){});
What is the difference between $(function(){}); and var func=function(){}; How are each of them called?
Given the following script
<script language="javascript">
$(function()
{
var id=$("cssID");
//do something with your id
//your event to be added here
});
</script>
How can you add an event, say, onmouseout that will work on the id?
Here are my answers:
They are the same, both are meant to run when the page document finishes loading
The first one is called automatically while the second one will be called via named reference; that is func.called(), for example.
Something like this:
$(function()
{
var id=$("cssID");
//do something with your id
//Oki
id.onmouseout
(function(){
//do something
});
});
However my professor says I was wrong in all three. she explained things I am unsure and didn't dare to ask, she was mad about me. What are the correct answers and why are mine wrong?
These are the different types of Document Ready functions typically used in jQuery (aka jQuery DOM Ready). A lot of developers seem to use them without really knowing why. So I will try to explain why you might choose one version over another. Think of the document ready function as a self-executing function which fires after the page elements have loaded.
See Where to Declare Your jQuery Functions for more information on how to use the Document Ready Functions.
Document Ready Example 1
$(document).ready(function() {
//do jQuery stuff when DOM is ready
});
Document Ready Example 2
$(function(){
//jQuery code here
});
This is equivalent to example 1… they literally mean the same thing.
Document Ready Example 3
jQuery(document).ready(function($) {
//do jQuery stuff when DOM is ready
});
Document Ready Example 4
(function($) {
// code using $ as alias to jQuery
$(function() {
// more code using $ as alias to jQuery
});
})(jQuery);
// other code using $ as an alias to the other library
Document Ready Example 5
$(window).load(function(){
//initialize after images are loaded
});
Here is the link for you to refer.
1. They are the same, both are meant to run when the page document finishes loading
This is half right. They are the same, the first is just a shortcut way to write the second, but they don't run when the document finishes loading, they run when the DOM is ready (at which time some resources such as images might still be loading).
2. The first one is called automatically while the second one will be called via named reference; that is func.called(), for example.
Again half right. In the first one the anonymous function will be called automatically when the DOM is ready as per question 1. The second example can be called with func(). You wouldn't have the .called part in there. Or you can pass func as a parameter, e.g., as $(document).ready(func).
Q3
var id=$("cssID");
How can you add an event, say, onmouseout that will work on the id?
$("cssID") creates a jQuery object that will contain zero or more elements depending on how many matched the "cssID" selector. The id variable references that jQuery object. If the question is how to assign an event handler to those matching elements you'd do this:
id.mouseout(function() { /* some code */. });
// OR
id.on("mouseout", function() { /* some code */ });
When processing events with jQuery you don't use "on" in the event names, so it's "mouseout" not "onmouseout".
So your answer to 3 was nearly right.
(Note though that "cssID" is a selector that won't actually match any elements unless you have <cssID> tags in your document...)
There is no difference between:
$(functionValue);
And:
$(document).ready(functionValue);
So your professor is wrong there. The second example is completely different. One of them runs on document ready and requires jQuery; the other one is just a function literal assigned to a JavaScript variable.
As for the third one, you'd probably do it with on. onmouseover is correct if you use get, but not really the best way of going about things, and you definitely wouldn't call it like you're doing there - that's completely incorrect.
id.on('mouseout', yourHandler);
or
id.mouseout(yourHandler);

Javascript override problem class xml

Not sure what is the problem , this the second post looking for the answer.. but this time with a with the example .
What i'm doing : I 'm implementing a gallery that is getting a xml, and then build me using some javascript code. the problem i tried to call twice gallery.init like :
$(document).ready(function(){
galleryXML.init({
id: "#gallery1"
});
galleryXML.init({
id: "#gallery"
});
})
I expected to have one in #gallery1 other in #gallery. Can someone tell me what the problem(it only happen when i had the loadXml() , so probably something with asynchronous call not sure )?
I think your problem can be that you are using the same variable _P for (what you expect to be) 2 different instances of the galleryXML.
The _P variable is created and initialized when the javascript code is parsed, because of the () after the var galleryXML = function() {...}.
So I guess your problem is going to be solved if you just put the variable inside the init of galleryXML. You can see the code here: jsfiddle.net/rpNab/3/ (notice that now each li is inside each gallery, instead of both li in the last gallery)
EDIT: And I realize that now with my modification the galleryXML module seems ugly (because it only has one method and no variables), so I made a minor refactoring in order to have more methods inside that class, but the methods now must receive the parameter because the class itself continue to be "static", but the parameters can make it act for different contexts. Hope it helps: jsfiddle.net/rpNab/4/

jquery multiple selector with a this

I see, from to time, this kind of jquery selector, which I don't really understand. What does this do in it:
$('.myClass', this).someFn();
Can someone explain to me, please?
Thanks
That searches for child elements with a class of myClass in the context of whatever this is and then calls someFn();
It would give you the same results as writing $(this).find(".myClass").someFn(); but is not as efficient.
This means that you are trying to select .myClass inside just this
The "this" keyword is something that is only meaningful inside a method of an object. It will mean something different -- or nothing at all -- depending on where you're calling this code from.
If you're calling it from inside an object (usually an HTML element), the object will be added to the selector that is passed to jQuery.

Categories