How to prevent adding elements to a DOM node? - javascript

I have a pretty disgusting issue. "Disgusting" because I do not have full control of the whole webpage and therefore have to hack my way to success.
Situation
I have my own script, which is loaded into the webpage, and a div container, that displays the pageĀ“s navigation. I want to add a link to that container and that container should only contain that single link.
Problem
There is a third party script, which also adds links to that container. It does that inside a AJAX callback function
What I have tried
1. Deleting all links but mine after document is completely loaded
This is not possible because third party script loads content via AJAX callback, so when page is fully loaded the unwanted links have not been rendered yet.
2. Renaming div container
After adding my link to the container I stripped the container completely naked, deleting class names, IDs etc. But the third party script still finds that container.
3. Attaching DOMNodeInserted event to the container
Works great in anything that I call a browser. But fails in IE. And the IE is the main browser the user of that page use.
What else can I try?

If the third party script uses jQuery then you can try ajaxComplete().

You can listen to DOMSubtreeModified event, and restore original div state.
var originalChildren = $('#content').children();
var setOriginal = function(e) {
$('#content').off('DOMSubtreeModified');
$('#content').empty().append(originalChildren);
$('#content').on('DOMSubtreeModified', setOriginal);
};
$('#content').on('DOMSubtreeModified', setOriginal);
Test it.

You could override/wrap the DOM methods the other script is using to add elements, such as appendChild(). Something like this (psuedocode)
var originalAppend = document.appendChild;
document.appendChild = function () {
if condition {
originalAppend.apply(document, arguments);
}
}

Related

On load instead of document ready with other javascript on page?

I currently have this bit of code going that looks for a certain class and adds the QTY text inside the class. I have to do it this way as I don't have access to the base HTML code for this portion of the site, but rather can do so via JS access.
The current code I have running is as follows:
$('.cart-product-qty').each(function() {
$(this).prepend("QTY: ");
});
But the problem I just ran into is when certain functions are performed in the shopping cart it doesn't refresh, so it ends up dropping the QTY text. Is there another method so that it keeps it there continuously even if the page "refreshes"?
Listen to the parent div underneath the products will be listed. So whenever the content changes, you can trigger your function.
DOMSubtreeModified event might be helpful.
var element = document.getElementById('div');
element.addEventListener('DOMSubtreeModified', updateQtyText);
function updateQtyText(e) {
$('.cart-product-qty').each(function() {
$(this).prepend("QTY: ");
});
}
Reference : fire a call when inner HTML changes.
This might help

Unable to append HTML to an element in JavaScript or jQuery from inside a function

I am trying to use Barba to implement smooth page transitions. Here is my code to append some HTML when a new page is added.
Barba.Dispatcher.on('newPageReady', function(currentStatus, oldStatus, container) {
console.log("I am In.");
$("#quick-share").append("Share Now!");
});
The appending works from the developer tools console but from inside this function it doesn't. However, the console.log() statement works properly without any issue. I have also tried a pure JavaScript way but it doesn't work inside the Barba function either.
document.getElementById("quick-share").innerHTML = "Share Now!";
Is there something that I am missing?
Thanks.
In fact with Barba.js when you make a transition, the new content will override the old one, that's what we can see in their How it works section:
5- As soon the new page is loaded, barba.js parses the new HTML (taking .barba-container) and puts the new content on the DOM inside #barba-wrapper.
6- The transition instance will take care of hiding the old container and
showing the new one.
7- As soon the transition is finished, the old container is removed from
the DOM.
So your problem is that when calling $("#quick-share"), in the 'newPageReady' event, the old content was removed so it won't return any element with that id, that's why you can't see the text appended.
What you can do is to recreate this element in the new container, in the transitionCompleted event handler.

jQuery : delete a page

