How does this JS copy trick work? - javascript

On this page almost anywhere on the page if you copy you'll get the string Read more at http:// added to the end of your copy. I was wondering how. After looking at the source (post-copypaste.js) and setting a breakpoint I didn't understand. That area seems to be firing when i select text.
I tried looking at the DOM (via view selected source in firefox) and I didn't see the text in the dom. So it must be a javascript trick. I can imagine catching a control C event (i dont know if that is what is happening) but i cant imagine how you can add or affect the text being compied in since it belongs to the dom. I don't see flickering or anything
How does that JS trick work or how do i debug it to figure it out?

But the awkward thing is the selection on the regular window/dom doesn't seem to be affected.
It is, but just not visible. What usually happens is there is a container somewhere else on the page (not necessarily visible). The content you have selected is being pasted in there, then extended, then copied and deleted from the container. It all needs a fraction of a second and by the time you paste it in somewhere, your clipboard is already storing the extended content.
If you look closely on the page you have linked in as an example, there is an empty div tag in the body with a class of pw-root. <div class='pw-root'></div> When you copy the text, for a second (visible in Firebug for instance) it changes as explained above then gets emptied again.

Related

Why does the value attribute from an input[text] is different from what the browser renders?

I'm getting this strange behaviour in a very specific set of inputs on one my applications. I create some inputs and I can see them as I created them on the Elements panel (google chrome), but the way the browser renders it is different.
Note how the input is renders with comma instead of a point, but the value attribute uses a point
When I get a referente to that element using the selector API, I get this:
A direct reference to the Dom Element will return 11,00. The tag has 11.00 and jQuery returns the 11,00. I've removed all js that interacts with this element (masks, events, etc) and the issue still happens.
I've been swearing at the DOM for a day and a half, but I know this is most probably an issue with my application. What bothers me the most is that the browser does not honor what I see in the elements panel.
This is the small piece of code that creates the element, stopped right before the tag is created. Note the variables values in the right panel:
Could someone give me a hint about what could be causing this difference in between element, view and attributes? If possible, I'd like to know what/how this is happening in depth.
Thank you in advance

IE8/9 dynamically inserted elements are invisible for a nondeterministic amount of time

