How to target / apply styles to an image loaded from Javascript - javascript

I installed a SSL trust logo onto my website – the following code is what displays the logo:
<script language="JavaScript" type="text/javascript">
TrustLogo("https://www.(mywebsite).com/comodo_secure_seal_76x26_transp.png", "CL1", "none");
</script>
I needed it to be fixed on the bottom left corner of my page, so after a lot of trial and error I settled with the following code:
img:not(main img) {
position: fixed;
bottom: 0;
left: 0;
The problem is, this isn't really targeting the specific image that needs to be targeted. The bigger problem is that this does not work on any other browser other than the browser I had originally tested (Safari). (Maybe it's because the 'img' tag is not appropriate targeting?)
How can I target this logo? (If not through CSS, how can I make it fixed?)
Safari (the CSS works here)=>
Chrome (CSS does nothing)=>

This worked for me:
Do not use img to target the logo – use one of the image's attrributes to be as specific as possible.
Try something as simple as the src attribute:
[src="https://www.(mywebsite).com/comodo_secure_seal_76x26_transp.png"]
You can also use a node inspector to view more useful information to help you pinpoint the image.

Related

Watir::Browser#execute_script and "Element no longer valid"

I'm writing some automation for a website of ours in Internet Explorer (it has to be IE :< ) and I ran into some issues with execute_script. I need to move a vertical splitbar over 200px so it doesn't move certain elements off the page, making them unclickable. To do this I figured I would use the Watir::Browser#execute_script functionality. The idea would be to change the style tag to the correct coordinates. Unfortunately I haven't been able to get it to work due to "Element is no longer valid" errors. Here are the two cases I tried and their respective errors.
First, I tried just getting the style attribute (the one I need to change) via a javascript script.
script = <<-JS
return arguments[0].style
JS
browser.execute_script(script, aw.watir.div(class: 'x-vsplitbar'))
This gives me Uncaught exception: Element is no longer valid
I also tried changing the element's tag as well.
element = aw.watir.div(class: 'x-vsplitbar')
style = element.style.gsub('200', '400')
script = "return arguments[0].style = '#{style}'"
browser.execute_script(script, element)
This just gave me a sweet error JavaScript error (Selenium::WebDriver::Error::JavascriptError)
The script in this example comes out to:
return arguments[0].style = 'HEIGHT: 897px; WIDTH: 5px; POSITION: absolute; LEFT: 400px; TOP: 50px'
Not sure what I'm doing wrong here, I followed this guide.
Another solution would be to use Watir to simulate the dragging action needed but I couldn't figure out how to drag the bar to the right.

Can't fix the width of popup element (colorbox jquery override)

I have the following code on my site that's supposed to show a popup window
<span class="fbridge-signup-form" data-widget-id="21378"></span>
<script type="text/javascript">
(function() {
var secure = ("https:" == document.location.protocol);
var fb_js_host = (secure ? "https://www.fanbridge.com" : "http://widget-platform.fanbridge.com");
window._FBRIDGE_WIDGETS_HOST = fb_js_host; var p, s, id = 'fbridge-widgetjssdk-v1';
p = document.createElement('script'); p.id = id; p.type = 'text/javascript'; p.async = true;
p.src = (secure ? "https://ssl.fbridgecdn.net" : "http://static.fbridgecdn.net") + '/js/fb/widget/v1/platform.js?_=' + ((new Date()).getTime());
s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(p, s);
})();
</script>
It works fine, but the problem is that there's some setting with lightboxes on my Drupal site that makes this window of a smaller width and height than the actual content inside.
I tried getting the element with getElementByClassName or writing the width and heightparameters into the style property of fbridge-signup-form but it didn't work out.
Do you know what I could do to force it to be a certain width and height? Say 480px by 400px?
You can check the actual page on http://waytorussia.net/Moscow/Intro.html (it has a cookie set to show only once).
UPDATE: maybe it's possible to use another kind of popup so this one is not overridden by my other settings?
According to the HTML source, the element you should resize is (id) cboxContent.
But the black frame around it doesn't seem "ready" (from an HTML/Css point of view) to be resized.
See the screenshot here:
I resized it 400x400.
EDIT -
By resizing all the appropriate elements, you can manage to get what you want. Here's an example done manually:
Just inspect the element (right-click > Inspect) with a modern browser, and look at the divs that you need to resize on load (with JavaScript).
i opened your page in Firefox with the developer tools to see how things work width and height wise and the results are interesting.
Basically the frame of the lightbox is made up of numerous divs all seem to be hard coded to a specific width and height. When you hover over the inner content using the inspector tool you can see that the inner content is actually the correct width and height but the container ( your collection of divs is not )
Try expanding the height and width of the container divs using css maybe??
I wouldnt have used this as answer but unfortunately i cant provide screenshots using just the comments section to my knowledge.
To see the image at full screen open it in a new tab.
For a good alternative try colorbox its a great JQuery modal plugin that can be used for just about anything.
Demos are here. Have a look at inline HTML example it seems to be similar to what you need.
Thanks to #Vincent G and #KyleT for their help I found that I had to edit the CSS styles for colorbox module.
#cboxLoadedContent iframe{display:block; min-width: 480px; min-height: 400px; border:0;}
and
#colorbox{min-width: 480px !important; min-height: 400px !important; }
in the colorbox.css file which was part of my Drupal installation.
After that the widget was loading fine.

