JavaScript: Injecting CSS code using jQuery - javascript

So, I've just started developing a twitch event list with Streamlabs' kinda API and probably got some trouble accessing the style trough jQuery. What I am trying to accomplish is creating .widget-EventList li:nth-child-s depending on the value of {max__events} and besides, reduce the amount of opacity. Sure, I could add those classes manually to the CSS, and I did first, but there was missing a lot of dynamic and user-friendliness. There are two functions I can write code in:
That's the problematic function, it's called on widget load:
document.addEventListener('onLoad', function(obj) {
$('.widget-EventList .message').css("background", "black"); // experimental, doesn't work either, tho
var opMax = 1 / {max__events};
for(var i = {max__events}; i <= 1; i++){
let temp1 = 1 - opMax;
$('.widget-EventList li:nth-child(' + i + ') div:last-child {}').insertAfter('.widget-EventList .message');
$('.widget-EventList li:nth-child(' + i + ') div:last-child').css("color", "{font_color}");
$('.widget-EventList li:nth-child(' + i + ') div:last-child').css("opacity", temp1);
opMax++;
}
});
Here's the additional function I can write into, it's called on widget event receive:
document.addEventListener('onEventReceived', function(obj) {
$('.widget-EventList .message').css("background", "black"); // experimental, and works perfectly fine
});
That's the position it is supposed to be in:
.widget-EventList .message {
float: middle;
white-space: nowrap;
text-overflow: ellipsis;
margin: 4.5 0.25em;
display: inline-block;
}
/*style list-elements <<-----HERE----- */
Maybe document.addEventListener('onLoad', function(obj)) is loading way before the css even got loaded? What am I missing here?

Related

Scrolling select element jumps to top when removing options from DOM in IE

This issue appears to be isolated to Internet Explorer:
I'm moving option tags from one select to another when they're double clicked using Javascript. The select elements can have many items, so I've set the height with overflow: auto; so that they scroll. If you scroll down the list and double click an item to move, the select list will scroll up to the top when the option is removed, instead of staying at the current scrolled-to position as it does in Chrome or Firefox.
I made a basic example to demonstrate this here: https://jsfiddle.net/yk8LeLbw/1/
The Javascript is pretty simple:
$(".listBoxSelectorAvail").dblclick(function() {
$(this).find("option:selected").remove().appendTo(".listBoxSelectorAssigned");
});
$(".listBoxSelectorAssigned").dblclick(function() {
$(this).find("option:selected").remove().appendTo(".listBoxSelectorAvail");
});
I haven't been able to find any specific reason why this happens - I'm not sure if it's a bug or if this is expected behavior, but is there anything that can be done?
EDIT: made the title more clear
EDIT 2: I was hoping to stop the scrolling, but the best solution I've come up so far is to rescroll once the item has been moved, as seen here:
https://jsfiddle.net/yk8LeLbw/2/
The issue is that IE behaves differently. So, we have to work around that unwanted behavior. The solution is to wrap the select in a div and use some CSS.
Here's a working jsFiddle.
Note how I wrapped a div around each select and replaced the size="50" attribute with the multiple="true" attribute. This removes the scrollbar on the select elements.
$(document).ready(function() {
var arr1 = [];
var arr2 = [];
arr1.push("<div class='scroll'><select class='listBoxSelectorAvail' multiple='true'>");
arr2.push("<div class='scroll'><select class='listBoxSelectorAssigned' multiple='true'>");
for (var i = 0; i < 20; i++) {
arr1.push("<option value=\"" + i + "\">Option " + i + "</option>");
}
arr1.push("</select></div>");
arr2.push("</select></div>");
$("body").append(arr1.join(""));
$("body").append(arr2.join(""));
$(".listBoxSelectorAvail").dblclick(function(e) {
$(this).find("option:selected").remove().appendTo(".listBoxSelectorAssigned");
});
$(".listBoxSelectorAssigned").dblclick(function(e) {
$(this).find("option:selected").remove().appendTo(".listBoxSelectorAvail");
});
});
Here's the modified CSS.
select {
width: 200px;
height: 200px;
}
.scroll {
overflow: auto;
display: inline-block;
margin-left: 10px;
}

Top Bar breakpoint in foundation 5