Has anybody else encountered this problem and arrived at a satisfactory solution?
Basically I have a very complex web application which under IE9 Quirks mode (There is no possibility of switching the doctype as of right now) a specific type of element being dynamically inserted via jQuery is failing to present itself fully. It participates in page layout, but the element itself does not appear.
Sometimes 5 seconds later, and sometimes 30 seconds later, and sometimes even later than that, the element will finally magically appear.
I have used the F12 dev tools (both with and without the "Begin Debugging" clicked) and it does present the element in question, and it does not show the blue border indicator (as it's apparently not being rendered no rendering of its border appears, this is logical).
The temporary functioning workaround has been to dynamically remove the element, and reinsert it, in a nested setTimeout() chain. Then I have to re-install click event handlers.
Like this:
if (isQuirksMode()) {
setTimeout(function() {
var parent = jqelement.parent();
var removed = jqelement.remove();
setTimeout(function() {
parent.append(removed);
removed.children('input').click(clickcallback);
},0);
},0);
}
jqpage.append(jqelement);
This code will force the element to be inserted, removed from DOM, and inserted again, and after that it seems to correctly display.
The reason for doing it this way is that I tried adding and removing a class, in hopes it would trigger a re-render, but that did not change any behavior.
My question is, does this behavior ring any bells for anyone, and have you been able to come up with a less expensive way of getting it to behave?
Injecting elements as strings all in one go is much faster than injecting them individually into the DOM.
Build it up in a string - use innerHTML to insert.

Get the html of the javascript-rendered page (after interacting with it)

I would like to be able to save the state of the html page after I've interacted with it.
Say I click a checkbox, or the javascript set the values of various elements.
How can I save the "javascript-rendered" page?
Thanks.
In Chrome (and apparently Firefox), there is a special copy() method that will copy the rendered content to the clipboard. Then you can do whatever you want by pasting it to your preferred text editor.
https://developers.google.com/chrome-developer-tools/docs/commandline-api#copyobject
Console Example:
copy(document.body.innerHTML);
Note: I noticed Chrome reports undefined after the method is run, however, it seems to execute correctly and the right content is in the clipboard.
That should do and will grab the ALL page not just the body
console.log(document.getElementsByTagName('html')[0].innerHTML);
document.body.innerHTML will get you the HTML representation of the current document body.
That will not necessarily include all internal state of DOM objects because the HTML contains the initial default state of objects, not necessarily the state that they may have been changed to. The only way to guarantee you get all that state is to make a list of what state you want to save and actually programmatically get that state.
To answer the part of your question about saving it, you'll have to describe more about what problem you're really trying to solve.
To get the equivalent of view source with javascript rendered, including doctype and html tags, copy the command into the chrome console:
console.log(new XMLSerializer().serializeToString(document.doctype) + document.getElementsByTagName('html')[0].outerHTML);
In the chrome console, hover at the end of the output and click on the copy link to copy to the pasteboard.

Jquery (input/textarea).val(): how is it adding content without changing the DOM?

take a look at the JsFiddle here:
http://jsfiddle.net/ru2Fg/2/
Essentially, it starts with two textareas: one empty, one with stuff inside, and an input type=text. I was under the impression that to put stuff in an input you change it's value, and to put stuff in a textarea you add the text as a child to the node.
I perform a $(...).val(...) to change their contents. And their contents do change.
However, the DOM looks exactly the same! I'm printing out the 3 elements with console.log(); they seem unchanged. I look at them with chrome's inspect element: they seem unchanged.
I've looked at jQuery's val() method change doesn't seem to change the DOM, but that question concludes it's something funny with firebug not refreshing the HTML it displays. In this case, i'm quite sure inspect element displays the current html that exists on the page: i've seen the left attribute changing furiously when things are scrolling, for example. I'm also checking it using the console, which tells me the same thing: nothing changed.
My eyes, though, tell me something has changed, as I'm seeing "10, omg, moo" instead of "blank, hello world, 2000". What's going on?
EDIT: I posted the wrong jsFiddle. This should be the correct one now
There is a difference between the value attribute and the value property. When you type in the input box, you are changing the property, not the attribute. The attribute stays the same as when the document was loaded. Among other things, this means you can reset an input box to its default value with elem.value = elem.getAttribute('value');.
Similarly, if you have a drop-down <select> with one of the options having the selected attribute set, even if you choose a different option that attribute will still be there even though the selected property is now false.
The same applies to checkboxes and the checked attribute. The same also applies for the disabled attribute, and several other things too.
It is in-fact changing the DOM, other ways the 10 woulnd't have showed up in the text area anyway. The problem is in the firebug itself(at list the old one), I am not sure if it is still available in the new ones.
To verify, you can use the web console of firefox or console of chrome.
The DOM is completely loaded before anything jQuery happens, so technically the data inserted in the DOM isn't seen by debuggers. The debugging tools see only what is rendered so you won't be able to manipulate the "after the fact" data that arrives via jQuery. You could consider it "out of band" or fudging the DOM in a way. The same happens with AJAX. If you add in data or page content with AJAX methods like .load() you won't see it in the DOM.
An input box in jQuery has the val() method -- which is the value attribute, in the textarea, it is usually the html() method, what the textarea contains.

javascript iframe "top." multiple divs?

I orginally asked this question and at the time I was grasping at straws. I created the following fiddle that is closely related to what I'm actually seeing on my internal application:
http://jsfiddle.net/uwtj9/10/
There is a normal index.asp page. On that page I can open a div that includes an iFrame (so a popup). Then from that iFrame I can then open another div that includes another iFrame. However, when the second div opens I am trying to close the 1st div. Hopefully that makes sense.
However, when I try to open the second div, the code to create the iframe never gets run. I think it has to do with the "top." that is currently in my internal application code. When I try to add top.hidepopwin I get an error in Firebug:
Permission denied to access property 'hidePopWin'
However, in my code internally I don't get that error message, but I don't get into the doPopWin code.
Unfortunately for whatever reason when I take out the top. in my code internally it doesn't quite work the way I'm expecting (and I can't replicate it on the fiddle). Basically the second div gets created but it remains the same size and not all the elements are getting cleared (i.e the original menu is still showing up under the new menu).
Anyone have any idea's on this? The fiddle seems to be working as I expect but this "top." thing is kind of weird.
UPDATE:
SLaks answer of why the "top." doesn't work for jsFiddle is acceptable. I'm still left wondering about this issue:
Unfortunately for whatever reason when I take out the top. in my code internally it doesn't quite work the way I'm expecting (and I can't replicate it on the fiddle). Basically the second div gets created but it remains the same size and not all the elements are getting cleared (i.e the original menu is still showing up under the new menu).
Any ideas?
top returns the window object for the outermost frame hosting your page.
In jsFiddle, that's the root jsfiddle.com page, which is in a different domain than your user code. (user submissions in jsFiddle run in http://fiddle.jshell.net)

Categories