How to remove an event out of content script scope? - javascript

I'm trying to unbind an event from a specific element and upon research, I found this. Which is useful. In itself. I didn't know you could do that. But:
Is there a way to make it work in a browser/Chrome extension? I'm talking about content scripts.
The reason why this doesn't work the way it's described there is that the website which has attached the event in question with its own script is using a different jQuery object than the one in my extension's includes/ folder. And I can try to search the event via jQuery._data(el, 'click'); but that is my jQuery object, not the one of the website where the events are apparently stored. I'm glad I figured that out after hours of fiddling around.
Or maybe it is possible to access the website's jQuery object itself?
EDIT:
What I'm ultimately trying to achieve works in theory but … it's complicated. The original script uses a plugin event and keeps reinstalling it with .on('mouseleave',….
Anyway, this is what I got thanks to you, pdoherty926:
var $el = $('div.slideshow');
$('h2', $el).click(function(){ console.log('ouch!'); }); // test event
var $slides = $('.slides', $el).detach();
$copy = $el.clone(false);
$slides.prependTo($copy);
$el.replaceWith($copy);
The test event doesn't get triggered but the event I'm actually trying to remove still fires. I can imagine figuring it out, though, now that I got closer to my goal.

Okay, the aforementioned re-installation on mouseleave really messed up this otherwise satisfying suggestion. (The site is using the jQuery Timer plug-in by Cyntaxtech). So here's how I solved it instead: I simply changed the class name (-.-' )
Now the re-installation code cannot find the element anymore.
This is how my finished script looks like:
function stop_happening() {
var $el = $('div.fullwall div.slideshow');
$el
// first, stop the current automation.
.timer('stop') // Timer plug-in
// next, change class name in order to prevent the timer
// from being started again.
.removeClass('slideshow').addClass('slideshow-disabled-automation');
//--- copied some extra code from the website itself for the onclick
// events which are supposed to keep working. I wish I could do *that*
// programmatically but I'm glad I got as far as I got. ---//
// […]
}

Related

Prevent copy on an empty iFrame (GWT RichTextArea)

