Intercept append method on dom - javascript

i need a way to parsing the dynamic content of webpage.
For example if I need to append a class for every element with a class "test" i can do like that :
$(".test").each(function(index, element)
{
if(!$(this).data("parsed"))
{
$(this).data("parsed", true);
//all my operation - Example :
$(this).addClass("new-class");
}
});
That work, but only for the html at this time.
If on second time I append new html to my page, that will not parsed by my script.
I would a way for do that.
There is a method called when the content change? For example on every append, html, ajax request etc?

That could be one own solution :
var original_append = $.fn.append;
$.fn.append = function()
{
console.log(arguments);
//my code
return original_append.apply(this, arguments);
}

Related

Add class to body when url changes using Jquery?

I'm using a plugin in ajax that filter some products of my site.
The url changes without reload the page.
I need indentify the url, split the words and add those class to body.
E.G: I filter some products, then my url changes to https://website.com/size=big/color=yellow,green,dark-red
So, this classes would be added to body: size big color yellow green dark-red
I have this code but I don't know how to make it work.
$(window).on('hashchange', function(e){
$('body').
});
Thanks.
UPDATE: Based on the comment thread in my answer it seems that you're really trying to convert the querystring values to css class names.
You can use the window.location.search to access all the querystring parameters.
function updateBodyClasses() {
var classNames = [];
// Use `.split()` to separate each key/value pair in the query by `&`
window.location.search.split('&')
// and loop over the results
.forEach(function(c) {
// Now split each pair by '='
var pair = c.split['='];
// Add the value to the left of the '='
if (pair.length > 0) {
classNames.push(pair[0]);
// if there are values on the right of the '='...
if (pair.length > 1) {
// ... split them by ',' and loop through them
pair[1].split(',').forEach(function(t) {
classNames.push(t);
});
}
}
});
// Now append those classNames to the body
$('body').addClass(classNames.join(' '));
}
// If your ajax plugin modifies the url via HTML5 history api...
$(window).on('popstate', updateBodyClasses);
// Update classes on page load
$(window).on('load', updateBodyClasses);
// If the ajax plugin modifies the url using window.location.replace()
// you'll need to check on an interval whether things have changed
// and update accordingly. the following example does this every 1000 milliseconds (or every second)
setInterval(updateBodyClasses, 1000);

Is there a DOM rendered callback for Knockout.js without templates?