I'm using jQuery mobile and my page is generated from an index.php file. When I click on links referring to another option of my php file (index.php?action=other_action) it loads in Ajax so the previous content is still kept in the code. This causes problems as nothing is dynamic anymore, because I'm using specific ids, so it breaks everything. Of course disabling Ajax works but I loose all the beauty of jQuery Mobile.
I guess a solution would be to create an onclick function on the <a>, that will prevent the page from keeping the previous content or delete the old page.
So is there a way to keep using ajax in a way that it doesn't break my dynamic elements ?
You can see it in action here, you can filter names if everything's good. Then click on the top left panel and click something, notice what happens in the inspector...
Thanks for any help.
Hi you have missed enclosing the selector within qoutes...
your jQuery
$(document).ready(function() {
//bind a listener to "click" event on links with class "markviewed"
$('a.ui-btn-present').click(function(event) {
$('ul.listlist').listview('refresh');
$(#pageone).remove(); //<-- selector should be within quotes
// get ids from clicked <a>
var id = $(this).attr('data-id');
$(this).attr({
"class" : "ui-btn ui-btn-icon-notext-ok ui-icon-check ui-btn-a"
});
After much more research I wasn't looking in the right direction: the problem was that the listview had to be refreshed. So I created a new function
<script>
function refreshlist() {
$('.listlist').listview("refresh");
$('#pageone').remove();
};
</script>
And then I added onclick= "refreshlist()"to all my links and now it works.

How to call a Greasemonkey function when a JavaScript link is clicked

So I recently started working on Greasemonkey scripts without much prior experience in JavaScript. It was going fine until I hit this roadbloack.
I'm writing a script for a page that has a small table of information. If a link at the bottom is clicked, the table expands fully in the page to display all information. I need to call a function in Greasemonkey when this happens, however, the link doesn't appear to have an ID or anything I can actually reference to watch it. It's simply this:
When it's clicked, the table expands and it then shows as true. I initially used the following to expand the table upon loading the page, but that broke several things:
window.location.href = ('javascript: expandFullTable(false)');
I've attempted using "click", "onclick", and even "mouseover" to have Greasemonkey detect when it's pressed but nothing seems to work. From what I can tell it's simply a link that calls a function, but after some significant searching I wasn't able to find out anything about how to reference it in my script. I'm sure it's incredibly simple, but it's frustrated me to no end.
You can hijack the function like this:
var oldExpandFullTable = unsafeWindow.expandFullTable;
unsafeWindow.expandFullTable = function() {
// Do something
alert("You clicked on that thing!");
// Call the original function
oldExpandFullTable.apply(this, arguments);
};
But since you tagged this jquery this should let you retrieve the link:
var link = $("a[href^=\"javascript: expandFullTable\"]);
It should work if jQuery is injected into your script with #require. If it's already in the page, you can add this before to access it: var $ = unsafeWindow.jQuery;.
And by the way, perhaps you should learn more about unsafeWindow to avoid security holes.

Dynamic web page resizing with javascript

I currently have a page that is being resized through the use of javascript whenever the end-user resizes the window, so that scrolling is reduced or eliminated when not necessary. I have a loader.js jquery file which picks out .html documents to throw in to the content section of the page when the user selects an option from the left menu:
$("#response").load("home.html");
$("#home").click(function(){
// load home page on click
$("#response").load("home.html");
setTimeout("resizefunc()",500);
});
$("#about").click(function(){
// load about page on click
$("#response").load("about.html");
setTimeout("resizefunc()",500);
});
//etc
While these timeout functions work most of the time, they have the potential to fail if the page loads abnormally slow for any reason. I am using document.ElementId.scrollHeight to determine the height of each new page, but it seems to only detect the height after the changes have been correctly applied. If the javascript loads before the page content then the resize fails.
It seems that if I were using complete html documents for each page then the problem would be irrelevant. I could put an onLoad event in to the body of each one and have it resize there... But since the tag is only loaded once I'm somewhat at a loss. My current implementation "works", but I feel that there should be something more efficient.
Don't use onLoad, instead wrap your code in
$(window).load(function() {
// your code here
});
Also, instead of load() with just the filename as a parameter, use:
$('#response').load('file.html', function() {
resizefunc();
});
Along with "load" you could also use "resize" as one of the events. This would allow dynamic resizing.
$(window).resize(function() {
resizefunc()
});
function resizefunc()
{
// code to resize.
}
See: http://api.jquery.com/resize/

Categories