JRenderer and JQuery Mobile List View Losing Style - javascript

I'm doing a pretty typical JSON request and populating a JRendere template. It works great, but when I wrap the li in a href it loses all formatting.
HTML Code:
<script id="recipeTemplate" type="text/x-jquery-tmpl">
{{for Content}}
<a href='searchResults.html' data-transition='slide'>
<li class="ui-li ui-li-static ui-body-c" style='height: 150px; border: 0px; margin-left: 20px; margin-right: 20px;'>
<img src="{{:ImageURL}}" style='max-height: 125px; max-width: 125px; position: absolute;'/>
<div style='margin-left: 50px;'>
<h3 style="white-space : normal;">{{:Title}}</h3>
<h3 style="white-space : normal;">Ratings:</h3>
<p style="white-space : normal;">{{:Description}}</p>
</div>
</li>
</a>
{{/for}}
</script>
The JS is as follows:
$("#search").focusout(function()
{
var searchTerm = $("#search").val();
$.getJSON("http://website?searchterm=" + searchTerm + "&callback=?",
function (data)
{
var htmlString = $("#recipeTemplate").render( data );
$('#results').html(htmlString).listview('refresh');
});
});
It looks as above. Why does it lose the CSS?
Thanks, Graeme.

It works great, but when I wrap the li in a href it loses all
formatting.
First of all, having an <li> within an <a> tag is invalid HTML.
Your CSS is most likely relying on a specific order, targeting an element then maybe another element which has to have a specific class inside that element, and so on.
By adding the <a> around the <li> element you have now changed the expected order and you CSS is not able any more to match the selectors.
Placing your <a> tag inside the <li> instead could keep the CSS intact and at the same time be valid HTML, well, assuming you have ul or ol around the set of li's in the final HTML.
Check your CSS and make sure you are not messing with the expected order of nested elements or classes. Then either ass the <a> so it doesn't break the CSS or update the CSS to match your new hierarchy.

Related

Optimize performance of huge content HTML