I tried the break point in 5.5.2 and was pretty easily accomplished just by changing the width in 3 instances as follow:
meta.foundation-mq-topbar {
font-family: "/only screen and (min-width:64.063em/";
width: 64.063em;
}
#media only screen and (min-width: 64.063em) {
.top-bar {
background: #333333;
*zoom: 1;
overflow: visible;
}
the only problem I'm facing is the main menu (parent link) of the drop down is not visible (once you click, it only shows the dropdown part not the main link) when it comes to toggle menu, unless you reach the actual break point ie. 40.063 em. Should I need to make any change in javascript?
Thanks for helping me!!
I've done a little more research and found the fix. All you have to do is go to [js/foundation/foundation.topbar.js]
line number 368 change "show-for-small" to "show-for-medium-down".
Following is the code for you:
if (settings.mobile_show_parent_link == true && url) {
$titleLi = $('<li class="title back js-generated"><h5></h5></li><li class="parent-link show-for-medium-down"><a class="parent-link js-generated" href="' + url + '">' + $link.html() +'</a></li>');
} else {
$titleLi = $('<li class="title back js-generated"><h5></h5>');
}
Then at the very bottom of your html file, where you are calling other js files, call topbar.js by adding following line
<script src="js/foundation/foundation.topbar.js"></script>
You can even make this work just by making the above mentioned change in js/foundation.min.js

Mootools slideshow adapting

