I am trying to detect a start click in jwplayer. I am embedding it via swfobject so the method is slightly different from the example in the api, http://www.longtailvideo.com/support/jw-player/jw-player-for-flash-v5/16024/listening-for-player-events
I have tried
var flashvars = {
'file':'xxx',
'streamer':'xxxxxx',
'image':'xxxxx',
'plugins':'xxxxx',
'gapro.accountid':'xxxx',
'gapro.trackstarts':'xxxx',
'gapro.trackpercentage':'xxxx',
'gapro.tracktime':'xxxx',
'logo.file':'xxxxx',
'logo.link':'xxxx',
'logo.hide':'xxxx',
'logo.position':'xxxx'
};
jwplayer().onPlay(function() {alert('it has started'});
jwplayer() is not defined, how do I defined an object to detect the click?
The player is probably undefined because it hasn't been created yet. You should wrap your command in a callback from a DOM ready listener. Since you're using jQuery you can use its .ready() method (jQuery documentation):
$(document).ready(function(){
jwplayer().onPlay(function() { alert('it has started'); });
});
Just a note about jwplayer onPlay(), it doesn't necessarily happen from a click event, it fires whenever the video is played, which could be by clicking play, or by programmatically playing the video. All it's telling you is that the video is playing. (Corrected the syntax error)
Related
I am beginner programmer with CasperJS and I love to try new things with scraping. My problem:
I am able to login to youtube and like a video, but I cannot find correct XPath for youtube comment like button.
http://tinypic.com/r/2vayr83/8
Here is the part I am stuck on, I always get error:
wait timeout of 5000ms expired exiting-
so I guess that's because of the incorrect XPath and I want to do that on a specific comment. How could I do that?
casper.waitForSelector(x('//*[#id="update-z132gvlzosmchn30f225wng5gluzgbs5o04"]/div/div/div[1]/div[4]/div[3]/img'), function() {
this.click('//*[#id="update-z132gvlzosmchn30f225wng5gluzgbs5o04"]/div/div/div[1]/div[4]/div[3]/img');
this.capture('like.png')
this.echo("liked");
});
The Youtube comment thread is loaded in an iframe, so you need to change into the iframe first, before doing something in it. You can use casper.withFrame() step function to do this. Keep in mind to select the correct iframe, because there are multiple iframes.
The other thing is that nearly all CasperJS functions only accept CSS selectors by default, but you use an XPath expression for the click. You have to use the XPath utility that CasperJS provides to tell CasperJS that the passed string contains an XPath expression and not a CSS selector.
Another problem might be that the iframe is only loaded once it is scrolled into view. You might need to scroll to the bottom. CasperJS provides the scrollToBottom() function to do this. You will also need to wait until the iframe is put into the page after you scroll down.
Complete (untested) script:
var casper = require('casper').create();
casper.start(url, function(){
this.scrollToBottom();
this.scrollToBottom();
});
casper.waitForSelector('.comments-iframe-container iframe', function(){});
casper.withFrame(1, function(){
var link = '//*[#id="update-z132gvlzosmchn30f225wng5gluzgbs5o04"]/div/div/div[1]/div[4]/div[3]/img';
this.waitForSelector(x(link), function() {
this.click(x(link));
this.wait(1000, function(){
this.capture('like.png')
this.echo("liked");
});
});
}).run();
When using the HTML5 Validation API it is possible to intercept the error, access the error message and render it differently.
When using the WebShim Polyfill, I would've hoped that this would work in the same way without having to access a customValidationMessage property.
Is there a way WebShim can be configured so we can write consistent code for intercepting these error messages as below.
$("input").on("invalid", function(evt) {
evt.preventDefault();
alert(evt.currentTarget.validationMessage);
});
... I would expect this code to work in a Polyfill, perhaps I have misunderstood it's setup or something?
The reason I want to do this is so that I can grab all the invalid fields and display the errors in one block, rather than next to each field.
Thanks,
Nick
Yes, this is possible. If you setup everything correctly you only have to change your call to validationMessage. Webshims always fixes elements through the jQuery API, not the DOM element itself. Which means you always have to use $.prop to access DOM properties.
$("input").on("invalid", function(evt) {
evt.preventDefault();
alert($.prop(evt.target, "validationMessage"));
});
You can also use eventdelegation:
$(function(){
$(document).on("invalid", function(evt) {
var message = $.prop(evt.target, "validationMessage");
if(message){
evt.preventDefault();
alert(message);
}
});
});
Note:
Eventdelegation for invalid is done through event capturing (which isn't normally used by jQuery). Therefore you have to wait untill polyfill is loaded. (Normally, jQuery's ready event is delayed untill then.)
I check if an validationMessage is there, although there was an invalid event. Here is why: There was a spec change and now an invalid event is also triggered on the form element. This is currently only polyfilled in an unstable version of webshims and only for incapable browsers (IE < 12, Safari < 8 ...).
I am using the following directive to create a ckEditor view. There are other lines to the directive to save the data but these are not included as saving always works for me.
app.directive('ckEditor', [function () {
return {
require: '?ngModel',
link: function ($scope, elm, attr, ngModel) {
var ck = ck = CKEDITOR.replace(elm[0]);
ngModel.$render = function (value) {
ck.setData(ngModel.$modelValue);
setTimeout(function () {
ck.setData(ngModel.$modelValue);
}, 1000);
}; }
};
}])
The window appears but almost always the first time around it is empty. Then after clicking the [SOURCE] button to show the source and clicking it again the window is populated with data.
I'm very sure that the ck.setData works as I tried a ck.getData and then logged the output to the console. However it seems like ck.setData does not make the data visible at the start.
Is there some way to force the view window contents to appear?
You can call render on the model at any time and it will simply do whatever you've told it to do. In your case, calling ngModel.$render() will grab the $modelValue and pass it to ck.setData(). Angular will automatically call $render whenever it needs to during its digest cycle (i.e. whenever it notices that the model has been updated). However, I have noticed that there are times when Angular doesn't update properly, especially in instances where the $modelValue is set prior to the directive being compiled.
So, you can simply call ngModel.$render() when your modal object is set. The only problem with that is you have to have access to the ngModel object to do that, which you don't have in your controller. My suggestion would be to do the following:
In your controller:
$scope.editRow = function (row, entityType) {
$scope.modal.data = row;
$scope.modal.visible = true;
...
...
// trigger event after $scope.modal is set
$scope.$emit('modalObjectSet', $scope.modal); //passing $scope.modal is optional
}
In your directive:
ngModel.$render = function (value) {
ck.setData(ngModel.$modelValue);
};
scope.$on('modalObjectSet', function(e, modalData){
// force a call to render
ngModel.$render();
});
Its not a particularly clean solution, but it should allow you to call $render whenever you need to. I hope that helps.
UPDATE: (after your update)
I wasn't aware that your controllers were nested. This can get really icky in Angular, but I'll try to provide a few possible solutions (given that I'm not able to see all your code and project layout). Scope events (as noted here) are specific to the nesting of the scope and only emit events to child scopes. Because of that, I would suggest trying one of the three following solutions (listed in order of my personal preference):
1) Reorganize your code to have a cleaner layout (less nesting of controllers) so that your scopes are direct decendants (rather than sibling controllers).
2) I'm going to assume that 1) wasn't possible. Next I would try to use the $scope.$broadcast() function. The specs for that are listed here as well. The difference between $emit and $broadcast is that $emit only sends event to child $scopes, while $broadcast will send events to both parent and child scopes.
3) Forget using $scope events in angular and just use generic javascript events (using a framework such as jQuery or even just roll your own as in the example here)
There's a fairly simple answer to the question. I checked the DOM and found out the data was getting loaded in fact all of the time. However it was not displaying in the Chrome browser. So the problem is more of a display issue with ckEditor. Strange solution seems to be to do a resize of the ckEditor window which then makes the text visible.
This is a strange issue with ckeditor when your ckeditor is hidden by default. Trying to show the editor has a 30% chance of the editor being uneditable and the editor data is cleared. If you are trying to hide/show your editor, use a css trick like position:absolute;left-9999px; to hide the editor and just return it back by css. This way, the ckeditor is not being removed in the DOM but is just positioned elsewhere.
Use this java script code that is very simple and effective.Note editor1 is my textarea id
<script>
$(function () {
CKEDITOR.timestamp= new Date();
CKEDITOR.replace('editor1');
});
</script>
Second way In controller ,when your query is fetch data from database then use th
is code after .success(function().
$http.get(url).success(function(){
CKEDITOR.replace('editor1');
});
I know, that this thread is dead for a year, but I got the same problem and I found another (still ugly) solution to this problem:
instance.setData(html, function(){
instance.setData(html);
});
I have some code which does the following:
External content is loaded via AJAX (video thumbnail images)
The new content is then inserted into a div using $("#content").append();
A mobile touch scrolling helper (iScroll) is applied to this div.
However the jQuery "load" event is not firing when the DOM changes due to an AJAX event, which means the call to initialise the scroller is happening too soon (before the images inthe content has loaded) which means it often doesn't get intiiallised. Without waiting for the images to load the content box is often short enough such that a scroll function isn't needed, but then when the images subsequently load, the box is not scrollable.
$("#videoList").append(videoThumbnails);
$(document).load(function () {
// doesn't fire
initScroller();
});
It appears that jQuery's append function does not block until all images referenced in the appended HTML have loaded.
How can I detect that all of the images loaded by the AJAX function have finished loading in order to call the initScroller() function AFTER all images have loaded?
OK I've found the solution in another similar question. It turns out there's a jQuery waitForImages plugin which does exactly what I want:
So I can just do this:
$("#videoList").waitForImages(function () {
// Fires when all images in the #videoList div have loaded
initScroller();
});
The methods you are trying to use are triggered only once, when the page is loaded, but not for changes you make to the DOM aftewards (e.g. inserting content with ajax).
If you want to observer DOM changes you can use the DOMNodeInserted event
$(document).bind("DOMNodeInserted", function(event) { ....do stuff...here });
But generally it would be better to trigger this with the ajax callback.
$('#targetElementForYourContent').load('server/url.html', function() {
...do stuff here....
});
I was under the impression that jQuery's on event handler was meant to be able to 'listen' for dynamically created elements AND that it was supposed to replace the behavior of live. However, what I have experienced is that using on is not capturing the click event whereas using live is succeeding!
The tricky aspect of my situation is that I am not only dynamically creating content but I'm doing it via an AJAX .get() call, and inserting the resultant HTML into a modal .dialog() jQueryUI popup.
Here is a simplified version of what I was trying to accomplish (wrapped in $(document).ready(...) ):
$.get("getUserDataAjax.php", queryString, function(formToDisplay) {
$("#dialog").dialog({
autoOpen: true,
modal: true,
buttons...
}).html(formToDisplay);
});
$(".classThatExistsInFormToDisplay").on("click", function() {
alert("This doesn't get called");
});
From the documentation for on I found this which which was how I was approaching writing my on event:
$("p").on("click", function(){
alert( $(this).text() );
});
However, for some reason, live will work as I expect -- whereas on is failing me.
This isn't a question for "how can I make it work" because I have found that on will succeed (capture clicks) if I declare it inside the function(formToDisplay) callback.
My question is: what is wrong with on that it isn't finding my dynamically created elements within a modal popup? My jQuery instance is jquery-1.7.2. jQueryUI is 1.8.21.
Here are two jsFiddles that approximate the issue. Click the word "Test" in both instances to see the different behavior. The only difference in code is replacing on for live.
Where the click is captured by live.
Where the click is NOT captured by on (click 'Test - click me' to see nothing happen).
I realize I may just be using on inappropriately or asking it to do something that was not intended but I want to know why it is not working (but if you have something terribly clever, feel free to share). Thanks for your wisdom!
Update / Answer / Solution:
According to user 'undefined', the difference is that on is not delegated all the way from the top of the document object whereas live does/is.
As Claudio mentions, there are portions of the on documentation that reference dynamically created elements and that what you include in the $("") part of the query needs to exist at runtime.
Here is my new solution: Capture click events on my modal dialog, which, although it does not have any content when the event is created at runtime, will be able to find my content and element with special class that gets generated later.
$("#dialog").on("click", ".classThatExistsInFormToDisplay", function() {
... //(success! Event captured)
});
Thanks so much!
live delegates the event from document object, but on doesn't, if you want to delegate the event using on method, you should delegate the event from one of static parents of the element or document object:
$(document).on("click", ".clickHandle", function() {
alert("Content clicked");
});
The problem is that the element to which you attach the event has to exist.
You have to use on like this to capture clicks on p tags created dynamically
$("#existingContainerId").on("click", "p", function(){
alert( $(this).text() );
});
if you have no relevant existing container to use, you could use $("body") or $(document)
If selector is omitted or is null, the event handler is referred to as direct or directly-bound. The handler is called every time an event occurs on the selected elements, whether it occurs directly on the element or bubbles from a descendant (inner) element.
When a selector is provided, the event handler is referred to as delegated. The handler is not called when the event occurs directly on the bound element, but only for descendants (inner elements) that match the selector. jQuery bubbles the event from the event target up to the element where the handler is attached (i.e., innermost to outermost element) and runs the handler for any elements along that path matching the selector.
Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on(). To ensure the elements are present and can be selected, perform event binding inside a document ready handler for elements that are in the HTML markup on the page. If new HTML is being injected into the page, select the elements and attach event handlers after the new HTML is placed into the page. Or, use delegated events to attach an event handler, as described next
Take a look to section Direct and delegated events here for more details