I'm coding a new version of a chrome extision, but got a trouble.
Here's my element code: Element code
At line 32 I'm tring to call the custom method willUpdateBackground, console tells me the method is undefined. Code below.
Polymer({
is: 'pure-newtab',
ready: function() {
console.dir(this.$.background);
this.$.background.willUpdateBackground('color', '#333');
// This line get error, 'willUpdateBackground' is undefined
}
});
The definition
Polymer({
is: 'pure-background',
ready: function () {
},
willUpdateBackground: function(type, imageOrColor) {
console.log(type);
console.dir(this);
}
});
But if I store this object, in console I can call the temp1.willUpdateBackground, it's weried.
Screenshot: http://i.stack.imgur.com/OTLgw.png
Fixed And Problem Happens Again
I move the custom method call to attached callback, elements not ready in ready function in some environment.
And after I fixed it, it happens again: in attached method, call failed again, and I move it to async call with 100ms delay, problem disappear again. It's not a solid solution, I'm still finding a way out.
this.async(function () {
this.$['background'].updateBackground('rgba(255,128,0,1)', 'url(https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png)');
}, 100);
I tried pasting your code into this jsbin and it worked just fine... (I commented your console.dir() and added a couple of console.log() of my own, but that's all I did)
http://jsbin.com/tomewigobu/1/edit?html,console,output
I would suggest you check that your polymer version is updated, that should help.
Related
Javascript newbie here. I'm trying to understand this and bind within the context of jquery event handlers. I'm reviewing a piece of code from the todoMVC code here, and have a question.
Let's look at line 56:
$('#new-todo').on('keyup', this.create.bind(this));
Code excerpt for context:
var App = {
init: function () {
this.todos = util.store('todos-jquery');
this.todoTemplate = Handlebars.compile($('#todo-template').html());
this.footerTemplate = Handlebars.compile($('#footer-template').html());
this.bindEvents();
bindEvents: function () {
$('#new-todo').on('keyup', this.create.bind(this));
$('#toggle-all').on('change', this.toggleAll.bind(this));
$('#footer').on('click', '#clear-completed', this.destroyCompleted.bind(this));
$('#todo-list')
.on('change', '.toggle', this.toggle.bind(this))
.on('dblclick', 'label', this.edit.bind(this))
.on('keyup', '.edit', this.editKeyup.bind(this))
.on('focusout', '.edit', this.update.bind(this))
.on('click', '.destroy', this.destroy.bind(this));
},
create: function (e) {
var $input = $(e.target);
var val = $input.val().trim();
if (e.which !== ENTER_KEY || !val) {
return;
}
this.todos.push({
id: util.uuid(),
title: val,
completed: false
});
$input.val('');
this.render();
},
My question
I understand that when using jquery, this refers by default to “the element we called the method on” (#new-todo in this case), so in this code, we want to explicitly bind this to the object App instead.
In the example, both thiss appear to follow the “left of the dot rule” and refer to App. So far, so good.
From this behavior, I expect that this, if not inside the callback function must refer to the parent app, (and this inside the callback function must default to the element with ID #new-todo unless bound to some other value).
Therefore, if I call this.create without binding it to anything, this should still refer to App, right? WRONG.
As you can see, the first this now refers to the element with ID #new-todo. (And the this in other event listeners below also refer to the jquery wrapped object!)
Can someone help me understand why?
I discovered the problem (with my question), so I thought I'd post the resolution in case it helps anyone in the future.
I realized that my initial understanding of this and bind() was correct, so I must be wrong about something else.
It turns out that
(1) I made an incorrect assumption about how the debugger works
(2) I needed to review when each part of the code ran
(1) Debugger
In the debugger, when I pause and linger my mouse over a variable, the debugger shows me a preview of that variable's value. I erroneously assumed that when the debugger pauses code execution, I'd see various values of this displayed, depending on the context (so a this in one method would differ from the this in another.) I see now that's not how it works. I believe this will show up as the same value everywhere and that value will be the value of this at the point where the script was paused. See attached gif for example.
(2) Code execution timing
When code execution paused for my breakpoint, I was already inside the create method, so the this in this.create and .bind(this) was reflecting the value of this within the create method.
I have a little jQuery error. I have searched and read the others topics about it, and tried the solutions, but it didn't work.
Here is my code :
function paf() {
// My function - It is working, so I guess the problem is not there.
}
jQuery(document).ready(paf)
jQuery(window).load(jQuery('input').bind('keyup', paf())) // The problem is here
The last line has to update the price when the user type on a input box, but it gives the error :
TypeError: e.handler.apply is not a function
Here you don't have to have () and .load() should have an anonymous function:
jQuery(window).load(function(){ // load takes a function as param.
jQuery('input').bind('keyup', paf); // <---remove () from paf
});
The problem is you are passing a jQuery object as the load callback value.
You can call the paf and have the event registration code in the dom ready callback itself like
function paf() {
// My function - It is working, so I guess the problem is not there.
}
jQuery(document).ready(function() {
paf();
jQuery('input').on('keyup', paf)
})
I’m writing a method that’s a simple wrapper around calls to $.fn.modal. The method takes a selector and that selector should be passed to jQuery, so jQuery can find an element matching that selector.
Here’s what my spec looks like:
describe('The modal presenter', function() {
it('operates on the provided selector', function() {
spyOn($.fn, 'find');
myModule.presentModal('#the-modal', {});
expect($.fn.find).toHaveBeenCalledWith('#the-modal');
});
});
This is all fine. The odd behaviour is happening in my production code.
var myModule = {
presentModal: function(selector, event) {
event.preventDefault();
$(selector, document).modal('show'); // This line works
$(document).find(selector).modal('show'); // This line doesn’t work?!
// This should be fairly obvious, but I’m not running both
// of the above lines at the same time. I comment one out
// and run the method with one line at a time.
}
}
As far as I’m aware, those two lines that I’ve added comments to should be equivalent. They should both call $.fn.find with selector. The second commented line should definitely call .find, as I’ve written that explicitly.
When I run my test, I get TypeError: $(...).find(...) is undefined. How could this be?
I was building a slide-menu with javascript using classes and objects and a little bit of jquery as part of my efforts to learn javascript more deeply.
Everything went right until I wanted to bind a mouseleave to the initiator of my menu.
So here's my code block
var el;
function generate(obj){
return function(){obj.slidein();}
}
function slider(arg1,arg2){
...//Some junk
el=this;
for(i=0;i<this.nsubs;i++){ ...
$("#"+this.id+i).bind('mouseleave',function(){setTimeout("generate(el)",500)});
}
...
}
Well, I get no error on firefox error console but somehow the slidein() function which I want to be attached to the mouseleave is not being called when mouse leaves the element in question.
Can Someone explain what I am doing wrong here?
Try passing a function rather than a string to setTimeout:
$("#"+this.id+i).bind('mouseleave', function() {
setTimeout(function() {
generate(el);
}, 500)
});
Alright, I sorted it out on my own, what I actually needed was a closure that returns a function with 'setTimeout(generate(ObjPassedToClosure))'
i have a locate function defined in javascript
var locID;
function locateMe()
{
if(locID > 0)
{
// i do a jquery post here
}
setTimeout(locateMe, 2000);
}
// my document ready function is here, and inside it, at the end of it
// i do this
locID = 0;
locateMe();
when i test this code in firefox, the locateMe function is called every two seconds and works as expected. when i test the code in IE8 the function is never called (at least it appears to never be called from what i can see using IE's developer tools)
note: there is code defined in a click event handler for the 'zone_row' class that modifies locID. again, in firefox everything works as expected. the strange thing is, in IE when a zone_row is clicked the function WILL be called ONCE. i can see that both on the developer tools and through the result of the action of that jquery post.
i figured there is just some anomly with IE that i am not familiar with yet. what am i doing wrong?
EDIT: changed "locateMe();" to locateMe inside the setTimeout call.
UPDATE: adding more of my code (per request in comments) to show placement (albeit not much more code than my first post).
<script type="text/javascript">
var z_items;
var locID;
function locateMe()
{
if(locID > 0)
{
// my jquery post is here
}
setTimeout(locateMe, 2000);
}
$(document).ready(function()
{
// ... some click events and get requests here ...
locID = 0;
locateMe();
});
</script>
i also tried wrapping the call in a setTimeout (no effect) and changing the DOCTYPE (this actually caused IE to never call the function as opposed to now where it calls it ONCE and never again).
problem solved. i found an answer to another problem i was having from this post:
Prevent browser caching of jQuery AJAX call result
upon adding $.ajaxSetup({ cache: false }); to my document ready function, it solved THIS problem too. it looks like all this time it was a caching issue.
I've found that for IE (even IE9) that if you nest the self-called function in an anonymous function it works. But it does look like Toddeman's problem was related to the ajax part.
So the code would be:
function locateMe()
{
/* ... */
//IE way (still works in Chrome and FF):
setTimeout(function () { locateMe(); }, 2000);
//original: setTimeout(locateMe, 2000);
}
Use
setTimeout( locateMe, 2000 );