I have a page, reading a text file and showing it on the site on runtime. I use jQuery to parse the file and append to the page with the following code:
resultArray.forEach(function (val) {
$('#OutputArea').append(appendText(val.content));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<ol id="OutputArea">
<li class="someClass"> some content...</li>
<li class="someClass"> some content...</li>
<li class="someClass"> some content...</li>
<li class="someClass"> some content...</li>
<li class="someClass"> some content...</li>
<!-- New content will add below -->
</ol>
</div>
It was okay when there are only thousands of line, however as more content appended to the page, the site will become less responsive, i.e. Took long time to render and laggy when scroll.
I understand the browser will become slower as the page do take a lot of resources, however is there a way to optimize the performance of it? Thanks.
26/7/2018 Update
I've done a couple things to speed up the process:
1.Make use of DocumentFragment instead of appending html strings like <li class="someClass"> some content...</li>
2.Instead of jQuery forEach loop, the following loop did make things sightly faster
var fragment = document.createDocumentFragment();
for(var i =0 ;i<resultArray.length;i++)
{
var val = resultArray[i];
fragment.appendChild(appendText(val.content, val.id));
}
document.getElementById("LogArea").appendChild(fragment);
Adding will-change:transform; CSS property to the div, the scrolling is MUCH more faster than before.
I also found that removing the counter-increment will make the render a lot faster, almost 70%. I use the following CSS to create my own <li> number style.
My guessing is that the li:before content calculation did a lot of work load to the rendering? I had no idea on how to get over it.
ol {
counter-reset: item;
list-style-type: none;
padding-left: 10px
}
li {
display: -webkit-box;
}
li:before {
content: counter(item) " ";
counter-increment: item ;
color: gray;
display: block;
text-align: right;
font-size:14px;
}
li:last-child:before {
content: "";
}
A few thoughts
Only append once. So build a var of all your list items
var text = '';
resultArray.forEach(function (val) {
text += appendText(val.content);
});
$('#OutputArea').append(text);
Chunk your text file. So the most important file is loaded / parsed first.
Build an API with pagination

Bootstrap: In Navbar, Show Different Content Based on Li Link Hovered in a Single Location?

I've tried a few JQuery and CSS implementations of this, but can't seem to get it quite right. I'm utilizing FontAwesome icons in the navbar for Bootstrap, and I would like to have a single location where, when the icons are hovered, a text description of them is shown/hidden.
This implementation has gotten me the farthest, with the different captions showing up. However, I need them all to appear in one location (preferably to the front of the ul navbar-nav grouping, as they will be right aligned).
CSS:
div#navbar a span {display: none;}
div#navbar a:hover span {display: block; position: absolute; top: 40px; left:-50px; width: 125px; padding: 5px; margin: 10px; z-index: 100;color: #AAA; background: black;font: 10px Verdana, sans-serif; text-align: center;}
HTML:
<ul class="nav navbar-nav">
<li><div class="nav-button"><i class="fa fa-user"></i></div><span>Text Goes Here</span></li>
<li><div class="nav-button"><i class="fa fa-umbrella"></i></div><span>Text Goes Here 2</span></li>
<li><div class="nav-button"><i class="fa fa-star"></i></div><span>Text Goes Here 3</span></li>
</ul>
The implementation above is based off MeyerWeb's CSS Popup Demo
I have tried JQuery Fiddles that worked for simple classes/links such as this: http://jsfiddle.net/AstroCB/42gV5/ , but I'm uncertain if the depth of Bootstrap classes is causing some sort of override, as I cannot seem to get JQuery show/hide functions based on the examples I've seen to work.
I have also tried ~ relations such as: http://jsfiddle.net/YsHA4/ but am again hitting a wall.
It's highly likely I am just approaching this the wrong way, but I've been attempting to solve this problem for a few days now and just can't seem to find a solution. A fresh set of eyes and any and all help would be absolutely appreciated. If there's any way I can clarify, please let me know. Thank you!!
EDITED TO ADD: I do not need the final result to be spans inside the links in any regard, they can be hidden external divs, etc. The example I gave is the farthest I have managed to get the functionality to what I want (separate information showing up for each hover), but if a different approach using JS/etc removes the spans or hard codes the text into a JS string in some way, so be it. I am just looking to get this functionality to work as anticipated with Bootstrap, whatever implementation best gets it there!
Also, see my comment for an image representation of what I am trying to achieve.
I made a Fiddle based on your image.
It uses bootstraps right section for the menu.
I have applied a loop to each link:
$.each($('a'), function() {
$(this).hover(function() {
$('.placeholder').html($(this).html());
});
});
It simply takes the HTML inside a tag and places in the menu item with the class placeholder.
Update:
In your case your links are bit more complex so the selector for the loop would look like this:
$.each($('a > span'), function() {
// do stuff here
});
This fetches all links in your document and then the span element inside that.
Aaand finally a Fiddle for the HTML you have provided here.
Code below edited since loops are unecessary:
$('a').hover(function() {
$('.placeholder').html($(this).html());
});
$('a > span').hover(function() {
// do stuff here
});
HTML
<ul class="nav navbar-nav">
<li class="hover"><div class="nav-button"><i class="fa fa-user"></i><span class="text hidden"> Text Goes Here</span></div>
</li>
<li class="hover"><div class="nav-button"><i class="fa fa-umbrella"></i><span class="text hidden"> Text Goes Here 2</span></div>
</li>
<li class="hover"><i class="fa fa-star"></i> <span class="text hidden">Text Goes Here 2</span>
</li>
</ul>
JS
$(document).ready(function () {
$('.hover').each(function (index, el) {
var thiz = $(this);
var text = thiz.find('.text');
thiz.on('mouseover', function (e) {
text.removeClass('hidden');
});
thiz.on('mouseleave', function(e){
text.addClass('hidden')
});
});
});
jsFiddle

Display title attribute as string in another HTML element

Been trying everything all day to get this to work with no luck.
I want to use the title attribute from an li element as a string inside of a completely separate span element.
Here is my code:
<script type="text/javascript">
$(document).ready(function(){
});
</script>
<div id="slider">
<ul>
<li class="slide" title="Careers">
<img src="large-image-1.jpg" alt="Large Image 1" /> </li>
</ul>
</div>
<div id="slide-thumbs">
<ul>
<li><img src="thumb-image-1.jpg" alt="Thumbnail for Large Image 1" />
<span class="thumb-caption"><!-- need title attribute above reading "Careers" to go here --></span>
</ul>
</div>
I feel like I'm missing something easy here. I can only use Javascript to do this with the script I'm working with. PHP is not an option. Any help would be very much appreciated.
Thank you,
Justin.
var title = $('.slide').attr('title');
$('span').html(title);
The JS should work fine, but something to consider is you could do this with pure CSS and avoid the extra markup. Just display the title attribute using a pseudo-element and position it where you like:
.slide:before {
content: attr(title);
position: absolute;
display: block;
}
Since the title is already displaying on the page and you're not generating anything else in addition to it, no reason for the extra element
If there is more than one slide, better use:
$('.thumb-caption').each(function(i) {
$(this).html($('.slide').eq(i).attr('title'));
});

How to make LI innerText have indentation

Edit: This HTML is output from a Flash application & its badly formed because it contains li elements NOT inside a ul or ol element. Is there a way to get the desired indentation with this HTML(using CSS)? Hopefully I wont have to parse the HTML & insert my ol tags where I need to, hopefully :(
<textformat leading="2">
<li>
<font style=" font-family: 'arial'; font-size: 14px; color: #FFFFFF; letter-spacing: 0px; ">
Remaining optimistic and focused while paying attention to the doubts of others
</font>
</li>
</textformat>
Is there a way to make EVERY line of text inside a HTML li element be indented?
Example of what I am trying to achieve:
This is what currently happens which is what I am trying to avoid:
So I have this html:
<ol>
<li><font>text here <b>some bold</b></font></li>
</ol>
Add a padding and text-indent:
li {
text-indent: -1em;
padding-left: 1em;
}
Try it on JSFiddle.
It displays like that fine in all majors browsers by default. The only way you'll get the wrap around like the second example is if you actually wrote the numbers themselves instead of using:
<ol>
<li>List item 1</li>
<li>List item 2</li>
</ol>
There shouldn't be a problem as long as you use these tags. The only way you should be getting the second image is with the CSS style list-style-position: inside;. Should you have some strange stylesheet interfering with your example, you could add style="list-style-position: outside;" to the <ol> tag to ensure that the numbers are outside of the text.
Oh, gah... post edit:
<li> isn't really gonna work, then. Why not use a div for each one like this: http://jsfiddle.net/aMdm9/

Wrap link <a> around <div>

Is it possible to wrap an <a> tag around <div>s like so:
<a href=etc etc>
<div class="layout">
<div class="title">
Video Type
<div class="description">Video description</div>
</div>
</div>
</a>
Eclipse is telling me the div's are in the wrong place?
If this is not allowed. How can I make the entire 'layout' class become a link?
That structure would be valid in HTML5 since in HTML5 anchors can wrap almost any element except for other anchors and form controls. Most browsers nowadays have support for this and will parse the code in the question as valid HTML. The answer below was written in 2011, and may be useful if you're supporting legacy browsers (*cough* Internet Explorer *cough*).
Older browsers without HTML5 parsers (like, say, Firefox 3.6) will still get confused over that, and possibly mess up the DOM structure.
Three options for HTML4 - use all inline elements:
<a href=etc etc>
<span class="layout">
<span class="title">
Video Type
<span class="description">Video description</span>
</span>
</span>
</a>
Then style with display: block
Use JavaScript and :hover:
<div class="layout">
<div class="title">
Video Type
<div class="description">Video description</div>
</div>
</div>
And (assuming jQuery)
$('.layout').click(function(){
// Do something
}):
And
.layout:hover {
// Hover effect
}
Or lastly use absolute positioning to place an a anchor with CSS to cover the whole of .layout
<div class="layout">
<div class="title">
Video Type
<div class="description">Video description</div>
</div>
<a class="more_link" href="somewhere">More information</a>
</div>
And CSS:
.layout {
position: relative;
}
.layout .more_link {
position: absolute;
display: block;
top: 0;
bottom: 0;
left: 0;
right: 0;
text-indent: -9999px;
z-index: 1000;
}
This won't work with older versions of IE, of course.
While the <a> tag is not allowed to contain <div> element, it is allowed to contain other inline elements such as <span>.
When I encountered the problem i swapped the div tag with a <span>. Since the span tag is an inline element, you need to apply a display:block to the css of your <span> element, in order to make it behave like the <div> block element.
This should be valid xhtml and does not require any javascript.
Here's an example:
<a href="#">
<span style="display:block">
Some content. Maybe some other span elements, or images.
</span>
</a>
Another simple solution - just add an onclick event handler to the div thusly:
<div class="layout" onclick="location.href='somewhere'">
<div class="title">
Video Type
<div class="description">Video description</div>
</div>
</div>
This works great for me but there is one small gotcha. I'm not sure how search engine friendly this is. I fear that google's web crawlers might not find this link so I also tend to include a traditional A HREF link somewhere in the block like this:
<div class="layout" onclick="location.href='destination_url'">
<div class="title">
Video Type
<div class="description">Video description</div>
</div>
This is a link
</div>
Timothy's solution is correct ... instead of wrapping an anchor around a div ... you simply give layout to the anchor element with display:block and add the size and width of the anchor ...
.div_class { width: 100px; height: 100px; }
.div_class a { width: 100px; height: 100px; display: block; }
<div class='div_class'></div>
HTML provides two general elements, where div is a natural block element, and span is a natural inline element. All other elements are similarly assigned to be a natural block or inline.
Now, while both can be made by css display to be any of inline, inline-block or block, they are still treated for enclosure purposes as their natural selves, hence the warning messages. Leopards and spots sort of thing.
However, css is only meant to be for making what an element looks like (presentation), but not actually be like (functionality), so it doesn't change an element's basic nature, though that gets very fuzzy in practice. A span made block becomes a bully that kicks everything else off the line, which is very un-inline sort of behaviour.
So, to mitigate against possible conflicts between their natural and css-induced behaviours, it is better to allow:
div or any natural block tag to only ever be block or inline-block.
span or any natural inline tag to only ever be inline or inline-block.
This will also mitigate against tending to build page structures that will likely end up churning out error and warning messages.
Basically, NEVER embed a natural block tag inside a natural inline tag, at any depth.
Why there is a really a distinction is perhaps due to a simplistic idea of what HTML was going to be used for when it was first dreamed up.
Certainly, framework makers got around a lot of these what-to-embed-where problems by just using myriads of divs everywhere, and 'divitis' was born, and still alive and well in every framework. Just have to press F12 in a browser on almost any commercial web page and drill down through a dozen divs. This very page has 15 unbroken levels of divs.
It is not hard to see why just settling on divs made sense. For example, a p tag may have a bunch of links to various sites, and that is ok because inline links are allowed in a block p. However, if not wanting to have query variables visible in those urls, then buttons are required. If only one, then the p can be put inside a form, as a p cannot contain a form.
The formaction attribute on a button can be used to target a url other than the form default, but it still does not allow independent forms, each with their own set of hidden inputs. A button can use the form attribute to use it with a form that isn't an ancestor, but it can get messy to keep track of.
For multiple links to different sites to appear as part of one paragraph though, the only way is to use a div instead of the p and then wrap each button in its own form set to inline. Most frameworks have to cope with so much more complex scenarios that nested divs are the only way to go.
It meant that they really only had to manage one tag per purpose and manage it as if it was an isolated environment. So what was meant to be an occasionally-used functional grouping tag became the web's Lego block. And none of them are going to risk breaking their frameworks by converting to HTML5 semantic tags in a hurry. In the end, semantic tags only really work for fairly static content rather than rich interactive sites.
I had tried to create custom solution using jQuery, which would imitate same behavior as a tag does, for parent DIV.
DEMO:
https://jsfiddle.net/kutec/m9vxhcke/
As per W3C standard, you cannot do this:
<div class="boxes">
<a href="http://link1.com" target="_blank">
<div class="box">
<h3>Link with _blank attr</h3>
</div>
</a>
</div>
You must follow this:
<div class="boxes">
<div class="box">
<h3>
Link with _blank attr
</h3>
</div>
</div>
But by following above code, you wouldn't get the whole DIV clickable :).
Correct structure should be something like this, which also allows you to click over the DIV to redirect on the given href value:
<div class="boxes" data-href="http://link1.com" data-target="_blank">
<div class="box">
<h3>
Link with _blank attr
</h3>
</div>
</div>
Simple Solution:
$(function() {
$('.boxes a').each(function(){
var aTag = $(this).attr('href');
$(this).parent().attr('data-href',aTag);
$("[data-href]").click(function() {
window.location.href = $(this).attr("data-href");
return false;
});
})
}(jQuery));
Dynamic Solution:
(function ( $ ) {
$.fn.dataURL = function() {
// variables
var el = $(this);
var aTag = el.find('a');
var aHref;
var aTarget;
// get & set attributes
aTag.each(function() {
var aHref = $(this).attr('href');
$(this).parent().attr('data-href',this);
aTarget = $(this).attr('target');
$(this).parent().attr('data-target',aTarget);
});
// imitation - default attributes' behavior on "data-" attributes
$(el).delegate('[data-href]','click', function() {
var loc = window.location.href;
loc = $(this).attr("data-href");
aTarget = $(this).attr('data-target');
if(aTarget == "_blank"){
window.open(loc);
} else {
window.location = loc;
}
return false;
});
//removing attributes from selector itself
el.removeAttr('data-href');
el.removeAttr('data-target');
// css
$('[data-href]').css('cursor','pointer');
};
}( jQuery ));
Final call:
<script>
$('.boxes').dataURL();
</script>
Hope this would be helpful :)
You would just want to style the "a" tag as display: block;
Eclipse is appropriately telling you that your HTML is not to spec (as a div tag is not allowed in an anchor tag).
But, since you seem to want to be visually making the anchor look like a big-ol-box, then simply style it as such :)
One easy way to make the div a link/clickable is by using html javascript onclick attribute:
<div class="clickable-div" onclick="location.href='#';"><div> ... </div></div>

Categories