I'm trying to convert Dojo functions from non-AMD to AMD but am not sure how to convert the following function:
previously it was Non-AMD like
function step11(timestamp){
window.requestAnimationFrame(step11);
}
after converting to AMD
step11: function(timestamp) {
window.requestAnimationFrame(step11);
}
its been called from other method as
window.requestAnimationFrame(that.step11);
I tried:
var that = this;
window.requestAnimationFrame(function() {
that.step11();
});
Which gives the error "that.step11 is not a function".
found the solution.
define(["dojo/ready", "dojo/dom", "dojo/dom-construct","js/abc", "dojo/domReady!"], function(ready, dom, domConstruct,abc){
var test={
step11: function(timestamp) {
window.requestAnimationFrame(test.step11);
}
};
test.step11();
return test;
});
Related
I'm now using casperjs for web crawling. Almost everything is good, but I faced some trouble. First, my code is like below.
casper.start().each(SOME_URLS, function(self, URL) {
self.thenOpen(URL, function() {
self.then(function() {
var getDatas = function() {
var title = $('SOME_SELECTOR').map(function() {
return $(this).text();
}).get();
return {
title: title
};
}
data = self.evaluate(getDatas);
console.log(JSON.stringify(data));
});
});
}).run();
I want to get some data from webpage to 'data' variable. Sometimes data is perfectly good(on console.log), but sometimes, data is empty!
Why this happening? What did I wrong?
The problem is you cant call casper.start more than once. Your loop needs to inside the casper.start function or inside a casper.then
See this excellent SO answer to help you do this.
Basically only call casper.start once and place your loop inside a casper.then
I am learning how to write a jQuery plugin. I have this code below, my question is what does this stand for in the code below?
$.fn.myNewPlugin = function() {
return this.each(function() {
// Do something to each element here.
});
};
When you write a plugin you are extending the jQuery object, and because the jQuery object is a sequence, when you use return this.each(function () { }); then your plugin is executed for each item of the sequence.
For some reason when I try running the following code:
var casper = require('casper').create();
var x = require('casper').selectXPath;
var links = [];
casper.start('http://www.website.com');
function getLinks() {
var links = document.querySelectorAll(x('//*[#id="horizontalList"]/li[#class="paddingRight6"]/a');
return Array.prototype.map.call(links, function(e) {
return e.getAttribute('href')
});
}
casper.then(function() {
links = this.evaluate(getLinks);
this.echo(links);
}
casper.run();
Returns a null object, but when I use the very same xpath selector in conjunction with the thenClick method, everything works fine and the url changes. Why on earth is that?
So, it turns out that the querySelectorAll method doesn't actually support XPath. In fact it doesn't come from casperjs at all, and is supported by the browser, which is why it accepts CSS3 selectors, and not XPath. It was tough for me to figure that out so I figured I would put this up in case anyone else had this problem. You have to use CSS3 selectors for this within casperjs so the line:
var links = document.querySelectorAll(x('//*[#id="horizontalList"]/li[#class="paddingRight6"]/a');
Needs to be changed to:
var links = document.querySelectorAll('ul#horizontalList li.paddingRight6 a');
Happy hacking
The below function works for me with Xpath.
function getLinks() {
var links =__utils__.getElementsByXPath('//*[#id="horizontalList"]/li[#class="paddingRight6"]/a');
return Array.prototype.map.call(links, function(e) {
return e.getAttribute('href');
});
}
Imagine that I have a view, and as part of a view it render 'x' model objects, and 'x' only. The question, where is it appropriate for me to put this view related constant?
My guess would be to do something like this:
myApp.MyView = Backbone.View.extend({
...
myConstant: 10,
...
render: function(){
...
//some code that uses myConstant
...
}
});
Does this make sense?
Any suggestions help!
It sounds like what you want to do is to assign a class property to the view. You can pass a second hash into your extend call to do this. Your code would look something like this:
myApp.MyView = Backbone.View.extend({
render: function() {
alert(myApp.MyView.myConstant);
}
}, {
myConstant: 10
});
where your constant is accessible as myApp.MyView.myConstant.
You're very close! You'll actually just use this.myConstant. Here is a working example...
testView = Backbone.View.extend({
test: "hello world!",
initialize: function(){
alert( this.test );
_.bindAll(this, "render");
},
render: function(){
//do your rendering...
return this;
}
});
var view = new testView();
As above I agree with (and upvoted) the accepted answer however for clarity I would be tempted to go with this format:
myApp.MyView = Backbone.View.extend({
render: function() {
alert(myApp.MyView);
}
});
_.extend(myApp.MyView.prototype, {
enum : {
//...
}
});
The reason being you might have lots of mixins for your view and I find the visibility becomes blurred when you just keep adding on object after object to View.extend. At least this way you can break it up and put comments in-between your mixins. It also makes a bit more sense if you're using RequireJS and loading in a common set of enums/mixins.
Don't initialize your view constants under extend, it will behave like static constant for all your view instances. Use constructor instead:
constructor: function()
{
Backbone.View.prototype.constructor.apply(this, arguments);
this.myConstant = 10;
this.myOtherConstant = {};
}
more explanation here
Why are none of the live (or dead) events I bind to a dynamic element firing?
(function ($) {
$.fn.myPlugin = function () {
var $filterBox = $("<input type='text'>").live("click", function () {
alert("Clicked");
});
this.before($filterBox); // insert into DOM before current element
return this; // keep chain
};
})(jQuery);
I am calling myPlugin on several <select> elements. I thought it would work without the Live plugin if I bound it before adding the element to the DOM, but not even the live events are firing. Is it because my element has no ID?
Edit:
The following does not work either:
var $filterBox = $("<input type='text'>").bind("click", function () {
alert("Clicked");
});
.live() works off a selector (since it checks the target against the selector at the time the event happens), you can't attach it directly to an element...you should just use .click() in these cases:
(function ($) {
$.fn.myPlugin = function () {
var $filterBox = $("<input type='text'>").click(function () {
alert("Clicked");
});
this.before($filterBox); // insert into DOM before current element
return this; // keep chain
};
})(jQuery);
You can try it out here, or a bit shorter with .insertBefore():
(function ($) {
$.fn.myPlugin = function () {
$("<input type='text'>").click(function () {
alert("Clicked");
}).insertBefore(this);
return this;
};
})(jQuery);
You can test it here.
The live method works with selectors, not detached elements.
You can handle the normal (non-live) click event, and it should work fine.
Why not just bind it? http://jsfiddle.net/9WvpA/
Can it be just because "<input type='text'>" is not a valid HTML? You have not closed your tag. However, I am not sure whether jQuery is unable to close it for you.
Solved by not using global variables that replaced each other, and iterating over each element in question with this.each(...):
(function ($) {
$.fn.myPlugin = function () {
return this.each(function () {
// do stuff
});
};
})(jQuery);