I do something like this :
var profileViewModel = new KoProfile(config.data);
ko.applyBindings(profileViewModel , $('#myDiv')[0]);
injectSomeDynamicElements();
#myDiv contains some elements that I want to push content into after the model is bound.
When applying the new profile Knockout re-renders the html that the model is bound too.
My problem is that when I try to inject the new elements, the DOM has not been updated. I end up injecting images into a div that is about to be cleared by knockout.js
Is there a callback function for DOM update completed without using a template ?
What I doing in this cases is this:
OnElementUpdate(element, callback){
var timer = setInterval(function(){
if(!$(element).is(':empty')) {
clear(timer);
callback();
}
}, 100);
}
OnElementUpdate("#myDiv", function(){
//do whatever you want
}

Find and manipulate a HTML DIV element that is stored in a variable, using jQuery

I've been searching for a few hours to try and find a solution to my issue, for some reason partially similar answers on here don't seem to be working for me - so I'm creating my own question.
Basically, I'm loading pre-rendered HTML from the server using jQuery's $.get method, and I need to split the HTML returned into two sections (one that's wrapped in a div called #section-one and the other simply alongside that div, with no parent element).
See the example below:
$.get('http://jamie.st/remote_file.php', function(data){
// I want to get '#section-one' and then remove it from data, basically splitting a single returned HTML resource into two, that can be placed in two different areas of the page.
var sectionOne = $(data).find('#section-one');
// This should only return the HTML of '#section-one'
console.log(sectionOne);
// Also how can I then remove '#section-one' from the 'data' variable? The equivalent of calling the below, but from the 'data' variables string/html.
$(sectionOne).remove();
// So eventually the below would return the HTML without the '#section-one' element (and it's children)
console.log(data);
});
I've also created a jsfiddle which you can play around with if you need to, it's set up to use a real PHP file that I've hosted for demo purposes.
http://jsfiddle.net/6p0spp23/6/
If you can submit a jsfiddle link back that would be much appreciated, thanks in advance guys!
When you create a jQuery object with the remote contents $(data) becomes a collection of elements so instead of find() you want to use filter() like so:
$.get('http://jamie.st/remote_file.php', function(data){
var $data = $(data),
$sectionOne = $data.filter('#section-one'),
$rest = $data.filter(':not(#section-one)');
console.log($sectionOne);
console.log($rest);
});
Demo fiddle
I think the best way to put the received data inside a parent div. Then you can call remove or any other method to use it.
You can make parent div hidden using .hide() method if you don't want to show it.
Here I did it:
http://plnkr.co/edit/jQKXyles8sP8dliB7v0K?p=preview
// Add your javascript here
$(function() {
$.get('http://jamie.st/remote_file.php', function(data) {
$("#parent").hide();
$("#parent").html(data);
$("#section-one").remove();
console.log($("#section-one").html())
alert($("#parent").html())
});
});
When you remove a subsection from a derived jQuery object, the original string is not updated with the change so if you want the updated html content you need to generate it from the jQuery object. One way to do this is to
$.get('http://jamie.st/remote_file.php', function (data) {
var $ct = $('<div />', {
html: data
});
// I want to get '#section-one' and then remove it from data, basically splitting a single returned HTML resource into two, that can be placed in two different areas of the page.
var sectionOne = $ct.find('#section-one');
// This should only return the HTML of '#section-one'
console.log(sectionOne);
// Also how can I then remove '#section-one' from the 'data' variable? The equivilant of calling the below, but from the 'data' variables string/html.
$(sectionOne).remove();
// So eventually the below would return the HTML without the '#section-one' element (and it's children)
console.log($ct.html());
});
Demo: Fiddle

jquery extension return $.each confusion

I am trying to use a jQuery extension I came across (handsontable). I am having no problem creating the table
var spreadsheet = $("#dataTable").handsontable({
rows: 3,
cols: 15,
minSpareRows: 2
});
However after I create the table I want to call various helper functions I see declared in the javascript for the Handsontable object. The problem is the extension seems to return this.each(function() { ... }); and I don't understand how I can access the underlaying Handsontable object from this. The js for the extension can be found here and I put a small demo together on the following link
http://jsfiddle.net/7JTG2/7/
as you can see I would like get the data of one of the cells when I click a button.
The relevant code is in the end:
$.fn.handsontable = function (action, options) {
if (typeof action !== 'string') { //init
options = action;
return this.each(function () {
if($(this).data("handsontable")) {
instance = $(this).data("handsontable");
...
} else {
...
instance = new Handsontable($(this), currentSettings);
$(this).data("handsontable", instance);
}
});
}
}
That means, the code sets the Handsontable instances as a data attribute to the elements (and returns the selected set to be chainable). Having one element, you can easily extract it with instance = $el.data("handsontable"). If you have a set of elements, you will need to loop over it - e.g. with each().
Looks like you could just use the onChange method of the plugin to capture data every time it is entered automatically. No need for a button. A simple example to add to your code above.
onChange: function(data) {
$("#data").append(JSON.stringify(data));
}

Prototype Event.observe not seeing AJAX-returned HTML

I'm trying to create a CMS system based on AJAX using Prototype's library. On a page load, I have HTML, page title and additional Javascript for the page returned via JSON, and I update the HTML on the main area. I also have an event listener that listens for certain ID's to be clicked on.
The listener is working,
var TabMenu = {
selectedTab: 'main',
showTab: function(pid) { alert(pid); alert($(pid));
$(pid).addClassName('selected'); this.selectedTab = pid;
$(this.defaultTab).removeClassName('selected');
}};
After loading, I click on one of the new tabs, and the first "test" alert successfully alerts the element's ID, but the second alert ($(pid)) returns null. I can only surmise that the HTML returned by the AJAX request is not being evaluated and added to the DOM, otherwise it would alert [HTMLDivElement] instead of "null".
Here is the relevant AJAX call:
new Ajax.Request(url, {
onSuccess: function(t) {
data = t.responseText.evalJSON();
Page.update(data.html, data.title, data.js);
Page.destroyLoader();
}
});
And here is the updating function:
update: function(data, title, js) {
document.title = Global.title + title;
if (title != "") { $('HEADING').update(title); }
$('MAIN').update(data);
if (js != "") {
var nuJS = new Element('script', { type: 'text/javascript' }).update(js);
$('MAIN').insert({ top: nuJS });
}
}
Any ideas on how I can get this working?
When is the ajax request triggered? Is it triggered when you click the tab? If so the showTab function is being triggered before data has been inserted into the DOM.
If you have firebug, try using the console to select the html data, after the ajax call has finished, to see what you get. You can also use firebug's html tab to see if the data has been inserted into the DOM.
Also, even though you get the pid parameter that is set to a value, does it refer to a real id that exists in the DOM?
From your code and the comment above.
I think your plan is to load all the tabs after the page loaded immediately.
And hide all of them using the css. Wait until the user click the tab,
Show only the one that is "selected", right?
That's mean you should change:
$('MAIN').update(data);
To something like
$('MAIN').update({after: data});
So it won't overwrite the existed one.
And don't forget to move the code for document.title and eval js into showTab function.
For javascript evaluation you can insert the js into data.html and use this instead:
$('MAIN').innerHTML.evalScripts();

Categories