Unable to scale pdfobject element down to fit in a given frame

I have some problems with including an PDF on an JSF site. I'm using pdfobject (http://pdfobject.com/) but it does not work out the way I want. I can't adjust my settings for my desired outcome, where there is a unscrollable, scaled document (so that it fits the frame) shown in a frame with width = 595px & height = 842px. I tried until now:
<script type="text/javascript" src="pdfobject.js"></script>
<script type="text/javascript">
window.onload = function() {
var myPDF = new PDFObject({
url : "ls_v7.pdf",
width: "595px",
height: "842px",
pdfOpenParams : {
page: 1,
view : 'FitB'
}
}).embed("pdf");
};
</script>
[...]
<div id="pdf">
It appears you don't have Adobe Reader or PDF support in this web
browser. Click here to download the PDF
</div>
or also
<object data="ls_v7.pdf#page=1&view=fitH"
type="application/pdf" width="595" height="842"> </object>
I think I tried most of the cases mentioned in this document, but where not able to come up with the right solution. (The oucome is always a frame with scroll-bars & the PDF gets always shown in full size)
Some background information:
I first included an PDF with iFrame on a JSF page, what went very well. But the Problem is, that on IE8 (some of the client machines) does not show them. So I went to this approach, if you would suggest to try another framework/etc. I would be also very greatful.
it's best to use CSS to specify exact size of the wrapper element.
PDFObject expands the PDF to 100% width/height of the parent container, so wrap your PDF in a div then size the div using CSS.
See this example: http://pdfobject.com/examples/simplest-styled.html

How to load images dynamically (or lazily) when users scrolls them into view