I am required to prevent copy from a form. Using a oncopy handler works just fine on all <input/>-type fields.
Yet I fail to apply it to our "richtextarea", which is basically an empty iframe (src="about:blank" for what I have been able to gather; the page is GWT-generated, and the people before me developped quite an extensive framework around it).
I am able to get the iframe in the JavaScript, but I fail to have a correct handler (I tried adding one that logs, but it never does).
I have tried frame.oncopy, frame.contentWindow.oncopy, frame.contentWindow.document.oncopy, frame.contentDocument.oncopy. None of these does log to the console when I copy the iframe's content.
Does somebody have any lead for me? Any help appreciated (I've been stuck on this for some days now).
Having a cross-compatible solution would of course be ideal, but the main target is Firefox (the page is only open via a custom container based on Firefox 10).
Edit 2015-03-24
For those who want to try some debug script, the component I have trouble with is the one demonstrated here.
I have some native methods in the Java project to execute some custom JavaScript on it.
Below is some of the JavaScript I have unsuccessfully tried.
var frame = document.getElementsByTagName('iframe')[0];
function disallowCopy() {
alert('Gotcha!');
return false;
}
frame.oncopy = disallowCopy;
frame.contentWindow.oncopy = disallowCopy;
frame.contentWindow.document.oncopy = disallowCopy;
frame.contentWindow.document.body.oncopy = disallowCopy;
frame.contentDocument.oncopy = disallowCopy;
even though oncopy is a non standard event https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/oncopy and that there is no reliable way to prevent copying text,
you can check out the following bin
ensure the frame is loaded
use iframe.contentDocument.body to attch the event

Add class to dynamically generated HTML

I'm working to use custom checkbox styles with a checkbox which is dynamically generated by javascript for the Google Identity Toolkit. For example, we add this div:
<div id="gitkitWidgetDiv"></div>
And the Google Identity Toolkit script generates new html for that div.
I need to add a class to the HTML which is added by the javascript without any action by the user and I'm struggling to make it work. For example, here is my code:
$("#gitkitWidgetDiv").on('ready', ".gitkit-sign-in-options label", function() {
$(this).addClass('checkbox');
});
I've tried switching 'ready' for a few other options and also using the livequery plugin, but nothing is working for me. It works if I use an active event like 'click,' but I can't figure out how to do this when the page loads. Could someone please help? Thanks!
Modern browsers (including IE11) support mutation obervers. You can use one to monitor the parent node of the div that will be added. When the div has been added, just add the class.
Here's something I made which comes in handy in annoying cases like this where it's difficult to tell when the element you need has finished loading in: https://gist.github.com/DanWebb/8b688b31492632b38aea
so after including the function it'd be something like:
var interval = 500,
stopTime = 5000,
loaded = false;
setIntervalTimeout(function() {
if($('.dynanicElementClass').length && !loaded) {
$('.dynanicElementClass').addClass('checkbox');
loaded = true;
}
}, interval, stopTime);
It's not perfect and I'm sure there are better solutions out there but in most cases like this it does the job.

Dynamic CFTab onClose event

I simply can't find any real documentation on ColdFusion Layout Tabs. For the most part I've got them working, but I'd like to tie some logic to a close event. I was wondering if anyone had a working example they could show me? The catch is that I will need to trigger these events in JavaScript. But if you have a working version in plain ColdFusion, I'd still love to see it!
var tab = ColdFusion.Layout.getTabLayout("innerTabLayout").activeTab._cf_body;
$('#' + tab).on('close', blah); // doesn't work
tab.on('close', blah) // doesn't work
ColdFusion.Layout.getTabLayout("innerTabLayout").activeTab._cf_body.onTabClose( function(), blah ); //doesn't work
I have also tried setting the event on tab creation:
var tab = ColdFusion.Layout.createTab();
tab.onTabClose()
tab.on('close');
However, none of these work either. I've tried looking at EXT.JS which is what CFtabs were created from, but I don't seem to have any luck there either.
The Coldfusion.Layout object has a function for tab closing, so there must be a way to trigger it! (I would think, haha).
So after spending some too much messing around with the tab, I've got a solution.
ColdFusion.Layout.getTabLayout('innerTabLayout').activeTab.on('close', function(e) {
console.log(this) //this will return the tab object
console.log(e)//this also returns the tab object
});
This will trigger the event when the active tab within a parent is closed. I'm interested to see if there's another, better solution.

Prevent function from executing or removing anonymous event listeners

I'm creating a Chrome extension for a website that has no open API, so I'm stuck reading Closure Compiled spaghetti code for a long time. I've made a lot of progress but I seem to be stuck. On the page's onload, this function executes:
function comments_initReply(){
var b=$("#ajax_comm div.com");
for(var a=0;a<b.length;a++){var d=$(b[a]);
var c=d.find(".commentReplyLink");
if(c.length){
d.on("dblclick",function(){$(this).closest("div.com").find(".commentReplyLink").click()}).find(".t")}
}
}
What it does is it takes a comment div on a website and it makes it into a large double-clickable area for you to open a reply. All I want to do is remove the double-clicking property so you can double-click text and highlight it instead of opening a reply modal dialog.
Since the function is anonymous, it cannot using removeEventListener to detach it. Any ideas? I prefer to not use jQuery.
Well, although you prefer not to use jQuery, it's much easier to use it, and my solution here will be jQuery-based, and feel free to convert it into a normal Javascript, if you want to.
function comments_endReply() {
$("#ajax_comm div.com").off("dblclick");
}

JavaScript/FullCalendar - Attaching event to event rendering

My full code is here: http://pastebin.com/nctMtX9m
I've got an instance of FullCalendar, and using the 'className' property of the event object, I'm adding icons to certain events after the calendar renders. These simple icons indicate if a job (event) on the calendar has been shipped.
$(window).load(function(){
$('a.shipped div span').prepend("<img src=\"/img/truck_white.png\" title=\"Shipped\" alt=\"Shipped\" style=\"padding:2px 5px 5px 0; width=\"16\" height=\"16\" />");});
This works great! The problem is that whenever I change the view, like changing the month then coming back, FullCalendar completely re-renders the events! This means they are without my icons now since my icon adding process only occurs once, after the initial render.
I need my icon adding process to fire every time the FullCalendar renders events.
I've found this: http://arshaw.com/fullcalendar/docs/event_data/events_function/ but unfortunately my evens are written to the page by PHP, so they are statically defined as far as the script is concerned. This example leads me to believe that I can only do this with an external data source. This level of JavaScript is admittedly not my forte.
How do I attach my icon adding process to something that fires every time Fullcalendar renders events if my event data is statically defined?
Thanks!
edit I found out how to do what I want using eventRender, but I can't seem to reference the part of the element that I want to, because now the rendering is slightly off. I'll work on this further and update when I find the answer.
edit 2 Figured it out, can't post answer because I'm new. Will post answer tomorrow.
The solution was to use eventRender.
eventRender: function(event, element) {
if(event.className == 'shipped'){
var find = '<span class="fc-event-title">';
var replace = find + '<img src="/img/truck_white.png" title="Shipped" alt="Shipped" class="event_icon" />';
var newHTML = $(element).html().replace(find, replace);
$(element).html(newHTML);
}
}
It's a bit of a convoluted find/replace, but it works.

Categories