I have a page with a select. Then onchange, based on the value selected, a URL is loaded into a div (using $('myDiv').load()) This URL is allowed to have javascript/jquery that executes, which means that it can manipulate the DOM outside of the div in which it loaded.
The desired functionality is to have dynamic tools based on which value is selected. To prevent unintended crossover of functionality, whenever the select value is changed, the previous value's elements/scripts/everything it loaded from the URL should be removed from the page. Ideally I would be able to search the DOM and find all elements that had some kind of attribute pointing to which script they were generated from. I haven't been able to find any such attribute. I don't want to rely on the outside script giving its elements a certain class to mark them as an element that needs to be removed.
Think of a hotel: The client doesn't need to make the room ready for the next person to stay in that room. The hotel is responsible for that.
What can I do to make this work?
Related
Google Tag Manager's Element Visibility Trigger appears to be a rather excellent way of tracking whether an element has appeared within the viewport, using a class or ID.
The standard reporting appears to pull back data something like this
However what I would like to do is to be able to use the trigger to detect and report items in a dynamically created list. For instance the element would be triggered based on its class which is shared by all the other elements in the list, each element may be populated with specific data to be pulled from a database eg: name, product ID, price etc.
Currently this has been done using the Custom Event Trigger, but this reports all elements on the page whether they are loaded or not.
What I would like to know is whether the element visibility trigger is the right thing for this and if so, how can I manipulate it to do what I need?
Probably yes.
You'd use the CSS Selector and select via the class name for your dynamically created items.
In the "When to fire this trigger" option you would select "Every time an element appears".
Finally you would set the "listen to DOM changes" option. This checks every time the DOM is manipulated (e.g. by inserting your list element) if the other criteria in the trigger are now matched.
Note that GTM warn that there may be a performance penalty for using that option (since this runs on every DOM manipulation). So you probably don't want to do this a lot.
This question is based on a misconception, please see this question instead.
Subject
I am trying to create some context menu options via a Google Chrome extension that allow you to modify the contents of editable fields on certain web pages. My extension works perfectly on StackOverflow, where the DOM is nice and simple, but Youtube has been giving me trouble for some time now.
Problem
Many of the editable fields on Youtube are hidden in Iframes, so if I try to access document.activeElementfrom the top frame, I get the Iframe itself.
I am trying to get around this by injecting chrome.runtime.onMessage() listeners into every page.
Then, I can presumably compare the value returned by info.frameURL in the chrome.contextMenus.onClicked() event listener in the event page, with window.location.href in the content scripts to see if the message is addressing the correct frame or not. (See this question)
The problem is that the value returned by info.frameURL does not seem to be consistent.
For example, if you go to the home page and use the main search box as the test element, sometimes the value is simply, www.youtube.com...., but other times it is plus.google.com..... or apis.google.com..... or accounts.google.com... and I am not sure why this is.
Can someone explain why the value returned by the info.frameUrl would not remain constant each time you click the same frame?
I have a single page application which create and remove a number of iframe based on user input. each iframe could contain a jqgrid, a form for input submission with jquery.validate plugin etc...
the main page could access all the iframes to retrieve current operation status and some data to rebuild the main menu.
is safe to just remove the iframes or i need to .empty() the body before removing them?
EDIT:
when i say "retrieve current operation status and some data" i actually access the iframe properties using something like this
jqueryFrameObject[0].contextWindow.myCoolProperty
but never cache the object in the main page
No : jQuery takes care of removing the elements which could lead to memory leaks :
In addition to the elements themselves, all bound events and jQuery data associated with the elements are removed.
If you don't keep other pointers (including hidden ones based for example on closures), you'll be safe. Be careful not to use the native addEventListener if you don't want to keep hidden links to your removed elements.
I've been wondering how to efficiently and generically process content that is generated after any user action.
For instance, let's say my script processes all paragraphs of Facebook at page load in order to make them blink. What would be the most responsive way to make the text that is displayed later (because of infinite scroll e.g.) blink ?
Thanks in advance for your ideas,
Rolf
Personally, I define a function called dom_mods() that modifies the page in order to apply any special effects such as autocompletion, default value for <select>, auto-resizing textareas and so on. Whenever I add content to the document, I call dom_mods().
The only catch is to make sure you don't affect the same elements twice, or if you do it needs to not make a difference. For instance, there might be a class that defines a set of elements to affect, so the class should be removed by dom_mods() so it doesn't get the treatement twice.
You would add the blink function to the parent object that would encompass all the children.
In other words if you use jquery you would specify the event selector as (".parent .child") when registering the child blink event. This way, you don't need to register any additional jquery "dom_mods" function or call anything else which wastes memory and time.
I have a dialog box that has settings associated with it. When the user clicks the "settings" button, a form is displayed so they can modify them.
What is more efficient:
to have the settings div exist hidden on the page and display when needed
OR
to create the settings div and populate it with data when needed?
In the first scenario you don't need to create the DOM elements and populate them every time, but if there are many dialog boxes open at once (a common situation) then the amount of elements on the page is pretty large and many of them are not going to be used often. But in the second situation, elements are created and appended to the DOM which gets expensive.
I'd suggest you to "cache" your html on the page, but enforce browser to do not render it until necessary (until user request the data, or simply scroll to it). The main idea is to add your html (with data) to the page, but comment it out. For example,
<div id="cached-html">
<!--
<div>
...some custom html here
</div>
-->
</div>
Then once user requested the html, you can do the following:
var html = document.getElementById('cached-html'),
inner = html.innerHTML;
html.innerHTML = inner.substring(4, inner.length - 4);
Pros. is that you don't bother your browser with initial rendering (later you can simply user display:none to hide it again), so your page renders faster.
And another note - if your data (and as a consequence inner html) changes frequently, then it will be better to re-render it each time user request it, but if it is almost static, then hide/show should be more effective.
There can be problems either way, it depends on your page. If you already have a lot of elements on the page, it may be better load add them when you need them. If your page is already very "scripty" you may want to load the elements and show them when needed.
The real question is what would be better for your page, more script, or more dom elements.
When you have to display same setting div at multiple places.
Keeping that hidden is a better solution.
Remember that creating a new dom element or cloning a existing dom element gives almost same performance, but for code clarity/maintainence cloning or template is better.
Implementation using template: Make a template of div setting and keep that hidden:
<div class="template_setting">
Your settings(children of template_setting)
</div>
Javascript/Jquery code:
-Whenever someone opens a dialogue box, make a clone of childrens of template_setting and append to div_dialogue.
-As you may have multiple templates on the same page( which is not always true).
Apply a custom event on the id of newly created setting div.( keep id of each setting div different, you can increment each one by some character/number).
$('#dialogue_opener').click(function(event){
$('.template_setting').children().clone().appendTo(div_dialogue)
.trigger('adjustSettingID');
Consider a hybrid solution. Load the "settings" div after the page is ready. This way, the user won't feel the extra "expense", and you'll have the div ready for when you need it.
I've typically seen that rendering from JavaScript is pretty darn fast. I've built lots of "just in time" menus, grids, and forms and the users can't tell the difference. The nice thing about it is that you don't have to keep a form current, just blow it away and default everything to the data in you settings object. Makes for cleaner code in my opinion.