I've noticed this in numerous "modern" websites (e.g. facebook and google image search) where the images below the fold load only when user scrolls down the page enough to bring them inside the visible viewport region (upon view source, the page shows X number of <img> tags but they are not fetched from the server straight away). What is this technique called, how does it work and in how many browsers does it work. And is there a jQuery plugin that can achieve this behavior with minimum coding.
Edit
Bonus: can someone explain if there is a "onScrolledIntoView" or similar event for HTML elements. If not, how do these plugins work?
Some of the answers here are for infinite page. What Salman is asking is lazy loading of images.
Plugin
Demo
EDIT: How do these plugins work?
This is a simplified explanation:
Find window size and find the position of all images and their sizes
If the image is not within the window size, replace it with a placeholder of same size
When user scrolls down, and position of image < scroll + window height, the image is loaded
I came up with my own basic method which seems to work fine (so far). There's probably a dozen things some of the popular scripts address that I haven't thought of.
Note - This solution is fast and easy to implement but of course not great for performance. Definitely look into the new Intersection Observer as mentioned by Apoorv and explained by developers.google if performance is an issue.
The JQuery
$(window).scroll(function() {
$.each($('img'), function() {
if ( $(this).attr('data-src') && $(this).offset().top < ($(window).scrollTop() + $(window).height() + 100) ) {
var source = $(this).data('src');
$(this).attr('src', source);
$(this).removeAttr('data-src');
}
})
})
Sample html code
<div>
<img src="" data-src="pathtoyour/image1.jpg">
<img src="" data-src="pathtoyour/image2.jpg">
<img src="" data-src="pathtoyour/image3.jpg">
</div>
Explained
When the page is scrolled each image on the page is checked..
$(this).attr('data-src') - if the image has the attribute data-src
and how far those images are from the bottom of the window..
$(this).offset().top < ($(window).scrollTop() + $(window).height() + 100)
adjust the + 100 to whatever you like (- 100 for example)
var source = $(this).data('src'); - gets the value of data-src= aka the image url
$(this).attr('src', source); - puts that value into the src=
$(this).removeAttr('data-src'); - removes the data-src attribute (so your browser doesn't waste resources messing with the images that have already loaded)
Adding To Existing Code
To convert your html, in an editor just search and replace src=" with src="" data-src="
(Edit: replaced broken links with archived copies)
Dave Artz of AOL gave a great talk on optimization at jQuery Conference Boston last year. AOL uses a tool called Sonar for on-demand loading based on scroll position. Check the code for the particulars of how it compares scrollTop (and others) to the element offset to detect if part or all of the element is visible.
jQuery Sonar
Dave talks about Sonar in these slides. Sonar starts on slide 46, while the overall "load on demand" discussion starts on slide 33.
There is a pretty nice infinite scroll plugin here
I've never programmed one myself, but I would imagine this is how it works.
An event is bound to the the window scrolling
$(window).scroll(myInfinteScrollFunction);
The called function checks if scroll top is greater than the window size
function myInfiniteScrollFunction() {
if($(window).scrollTop() == $(window).height())
makeAjaxRequest();
}
An AJAX request is made, specifying which result # to start at, how many to grab, and any other parameters necessary for the data pull.
$.ajax({
type: "POST",
url: "myAjaxFile.php",
data: {"resultNum": 30, "numPerPage": 50, "query": "interesting%20icons" },
success: myInfiniteLoadFunction(msg)
});
The ajax returns some (most-likely JSON formatted) content, and passes them into the loadnig function.
Hope that makes sense.
You can now use loading="lazy" on the images as well as iframes so that it defers the loading until the user scrolls to that element.
<img src="http://placeimg.com/640/360/any" loading="lazy" />
As quoted in MDN:
Loading attribute The loading attribute on an element (or the
loading attribute on an ) can be used to instruct the browser
to defer loading of images/iframes that are off-screen until the user
scrolls near them.
Can I use?
You can use on all modern browsers for the images, but iframes are experimental as of now.
#import url('https://fonts.googleapis.com/css2?family=Oswald&display=swap');
.scroll-down {
height: 100vh;
background: #037ef3;
display: grid;
place-items: center;
color: #fff;
font-family: "Oswald";
font-size: 2em;
}
.image {
padding: 2em;
display: grid;
place-items: center;
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
}
<div class="scroll-down">
Let me take this space so that you can scroll down
</div>
<div class="image">
<img src="http://placeimg.com/640/360/any" loading="lazy" /> <!-- The only important part -->
</div>
Tip:
As you can see in the demo, it creates layout shift which will create a bad UX while scrolling. So try to use placeholders. Something similar like this: NextJS Placeholder
Lazy loading images by attaching listener to scroll events or by making use of setInterval is highly non-performant as each call to getBoundingClientRect() forces the browser to re-layout the entire page and will introduce considerable jank to your website.
Use Lozad.js (just 569 bytes with no dependencies), which uses IntersectionObserver to lazy load images performantly.
The Swiss Army knife of image lazy loading is YUI's ImageLoader.
Because there is more to this problem than simply watching the scroll position.
This Link work for me demo
1.Load the jQuery loadScroll plugin after jQuery library, but before the closing body tag.
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script><script src="jQuery.loadScroll.js"></script>
2.Add the images into your webpage using Html5 data-src attribute. You can also insert placeholders using the regular img's src attribute.
<img data-src="1.jpg" src="Placeholder.jpg" alt="Image Alt"><img data-src="2.jpg" src="Placeholder.jpg" alt="Image Alt"><img data-src="3.jpg" src="Placeholder.jpg" alt="Image Alt">
3.Call the plugin on the img tags and specify the duration of the
fadeIn effect as your images are come into view
$('img').loadScroll(500); // in ms
Im using jQuery Lazy. It took me about 10 minutes to test out and an hour or two to add to most of the image links on one of my websites (CollegeCarePackages.com). I have NO (none/zero) relationship of any kind to the dev, but it saved me a lot of time and basically helped improve our bounce rate for mobile users and I appreciate it.

Firefox and Chrome give different values for offsetTop

I am trying to position an span element (let us call it "the tooltip span") relative to a input field. To do this, I am wrapping the tooltip span and the input field in another span element (let's call it "the wrapper span") that has position: relative. Then I set position: absolute on tooltip span. This makes the tooltip span position itself relative to the wrapper span but not being part of the page flow - not taking up any space. This is exactly what I want.
Then, using javascript, I set the position of the tooltip relative to the position of the input element. Since the input element can be shaped differently on different pages (script should be globablly applicable), I am using its offsetTop and offsetLeft properties to calculate its position relative to the wrapper span.
However, I am noticing inconsistencies between browsers here. In Firefox, IE6, 7, 8, it works as expected. But in Chrome and Safari the reported offsetTop seems, well, incorrect.
To prove this, I created the test page below:
<html>
<head>
<style type="text/css">
span { font-size: 8px; position: relative; top: 0; left: 0; border: 1px solid red }
</style>
</head>
<body>
<span id="wrapper">
<input id="foo" name="foo" type="text">
</span>
<script type="text/javascript">
document.write("<br>Offset parent: " + document.getElementById("foo").offsetParent.id);
document.write("<br>Offset top: " + document.getElementById("foo").offsetTop);
</script>
</body>
</html>
and loaded it in Firefox and Chrome. Both browser report the wrapper span as its offsetParent, but for Firefox the offsetTop is -8 and for Chrome it is 2. Visually the page renders the same in both browsers.
This gives me a headache, because I cannot just hack in a different offset that I always apply when someone is using Chrome, because if I change the font size, the offsetTop will not change, and my script will break.
Is this a bug? Can I solve this differently?
You Can try using
$(window).load
instead of
$(document).ready
because Explorer and Chrome sets proper offsets only after images have been fully loaded.
I've been having the same problem as you and I realized that (in my case) the thing that was messing up the offset().top value in chrome, was having one or more images without the "height" attribute above the element.
Before
<img src="/images/foo.jpg" />
offset.top() was 100 in Chrome
offset.top() was 150 in Firefox and IE7 (beleive or not, it worked just fine in IE!)
After
<img src="/images/foo.jpg" height="50" width="50" />
offset.top() is 150 in both Firefox, IE7, AND CHROME.
Notice the the difference was 50px, which is actually the same as the image height.
Since I was developing a JQuery plugin, i tryed to collect all the images that had their width and height attributes undefined, and manually setting their size with .width() and .height(), but it didn't work, because Chrome returned 0 for both functions. So, i guess the problem with offset.top() actually relies on that. If JQuery is triying to get te offset.top() value by accumulating the "above" element's height, and one of those elements it's an image with no specified height, "0" will be added to that sum, and therefore the top value will be missing those "ignored" heights.
PS: Sorry for my english, it's been a long time since i wrote such a long text in this language!
Use jQuery. DOM differences between browsers is one of the things it excels at.
Put you code into a window.onload function. I recall having issues when attempting to work with the dom directly from a <script> during page load in firefox, and webkit tends to be slightly more willing to give a sane DOM at such points.
This is just based on prior issues i've encountered, i'm not sure if it's applicable to your case.
I ran into the same problem, and jQuery's position() function was reporting the same as the offset() function. Ultimately it turns out that even waiting for the document to be ready didn't work for me. I had to check offset() later in the flow (in my case, in my handler that is fired on a window.scroll event).
When I try this test code below, on page load, I get different figures for Firefox + Chrome. Once it loads, however, I can press 'd' and I get the same figure for both browsers.
// this produced different results on Chrome + Firefox (Chrome was wrong!)
$(document).ready(function () {
var x = $('#some-div-on-your-page').position().top;
alert("On load, offset is "+x); // Chrome + Firefox report diff figures
$(window).keydown(function(e, r) {
k = e ? e.keyCode : event.keyCode;
if(k == 68) { // press 'd'
var x = $('#some-div-on-your-page').position().top;
alert("Now the offset is "+x); // ...but this is consistent
}
});
}
Hope this helps.
I was experiencing the same problem, and tried adding to my function
$(document).ready(function(){});
and it worked in both Chrome and Firefox
If you get "0" in chrome, see if you are targeting an empty element like "a". It needs to wrap something in order to return the correct offset.
It could be related to the different border/margin values for the HTML and body elements that browsers set by default.

Categories