$.get( load_this, function( page ) {
$article = $( page ).find( ".js-Article--current" );
console.log( $(page) );
$article.removeClass( "js-Article--current" ).addClass( "Article--contentHidden" )
.children( ".js-ArticleHeader" ) .addClass( "ArticleHeader--teaser" )
.find( ".next-teaserFade" ) .addClass( "ArticleHeader-teaserFade" )
.end()
.find( ".next-teaserSqueeze" ) .addClass( "ArticleHeader-teaserSqueeze" );
$( ".js-Article--current" ).after( $article );
});
get returns whole page.
Now problem I've encountered is this:
if js-Article--current is not top level element find finds it.
if js-Article--current is top level element find cannot find it.
Why?
p.s. I know solution: filter instead of find. But why is find behaving like this? I don't get it.
find() will try to find a child element of the selector. So, if .js-Article--current is the selector, it will not find it.
filter(), instead, filters through the selectors
Check the console:
var findTest = $('div').find('#test').length;
var filterTest = $('div').filter('#test').length;
console.log('find test: ' + findTest);
console.log('filter test: ' + filterTest);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="test"></div>
<div id="anotherTest"></div>
Related
I am trying to retrieve data from a variable HTML element. On click, the id of the <span> element is retrieved, which I want to enable me to dynamically $([dynamic id]) select that element and request the data stored in the data attribute.
My jQuery looks like this:
$( document ).ready( function() {
$( ".checkmark" ).on( "click", ( event ) => {
let checkBoxId = "#" + event.target.id, // #checkBox1
checkBoxData = event.target.id + "-value", // checkBox1-value
checkBoxValue = $( checkBoxId ).data( checkBoxData ); // undefined
} );
} );
The HTML element targeted looks like this:
<span class="checkmark" id="checkBox1" data-checkBox1-value=-155></span>
The value of let checkBoxValue is undefined and I cannot figure out why.
Help would be greatly appreciated.
You can get attribute value of span using attr() function in jQuery
checkBoxValue = $(checkBoxId).attr(checkBoxData);
The checkBoxId variable is unnecessary because you can use the this keyword since it is the current element you are working with.
$(function() {
$(".checkmark").on("click", (event) => {
let checkBoxData = event.target.id + "-value";
let checkBoxValue = $(this).data(checkBoxData);
});
});
It seems you are having scope issues with the new ()=>{} syntax.
So, you will need to bind this to the function event handler using {self:this}. If you don't want to do this, you can use the old function(){} syntax instead.
$( document ).ready( function() {
$( ".checkmark" ).on( "click", {self:this}, ( event ) => {
var checkBoxValue = $(this).data("checkbox1-value")
alert(checkBoxValue);
} );
} );
And also as #Erwin mentioned, use only lowercase in your data- attribute name:
<span class="checkmark" id="checkbox1" data-checkbox1-value="-155"></span>
JsFiddle
It's returning undefined because it is declared incorrectly. The part after data- should be in lower case. In your case, it must be
<span class="checkmark" id="checkbox1" data-checkbox1-value=-155></span>
for the .data() to work.
this code works for me try it ;)
$( document ).ready( function() {
$( ".checkmark" ).on( "click", function() {
var checkBoxId = "#" + $(this).attr('id');
var checkBoxData = $(this).attr('id') + "-value";
$( this ).attr('data-'+ checkBoxData, 155 );
} );
});
jsfiddle link
I have the following code which loads jQuery into the page dynamically after page load and then attempts to run some jQuery of its own afterwards. The first console log of the page title works. The issue comes when it cant find the class "special-div" later on in the page and replace it with the appropriate text. Any thoughts?
//Load jQuery library using plain JavaScript
(function(){
var newscript = document.createElement('script');
newscript.type = 'text/javascript';
newscript.src = 'https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js';
document.getElementsByTagName('head')[0].appendChild(newscript);
// Poll for jQuery to come into existance
var checkReady = function(callback) {
if (window.jQuery) {
callback(jQuery);
}
else {
window.setTimeout(function() { checkReady(callback); }, 100);
}
};
// Start polling...
checkReady(function($) {
console.log( 'jQuery is loaded on: ' + $('title').text() );
$( '.special-div' ).each(function( index ) {
console.log( index + ": " + $( this ).text() );
$( this ).replaceWith( "Say something here " + $( this ).attr( "id" ) + ' ' + $( this ).attr( "title" ) );
});
});
})();
The HTML looks like this:
<div id="something" class="special-div" title="else"> </div>
The wacky CMS that I am working on only allows for me to paste in one external javascript file so i have to load in jQuery and all other scripts i need through that one file.
Edit:
so i ran a few additional tests and tried this:
console.log( 'jQuery is loaded on: ' + $( '.special-div' ).attr( "id" ) );
the response i am getting is:
jQuery is loaded on: undefined
If you want to return content of div in second console.log, use $( this ).html() instead of $( this ).text()
If you want to replace text for each $( '.special-div' ) with the content of their attributes, you have to do:
$( this ).replaceWith( "Say something here " + $( this ).attr( "id" ) + ' ' + $( this ).attr( "title" ) );
instead of
$( '.special-div' ).replaceWith( "Say something here " + $( this ).attr( "id" ) + ' ' + $( this ).attr( "title" ) );
otherwise you get the same replacement for all occurrences.
I tried it and it works.
But if you are putting it in <head> and another jQuery is loaded before it, DOM searching will run before the DOM getting ready so that it can not find the DOM.
(case of no window.setTimeout(function() { checkReady(callback); }, 100);)
(another CMS plugin might load jQuery)
So it could be better to run the script on kind of window.onload timings.
Or putting it on the end of <body> may also work.
$( "#target" ).scroll(function() {
if ( !($('#log')) ) {
$( "#log" ).append( "<div>Handler for .scroll() called.</div>" );
};
});
I want to append #log to the body if there isn't already a #log div, but if there is do nothing. How do I do this, my code doesn't work.
You use $('#log').length to see how many objects are found.
In your case it might be
if (!$('#log').length) {
// ...
}
Your solution does not work because !$('#log') expression is always false, because any object in JS (and $() function always returns an object, even if nothing was found) is always truthy.
$( "#log" ).append( "<div>Handler for .scroll() called.</div>" );
Instead of that try using this :
$("#log").appendTo('body');
I'm using the 'nested-list' plugin for jQuery Mobile, this one:
The problem is that when you use more than one level the plugins fails going back. For example, in the fiddle I have created I can go to 'Test 1.2.1' without problem, If I going back 1 level it works fine and I go to 'Test 1.2', but then if I tried to go up one level more (it was 'Test1') it goes up 2 levels (to 'Test').
I have checked the plugin code but I can't find the problem and I have left a message in the Git forum with no answer. Maybe someone could help me here.
Thanks in advance!
Fiddle
Looking at the plugin code, it is only designed for one level deep nesting. This is because the developer chose to remove created subpages each time you click on a parent LI. So when you get to the second level of depth, its parent has been removed from the DOM and you have to click the back button twice to get to the original page.
I have made some changes to the plugin code that should solve this problem:
In _attachBindings, I have commented out the line that removes previously created subpages:
_attachBindings: function() {
this._on({
"click": "_handleSubpageClick"
});
this._on( "body", {
"pagechange": function(){
if ( this.opening === true ) {
this.open = true;
this.opening = false;
} else if ( this.open === true ) {
//Don't remove the old LI
//this.newPage.remove();
this.open = false;
}
}
});
},...
Then in _handleSubpageClick, I check if the subpage already exists in the DOM (via data attribute added when creating the page). If not, we go through the existing code that creates the subpage, and then in the end I store the created subpage id in a data attribute on the parent LI. If it does exist we just navigate to that page.
_handleSubpageClick: function( event ) {
if( $(event.target).closest( "li" ).children( "ul" ).length == 0 ) {
return;
}
this.opening = true;
//see if we already created the subpage
var $li = $(event.target).closest( "li" );
var pid = $li.data("nextpageid");
if (pid && pid.length > 0){
this.pageID = pid;
} else {
this.newPage = $( this.options.page ).uniqueId();
this.nestedList = $( event.target ).children( "ul" )
.clone().attr( "data-" + $.mobile.ns + "role", "listview" )
.css( "display", "block" );
this.pageName = (
$( event.target.childNodes[0] ).text().replace(/^\s+|\s+$/g, '').length > 0 )?
$( event.target.childNodes[0] ).text() : $( event.target.childNodes[1] ).text();
this.pageID = this.newPage.attr( "id" );
// Build new page
this.newPage.append(
$( this.options.header ).find( "h1" ).text( this.pageName ).end()
).append(
$( this.options.content )
).find( "div.ui-content" ).append( this.nestedList );
$( "body" ).append( this.newPage );
//save subpage id as data attribute of the LI
$li.data("nextpageid", this.pageID);
}
$( "body" ).pagecontainer( "change", "#" + this.pageID );
}...
Here is your updated FIDDLE
I removed the external link to the plugin and instead copied all the code into the javascript pane and made the edits. You should be able to copy that code directly and use as the updated plugin. (Of course I did this quickly and have not rigorously tested it, so make sure it works for you).
I have a problem in jQuery, it is that I have an array to append to an object (id) This function also after intends such as.
When I now use a "each" function in jQuery do I do it this way.
$.each(childrenObj, function(index, value)
{
$( document.createElement('ol') )
.append(
$( document.createElement('li') )
.attr('id', 'list_'+ listItem )
.append(
$( document.createElement('div') )
.addClass('listContentItem')
.html( value.contentTitle )
)
)
.appendTo('#list_'+ ( listItem - 1 ) );
listItem++;
});
As you would imagine, it will make a <ol><li>test</li></ol> where after doing the same thing over and over again depending on how many people run through.
That I would like is that I would like it to make a <ol> in an object after which I in my each loop adds <li> to it and eventually make a appendTo ('# id') after my desire but could not quite get it resolved and it causes some problems pure design front.
Hope there are some who sits with a solution and can help me a little on the road.
Create the ol outside your loop (below code is untested, but should hopefully work)
var ol = $( document.createElement('ol') );
$.each(childrenObj, function(index, value)
{
ol.append(
$( document.createElement('li') )
.append(
$( document.createElement('div') )
.addClass('listContentItem')
.html( value.contentTitle )
)
);
});
ol.appendTo('#some_id');