I have a few javascript functions that changes DOM elements, such as add classes, replace images, etc...
Now, sometimes a page will create a popup or will populate a navigation tree with some extra items without loading a new page. In that case the new element loaded will of course not be affected by my javascript.
For example. Say I give all images an extra class via javascript. Now the page generates a popup with some images in it, and then those images won't be affected by my javascript and the images in the popup won't get said class.
I was wondering if there is a way to make javascript behave like CSS - to be persistent or to work all the time, so that those new images will also be targeted by my scripts?
I hope that id clear :)
Thanks!
EDIT:
I will provide a bit more information here:
Say I have a simeple function like this:
$('.somediv').addClass( '.anotherclass' );
now this function is executed after the page loads.
Is there a way where I can automatically run this function again, when it is detected that a new div of class .somediv has been added to the DOM?
Whenever the new elements are dynamically added to the page you could call a javascript function that resets all the necessary classes and event bindings. Otherwise, if you know on the server-side what classes are necessary for these items you could send them over with the class already assigned to it.
Related
I'm trying to get some data from a webpage:
https://www.cabotcorp.com/solutions#product-index
On this webpage, whenever you scroll down to the end, it takes a couple of seconds and then loads a new set of items.
When that happens something gets added to the HTML which I want to look at with selenium in python.
So my question is pretty general:
Is there a way to force the function that loads the new elements?
My first idea is as follows:
driver.execute_script("arguments[0].scrollIntoView();", driver.find_element(By.CLASS_NAME, "some class at the bottom of the page"))
This is the code I would use to let selenium scroll down to some element on the webpage. After that I would just sleep for a set amount of time to assure that the new elements loaded in.
However, I noticed that this webpage uses "ddscrollspy"
https://github.com/dynamicdriverepo/ddscrollspy
Is there a way to use selenium to trigger a new set of items?
I'm basically looking for a function that triggers certain Javascripts that are available on a certain webpage.
Edit:
A friend suggested looking for triggers:
This is what I found in Chrome:
So I now have access to the code that gets executed whenever something new loads. Now I just need to know how to trigger that code on demand.
Thanks for the help.
I am new to stack overflow and this is my first question. Pardon me for any mistakes.
This question is more generic but i tried to search for an answer but could not find it.
Say i have a page and i am using jquery ui button() widget for all the button. What happens is i have a specific class defined for all the buttons on my page. So i can just specify $('.myButtonClass').button(); but whenever i render partial views which has button again i have to do the same thing in the partial views. Is there any way i can globally specify a transition for button or any element for that matter.
Here is a sample Fiddle which adds buttons on click. But the added buttons are not transitions as button widgets(I do not want to use clone).
http://jsfiddle.net/wjxn8/
$('.clsTest').button().click(function(){
$(this).after('<input type="button" value="Added" class="clsTest"/>');
});
Is this possible without:-
1) Adding the css classes for a button widget manually for all the buttons created.
2) Tracking DOM Changes using Javascript and perform transitions for all the button elements.
Thanks for your help!!!
Since you were looking for something else, why not trigger a custom event when you load partials or whatever:
$('.clsTest').button().click(function(){
$(this).after('<input type="button" value="Added" class="clsTest"/>').trigger('addButtonUI');
});
$(document).bind('addButtonUI',function(){
$('.clsTest').button();
});
http://jsfiddle.net/wJXN8/3/
If you trigger your event and have the document listening for it, then you can do whatever you would like. I could have put in there the ability to add more buttons as well, but this should get the point across.
What you are asking for, some event when a button is added.... you would need to come up with that yourself and trigger it when a button is added. There is this: How to detect new element creation in jQuery? which talks about a specific event that is triggered when new elements are added to the DOM. Haven't tested it, and it looks like it may not work on IE.
I'm not a huge fan of this, but you could poll for new buttons. Check out my fork of your fiddle (that sounds funny):
http://jsfiddle.net/lbstr/Hq97H/
Using your example, this would look like:
setInterval(function(){
$('.clsTest').not('.ui-button').button();
}, 1000);
As I said, I'm not a huge fan of this. I understand the desire for something like $.live here, but I still think its better to initialize your new content when you add it. If you are making an ajax call for new content, just initialize it when you add it to the DOM.
My silly polling code and $.live (which is now deprecated) might be convenient, but they perform terribly. Just my two cents. You know your code better than I do!
I am preparing to implement a Twitter-like infinite scrolling to my product pages. That is, loading additional page portions using AJAX when I am crossing certain scroll thresholds. But I am unsure how the topics in the title are affected after such loading. My questions are the following:
For each new batch of elements being loaded with AJAX, will the DOM be updated for these new elements OR totally renewed? What happens with the old DOM?
Will I be able to use Javascript and jQuery on these new DOM elements exactly like I have on the DOM I start off with for the page? I guess this relates to the first question.
For each load, I will load say 9 new products. Each product has a FB Like button which is utilising FB Open Graph API. Will the new products Like elements go through the same asynchronous modification which happens to the DOM elements I start off with so that a proper Like submission is possible?
Let's begin one by one.
The DOM, in your intent, should only be updated, not renewed. There
is no old DOM since what you do is to insert new elements on them.
Yes, you'll be able to do that. Be careful though with event
listeners because if you start them wrong, you'll have to attach new
event listener to those new nodes again. For example:
$('body').on('click','a.addToCart',function(){}) // Will match present and future nodes
$('a.addToCart').on('click',function(){}); // Will only match present nodes
Yes, you'll need to do the same process for each button again.
Bonus tip: If you care about mobile environments, you should keep your DOM as clean as you can by deleting nodes you won't need.
Just use document.appendChild() for adding new Elements to the DOM. (http://www.w3schools.com/jsref/met_node_appendchild.asp)
Rebuilding the hole page would be a waste of time ;)
There should be no problem. I've done it many times without any problems. If you are using jQuery Mobile you have to refresh the new elements maybe. (Look at the methods of die jQuery Mobile Widget you are using, if it needs refreshing)
I don't have much experience with the facebook api, but i would say "yes" =)
edit: I had a link to a german site in my answer. I've forgot that this is an english site ;)
As many developers will be I'm producing web based application that are using AJAX to retrieve data and HTML.
I'm new to web development and javascript but have a couple of decades experience in programming in other languages.
I'm using mootools, which is a great framework, but have been battleing with the lack of destructors in javascript or even onDestroys/ unloads for the dom elements.
I've written a number of UI classes ( mostly to learn ) and alot of them use setInterval timers to periodically get data from the WebServer and update elements on the page (mostly images from cameras).
Most issue occur when another page is requested with the menu and the content div is reloaded with new HTML and Javascript ( using Request.HTML ). This simple replaces all the elements already in the div with the new one and runs the new scripts. Any timers in the old scripts or old objects created will continue to run. This was leaving me with lots of orphaned Clases, elements and timers.
I've been reading more on the mootools site and have realized a number of mistakes I've been making and have started to correct alot of the issues. The biggest of which was not using Element.store and Element.retrieve instead of linking my classes directly to the Elements.
I've already found that the contents of the div being reloaded need to be freed by calling destroy on all its child elements before calling the Request.HTML but that will not remove (clear) any timers that are running.
So I've done a JSFiddle here deinitialize classes to show what i've been trying, its appears to work fine but the following and what i want to know is,
Is it a good idea?
are there any other issues I might have missed?
can you see any problem with this type of implementation ?
or am I reinventing the wheel and missed
something?
Explanation
When the class is initialized it stores itself with the element.
It also appendes (makes if necessary) itself into an AssocClasses array also stored with the element.
I've created a ClearElement function that is called whenever the contents of an element are to be replace with and AJAX call or other method, which gets all elements within the div and if they have and AssocClasses array attached, calls the deinitialize on each of the Classes in the array, then it calls destroy on each of its direct children to free the elements/storage.
Any information, pointers etc would be most greatfully recieved.
Most issue occur when another page is requested with the menu and the content div is reloaded with new HTML and Javascript ( using Request.HTML ). This simple replaces all the elements already in the div with the new one and runs the new scripts. Any timers in the old scripts or old objects created will continue to run. This was leaving me with lots of orphaned Clases, elements and timers.
I would rethink your timer storage and use of evalScripts in your ajax calls.
Keep these outside of your AJAX requests. When doing peer code reviews rarely have I seen an instance where these were needed and could be done in a better way.
Maybe on the link that is clicked have it trigger a callback function on Complete or onSuccess
Without seeing your exact code it will be hard to advise further.
I have a list of items for which I want to show a couple of items, then a "more" button. I would like the more button to show the new items in a popup box. There are many ways to make this work, but I'm trying to figure out what is the best practice.
Here is my approach. We use MooTools and Clientcide on our site:
Directly following the "more" button, I include a div that contains the content I want to put in the popup (the full list, including a duplication of those items that are visible by default), with a class that includes the style "display:none".
I attach an event to the more button that runs a script called "popupNext". popupNext takes the next element after the button (using getNext from mootools), and creates a new StickyWin (via Clientcide and stickywin.ui) with that element as its content. Then (and this is the part that feels especially hacky) it removes the class that includes the "display:none" style from the content element.
Finally, I use element.store() (from mooTools) to store the StickyWin (with the key "win") in the event element. I neglected to mention above: when popupNext runs, it first checks via element.retrieve() whether there is an existing StickyWin, and shows it, if there is.
This all seems OK, I guess--the biggest disadvantage is page bloat--while I'm showing only first couple of elements of each list, there may be more that are loaded with each page but never seen. But I'm curious whether there is some better, standard way of doing this. For example, I could reduce bloat by retrieving the elements via ajax, at the expense of slower response when a user wants to see the full list.
Check out StickyWin.Ajax - it seems to be closer to what you need than the plain StickyWin.