I'm looking for a Mootools slideshow that changes main picture with a timer (normal slideshow function) and has a clickable thumbnail list. Because I have many other mootools features in the site I am working so the slideshow has to be mootools.
I found two options:
scrollgallery2.mashitup.de (which is a v.2 of this) - how to make it start the slideshow? (its stoped in the first picture)
github.com/jakobholmelund/SpinSlider (which Jakob adapted from a jQuery slideshow) - the .js file is missing the thumbs code. Any ideas how to merge/translate the jQuery idea to Mootools?(see under)
jQuery version:
if (options.bulletThumbs) {
var thumbName = slides.eq(i).data('thumb');
if (thumbName) {
var liMarkup = $('<li class="has-thumb">' + i + '</li>')
liMarkup.css({
"background": "url(" + options.bulletThumbLocation + thumbName + ") no-repeat"
});
}
}
orbitWrapper.children('ul.orbit-bullets').append(liMarkup);
liMarkup.data('index', i);
liMarkup.click(function () {
stopClock();
shift($(this).data('index'));
});
}
setActiveBullet();
}
Mootools adapted by Jakob Holmelund:
if(this.options.bullets){
this.bullets = new Element("ul").addClass("spin-bullets").inject(this.spinWrap);
this.slides.each(function(slide, index){
new Element("li",{text:index+1}).addEvent("click", function(){
self._stopClock();
self._spin(index);
}).inject(self.bullets);
});
this._setActiveBullet();
}
Any suggestions how to fix one of this? or any other slideshow idea?
Here is new code I added on the .js of Jakobs file. Maybe good for a next version of that slideshow.
In the JS file: ( this adds the capacity to see if a img is in the slide and adds thumbnail to the <li> CSS background-image)
if(this.options.bullets){
this.bullets = new Element("ul").addClass("spin-bullets").inject(this.spinWrap);
this.slides.each(function(slide, index){
var stl = '';
if (!slide.hasChildNodes()) stl = 'background-image: url('+slide.getAttribute('src')+')';
else if (slide.getChildren('img').length > 0) stl = 'background-image: url('+slide.getChildren('img')[0].get('src')+')';
else if (slide.get('img')) stl = 'background-image: url('+slide.get('img').get('src')+')';
new Element("li",{text:index+1, style: stl, class: ((stl != '')?"spin-bullets-img":"")}).addEvent("click", function(){
self._stopClock();
self._spin(index);
}).inject(self.bullets);
});
this._setActiveBullet();
}
Then add in the CSS:
.spin-bullets li.spin-bullets-img {
width: 50px;
height: 25px;
background-position: center top;
background-size: 80px auto;
border:#CCC 4px solid;
}
.spin-bullets li.spin-bullets-img.active {
border:#88F 4px solid;
}
Instead of reinventing the wheel it may be easier to use something that already exists. I took a quick look in the MooTools forge (http://mootools.net/forge/browse?search=gallery) and found the following:
http://software.bmo-design.de/scrollgallery.html
I modified the very awesome http://www.electricprism.com/aeron/slideshow/ on this project awhile back: http://treecareenterprises.com/c/tree-care-photo-gallery/?showonly=5
Unfortunately I do not have time to extract the code today but feel free to take a look and see if you can grab the relevant tidbits. Also it looks like it is running on v1.2.4 you may want to upgrade it to 1.4 which is not as hard as it may seem see the following link for guidence: https://github.com/mootools/mootools-core/wiki/Upgrade-from-1.2-to-1.3-or-1.4

How can I display the output of my userscript in a floating box on the side of the page?

I'm working on a userscript for Unicreatures that keeps track of events during exploration. It's working (well, it works but still needs some work lol) but I need a way to display the information I'm collecting that doesn't involve popup alerts for every step.
How can I create a box on the page and display stuff in it?
I'm looking to create a frame, window, whatever on the left side of the menu on this page, and write the values of various variables into it as my script runs.
I'm collecting this data in localStorage, so my script will first update various localStorage properties and then display the results in this box somehow:
localStorage.steps = Number(localStorage.steps) + 1;
displayValueInFloatingBox(localStorage.steps + ' in Sargasso' );
I'd also like to add a button to this box to reset the values of these properties, so that I have a choice of keeping track forever or just for a session or two without having to edit the script every time (especially if I decide to share the script). I assume this would just set the variables to zero so I just need to know how to create the button and making it do something... This would probably use an eventListener somehow.
Please stick to plain JavaScript, no jQuery... I'm still barely getting JavaScript at the moment. And please, explain answers so I understand how something works - I don't just want code snippets that leave me coming back with a similar question because I don't understand why a bit of code was used.
Appendix A: my current script
// ==UserScript==
// #name Unicreatures Egg pop-up
// #namespace Unicreatures Egg pop-up
// #description Unicreatures Egg pop-up
// #include http://unicreatures.com/explore.php*
// #include http://www.unicreatures.com/explore.php*
// ==/UserScript==
var regexp = /You find an? (Exalted )?(.*?) egg nearby/;
var match = regexp.exec( document.body.innerHTML );
if ( match ) {
if ( match[1] ) {
alert( "Exalted egg found: " + match[2] );
} else {
alert( "Normal egg found: " + match[2] );
}
}
var y = document.body.innerHTML;
var links = document.getElementsByTagName( 'a' );
for ( var i = 0; i < links.length; i++ ) {
var link = links[i];
if ( /area=sea(?!\&gather)/.test( link.href )) {
link.addEventListener( 'click', function () {
localStorage.steps=Number(localStorage.steps)+1
// alert(localStorage.steps + ' in Sargasso' );
}, true );
}
}
//document.addEventListener('click', function(){alert('page clicked')}, true);
if(y.indexOf("You find a Noble")> 0)
{
alert('Noble Egg Alert');
}
if(y.indexOf("You find an Exalted")> 0)
{
localStorage.exaltedEggCount=Number(localStorage.exaltedEggCount)+1;
alert('Exalted Egg Alert '+localStorage.exaltedEggCount);
}
if(y.indexOf("egg nearby!")> 0)
{
localStorage.eggCount=Number(localStorage.eggCount)+1;
alert('Egg Alert '+localStorage.eggCount);
}
Here's one simple way to add a box to the top left corner of the page. First, we need to create a div element to serve as the box. (Other HTML elements could work too, but div is a good choice since it has no special meaning, it's just a simple container.)
var box = document.createElement( 'div' );
We'll give our box an ID, both so that we can find it later with document.getElementsById() and so that we can style it with CSS:
box.id = 'myAlertBox';
Now we need to style the box. Since we're using GreaseMonkey, we can use GM_addStyle to add CSS style rules to the document:
GM_addStyle(
' #myAlertBox { ' +
' background: white; ' +
' border: 2px solid red; ' +
' padding: 4px; ' +
' position: absolute; ' +
' top: 8px; left: 8px; ' +
' max-width: 400px; ' +
' } '
);
Note the awkward syntax for including a multi-line string in JavaScript. (There are other ways to style the box, too, which will work also outside GreaseMonkey. I'll show some of the them below.)
Looking at the CSS style rule itself, the first three lines just say that our box should have a white background and a two pixels wide red border, and that there should be four pixels of padding between the border and the content. All this just makes it look like a typical simple alert box.
The following line says that our box should be absolutely positioned on the page — that is, always in a fixed position regardless of what else is on the page — and the one below that specifies the position we want to give it: here, four pixels from the top left corner of the page. The last line just says that the box should not stretch to be more than 400 pixels wide, no matter how much content we stuff into it.
Speaking of which, of course we need to add some content too. We can either just use plain text:
box.textContent = "Here's some text! This is not HTML, so <3 is not a tag.";
or we can use HTML:
box.innerHTML = "This <i>is</i> HTML, so <3 needs to be escaped.";
Finally, we need to add the box to the page to make it show up:
document.body.appendChild( box );
And there you go! A box on the page.
OK, but how do we get rid of it? Well, the simplest way would be to just make it disappear when clicked:
box.addEventListener( 'click', function () {
box.parentNode.removeChild( box );
}, true );
Alternatively, we could create a separate close button for the box and set the click handler only for that:
var closeButton = document.createElement( 'div' );
closeButton.className = 'myCloseButton';
closeButton.textContent = 'X';
GM_addStyle(
' .myCloseButton { ' +
' background: #aaa; ' +
' border: 1px solid #777; ' +
' padding: 1px; ' +
' margin-left: 8px; ' +
' float: right; ' +
' cursor: pointer; ' +
' } '
);
box.insertBefore( closeButton, box.firstChild );
closeButton.addEventListener( 'click', function () {
box.parentNode.removeChild( box );
}, true );
Inserting the close button before any other content in the box, and giving it the style float: right makes it float to the top right corner and makes text flow around it. The cursor: pointer rule makes the mouse cursor look like a hand when over the button, showing that it's clickable.
You can also add other buttons to the box (or elsewhere on the page) in the same way.
I gave the button a class name instead of an ID so that, if you want, you can give all your buttons the same class and they'll be style the same way.
It's also possible to just put the HTML code for the buttons in box.innerHTML, find the resulting elements e.g. with box.getElementById() and add the click handlers for them that way.
I said I'd mention other ways of styling elements. One simple way is to just write the CSS rules directly into its style property:
box.style.cssText =
' background: white; ' +
' border: 2px solid red; ' +
' padding: 4px; ' +
' position: absolute; ' +
' top: 8px; left: 8px; ' +
' max-width: 400px; ' ;
(This way, we wouldn't even need to give the box an ID.) It's also possible to set (and read) the styles one at a time:
box.style.background = 'white';
box.style.border = '2px solid red';
box.style.padding = '4px';
box.style.position = 'absolute';
box.style.top = '8px';
box.style.left = '8px';
box.style.maxWidth = '400px';
You'll note that some of the names are different; for example, max-width would not be a valid JavaScript property name, so it becomes maxWidth instead. The same rule works for other CSS property names with hyphens.
Still, I prefer GM_addStyle because it's more flexible. For example, if you wanted to make all links inside your box red, you could just do:
GM_addStyle(
' #myAlertBox a { ' +
' color: red; ' +
' } '
);
By the way, here's a neat trick: if you replace position: absolute with position: fixed, then the box will not scroll along with the page — instead it'll stay fixed to the corner of your browser even if you scroll down.
Another tip: If you don't have Firebug yet, install it. It will make examining page content and debugging JavaScript so much easier.

Html Country List with flags [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking us to recommend or find a tool, library or favorite off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam. Instead, describe the problem and what has been done so far to solve it.
Closed 9 years ago.
Improve this question
I am looking for a way to select and display a list of countries, preferably with flags. Any suggestions?
I started of by trying this jQuery plugin http://www.graphicpush.com/website-language-dropdown-with-jquery, but as the list of countries I have is quite large it turned out that the performance was really bad (too many http requests to images). Also the list is bulky when it is larger than 50 elements.
Just wanted to suggest a (imho) smarter way of doing the flags sprite.
The idea is to save the flags in a grid according to the country iso2 code.
1st letter -> vertical position
2nd letter -> horizontal position
Examples (for 16x11px flags + 4x4px spacing):
Austria = AT
A = 1 => vertically 1st row => y = (1-1)*(11+4) = 0
T = 20 => horizontally 20th column => x = (20-1)*(16+4) = 380
United States = US
U = 21 => vertically 21st row => y = (21-1)*(11+4) = 300
S = 19 => horizontally 19th column => x = (19-1)*(16+4) = 360
This way I can calculate the flag location with a very easy function on the client side without the need of 200+ extra style definitions.
Sample jQuery plugin:
(function($) {
// size = flag size + spacing
var default_size = {
w: 20,
h: 15
};
function calcPos(letter, size) {
return -(letter.toLowerCase().charCodeAt(0) - 97) * size;
}
$.fn.setFlagPosition = function(iso, size) {
size || (size = default_size);
return $(this).css('background-position',
[calcPos(iso[1], size.w), 'px ', calcPos(iso[0], size.h), 'px'].join(''));
};
})(jQuery);
Demo Usage:
$('.country i').setFlagPosition('es');
http://jsfiddle.net/roberkules/TxAhb/
And here my flag sprite:
Note from the future: jQuery UI autocomplete now supports custom
rendering by default, see
http://api.jqueryui.com/autocomplete/#method-_renderItem.
It's pretty easy. Things you need:
jQuery UI auto-complete
UI auto-complete html extension
A list of country names/codes
A CSS sprite with all flags
Remember, Google is your friend. Blend the ingredients well, carefully whisk some javascript in, and it's done - in 7 lines of code:
var countries = [["Argentina", "ar"], ...];
var countryNames = countries.map(function(country){
return {
label: '<div class="flag '+country[1].toLowerCase()+'">'+country[0]+'</div>',
value: country[0]
}
});
$('#country').autocomplete({
source: countryNames,
html: true
});
Here's this code in action
As mentioned by commenters, a CSS sprite is the proper solution here. Fortunately, there are many CSS sprites of flags freely available. This one looks pretty good.
We will have to tweak the dropdown code to accomodate that pre-made CSS sprite. I've gone ahead and done that for you. Here's a live demo.
languageswitcher.js
## -44,10 +44,11 ##
source.removeAttr("autocomplete");
var selected = source.find("option:selected");
var options = $("option", source);
- $("#country-select").append('<dl id="target" class="dropdown"></dl>')
- $("#target").append('<dt class="' + selected.val() + '"><span class="flag"></span><em>' + selected.text() + '</em></dt>')
- $("#target").append('<dd><ul></ul></dd>')
+ $("#country-select").append('<dl id="target" class="dropdown f16"></dl>')
+ $("#target").append('<dt><em class="flag ' + selected.val().toLowerCase() + '">' + selected.text() + '</em></dt>');
+ $("#target").append('<dd><ul></ul></dd>');
+ var $drop = $("#target dd ul");
options.each(function(){
- $("#target dd ul").append('<li class="' + $(this).val() + '"><span class="flag"></span><em>' + $(this).text() + '</em></li>');
+ $drop.append('<li><em class="flag ' + $(this).val().toLowerCase() + '">' + $(this).text() + '</em></li>');
});
}
languageswitcher.css
## -45,6 +45,8 ##
.dropdown dd { position: relative; }
+.dropdown ul { max-height:350px; overflow-y:auto; overflow-x:hidden; }
+
.dropdown a {
text-decoration: none;
outline: 0;
## -52,6 +54,7 ##
display: block;
width: 130px;
overflow: hidden;
+ white-space:nowrap;
}
.dropdown dt a {
## -107,23 +110,6 ##
padding: 2px 10px;
}
- .dropdown dd ul li a span,
- .dropdown dt a span {
- float: left;
- width: 16px;
- height: 11px;
- margin: 2px 6px 0 0;
- background-image: url(flags.png);
- background-repeat: no-repeat;
- cursor: pointer;
- }
-
- .us a span { background-position: 0 0 }
- .uk a span { background-position: -16px 0 }
- .fr a span { background-position: -32px 0 }
- .de a span { background-position: -48px 0 }
- .nl a span { background-position: -64px 0 }
-
.dropdown dd ul li a em,
.dropdown dt a em {
font-style: normal;
## -138,3 +124,5 ##
.dropdown dd ul li a:hover { background-color: rgba(255,255,255,.1); }
.dropdown dd ul li a:hover em { color: #fff; }
+
+.flag { padding-left:18px; }
The CSS changes I made were Q&D hacks; you'll probably want to spend some time polishing them. I removed all of the flag-specific stuff from languageswitcher.css since we're using flag16.css.
Also, if the country code doesn't exist in the CSS sprite, the flag shown will default to the
African Union's flag since it is the first image in the sprite. In the demo, several of the countries in my example list don't have a sprite image. Watch out for that.
Here's a file with the list of countries and links to their flags (some of the links might not be working though but most of them are)
Excel File
You can also use flags from http://www.famfamfam.com/lab/icons/flags/ and simply use CSS for positioning the appropriate flag.
----EDITED----
If i need to show flag of my country then i would do mapping from CSS like
<span class='np'></span>
.np {
background: url(./flags_preview_large.png) -172px -397px no-repeat;
width: 14px;
height: 20px;
}

Categories

Resources