Best way to rearrange positioning of images/divs with javascript/jquery? - javascript

I took a peek at the source of http://wonderwall.msn.com and noticed how all the span tags that the blocks of the wall have don't seem to be associated with any ID. It makes me very curious how they are able to accomplish the animated repositioning of elements when you click on one of the blocks/images without associated ID.
I am curious how you can click on say an image and get other images around it to move to the side. Is it some sort of formula or algoirthm?
I would like to accomplish getting say, 5 spans/blocks, clicking on one, and getting others to animate/move to the sides.

IDs are not necessary and often harmful. You don't need them, generated or otherwise.
When you put an element on a page with an ID, you're making the claim that there should be only one of whatever it is. Seldom is this true. More often, what you want to do is associate some behavior with some of the elements on the page, of which there may be many, one or zero.
In this case, there are lots of little image dealies, which when clicked, rearrange themselves. I don't have an algorithm for you for calculating how they should move, but here's a framework for how you could achieve the same with jQuery.
// create jQuery plugin for highlighting and shuffling brick dealies
(function($){
function expandify() {
var href = this.attr('href');
// create a popup containing the href
return this;
}
function shuffle() {
this.each(function(index, elem){
// calculate new position and move the element there.
});
return this;
}
$.fn.expandify = expandify;
$.fn.shuffle = shuffle;
})(jQuery);
// attaches behaviors to elements on the page after they've loaded
// either $.ready, or window onload, or after some ajaxing takes place
$('.wallBrick')
.click(function(e){
$(e.target)
.expandify();
$('.wallBrick')
.not(e.target)
.shuffle();
});

The IDs are generated via JavaScript on-the-fly. You won't see it in the source, but you'll see it if you inspect it with Firebug.

Related

Can this popup feature be applied for many users?

I made a popup feature, which shows the phone number of a user. I was able to apply this feature to one instance. A single user.
Normally, each user has a unique phone number. Each user's number's already embedded, it's just to reveal the numbers, for multiple users.
But then, I thought, what if I have lots of users as they come, to the site? How do I dynamically apply the same popup feature without writing the same lines of code I wrote for the single user, over and over again?
Please, help me out.
This is the JavaScript I wrote...
let tansform_scale_0 = document.querySelector('.transform_scale_0');
let num_btn = document.querySelector('.num_btn');
num_btn.addEventListener('click', ()=>{
if (!tansform_scale_0.classList.contains('scale_to_1')) {
tansform_scale_0.classList.add('scale_to_1');
} else {
tansform_scale_0.classList.remove('scale_to_1');
}
})
Please view the code here: https://codepen.io/matthewdon/pen/MWQEvJM
You need to extend the logic you've applied to each of your cards. For example, the simplest way is to use querySelectorAll rather than the querySelector you currently have.
This is very similar in that it will return you a list of matching elements which you can then loop over and add your event listeners to in much the same way you are doing now.
However to make things a bit easier, you will be better off looping over each of the containing .card elements first. That way you can scope a second querySelector to the containing element and leave the rest of your logic largely intact.
You can shortcut the click handler itself though, by using classList.toggle rather than manually checking the class and then adding/removing it as required.
const cards = document.querySelectorAll('.card');
cards.forEach((card) => {
// rest of your click handler logic
})
Here's a snippet that brings all that together. I've put it on codepen as the editor on here isn't really suited to such a large amount of html: https://codepen.io/29b6/pen/VwQQqrw?editors=1111

Generate Bootstrap tooltip on-the-fly

I have a page with a text and some words in the text can change dynamically. These words have an element and should have a tooltip. When the user hovers the word (or I guess on a touch device clicks it), a tooltip should be generated using generateSpecialMarkupElement($(element).text()). Once the HTML has been rendered to the DOM another JavaScript function has to be called replaceMarkupHTML().
I don't have control over these functions unfortunately.
Now I'm wondering if there is a simple way in bootstrap get this done. For instance a before event to run the first function and an after event to call the second one.
Here is a simple example text and simplified versions of the functions:
http://jsfiddle.net/8aqz5auk/1/
So is there a bootstrap-way of hooking/intercepting this kind of thing? Or is there maybe another simple way it could be done?
Edit: I just had an idea. When bootstrap shows a tooltip, it seems to inject an element into the DOM. The interesting part is the container with the class 'tooltip-inner'. So I tried to listen on the body for new elements matching '.tooltip-inner' to be injected and whenever that happens I try to manipulate it:
$('body').on('DOMNodeInserted', '.tooltip-inner', function () {
var el = $(this)
el.html("") // empty the tooltip element
el.append(generateSpecialMarkupElement(el.text())) // insert the generated markup element
replaceMarkupHTML() // replace the markup element with normal html
});
Unfortunately it doesn't work. It just throws a a million errors and the site freezes when I try it.
Edit 2:
Thanks to Chris Barr, I got a little bit closer: http://jsfiddle.net/8aqz5auk/2/
But the tooltip doesn't always show up and the position of the tooltip seems to be kind of wrong (shows up on top of the word, rather then next to/above/below/...).
You might want to look into the tooltip events listed in the docs: https://getbootstrap.com/docs/3.3/javascript/#tooltips-events
$('.elements-with-tooltips').on('show.bs.tooltip', function () {
// do something…
})
You can run a function: before being shown, after being shown, before hiding, after hiding, and when the element is inserted into the DOM.

Toggling an html IMG element's class using JS (no Jquery)

I give up... All of your answers were just different ways of targeting the local element.
If you bothered to actually read what I was saying you would realise that it was not a problem with the code I already had, just that the code DID NOT work on IMG tags.
While faffing around trying to demonstrate my problem (and that none of your solutions did anything different to what was already happening) I found that I can achieve exactly what I want by applying a Grayscale filter to a DIV element placed over each image. The mouseover event then triggers an opacity change in the DIV element.
It is a little heavier that I wanted but it answered my ACTUAL question. The answer being:
Yes, there probably is a way to toggle class of IMG tags. But no, I am probably not going to find it here without causing arguments or being told i'm using "bad code". So yes, it IS easier and more efficient to target DIV elements.
By the way, page load times are about how large data packages are. Larger data packages (images, html/css/js documents, etc) take longer to download and so the page takes longer to load. The website I am trying to create proves this thesis, I have an almost complete and (almost) fully functional website with loads of 'clever' little effects all under 20mb, about 15mb of which is images. This website is clean and simple, is hosted on my Samsung Galaxy Tab 4 (using Papaya) and loads almost instantly.
THIS is what I meant by "I want this to be VERY lite". Thank you all for your attempts to help, it's just a shame that I couldn't get anyone to understand what was going on.
If you add onClick to image element you don't need to pass anything, you will receive MouseEvent which contains all information. You need target from event.
I suggest to not use onClick on element as it is not scalable, you have to add it to all elements. Better to add listener to wrapping/container element and then filter target by some attribute e.g data-something Please check fiddle
So you have wrapping element and you images:
<div class="images-container">
<img src="https://placeholdit.imgix.net/~text?txtsize=33&txt=350%C3%97150&w=350&h=150" data-toggleable class="thumb-gray thumb-color" />
<img src="https://placeholdit.imgix.net/~text?txtsize=33&txt=350%C3%97150&w=350&h=150" data-toggleable class="thumb-gray" />
<img src="https://placeholdit.imgix.net/~text?txtsize=33&txt=350%C3%97150&w=350&h=150" data-toggleable class="thumb-gray" />
</div>
and you attach listener to you wrapping element. It is best practice as you don't attach listeners to each element and same time you are able easily scale your solution
var imagesContainerEl = document.querySelector('.images-container');
imagesContainerEl.addEventListener('click', function(event) {
var element = event.target;
if (element.hasAttribute('data-toggleable')) {
element.classList.toggle('thumb-color');
}
});
The same code can be extended to support mouseover and mouseout. Check fiddle2. One function to rule them all and in the darkness bind them..
var imagesContainerEl = document.querySelector('.images-container');
imagesContainerEl.addEventListener('mouseover', onToggleImage);
imagesContainerEl.addEventListener('mouseout', onToggleImage);
function onToggleImage(event) {
var element = event.target;
if (element.hasAttribute('data-toggleable')) {
element.classList.toggle('thumb-color');
}
}
Also updated fiddle which shows how to make image grayscale/color
Is what you refer to in your question as
onClick="colorFunction(image1)"
an inline javascript event listener?
If so, try replacing it with:
onClick="colorFunction(this)"
and rewrite colorFunction() as:
function colorFunction(image) {
image.classList.toggle('thumb-color');
}

Automate page turning with jFlip

I want to have a page turn effect like the one seen on this page: jFlip demo except I want to automate the page turning, like make it happen every second, 20 times (or however many images I have). I want to be able to trigger this animation to run either on page load, when a button is clicked, etc.
Unfortunately I don't understand jQuery all that well and the plugin's events seem rather complicated to me, probably mostly due to my inexperience with jQuery. Any help on which direction I should go, methods I should try? I am not limiting myself to jQuery or even Javascript, this is just the example I have found that achieves my desired effect.
You can find the updated code here. replace this with old one.
Usage :
var jFlip = new Flip("#g1",300,300,{background:"green",cornersTop:true,scale:"fit"});
// here #g1 is a jquery selector (make sure it returns only one).
// The structure is Flip(JQselector,width,height,options)
then use the jFlip object to flip slides/pages
jFlip.flipMe() // for next slide
jFlip.flipMe(true) // for prev slide
for binding a function to slide change event you can use
$("#g1").bind("flip.jflip",function(event,index,total){
$("#l1").html("Image "+(index+1)+" of "+total);
});
// here the selector is same as the one passed inside jFlip function.
Try this and let me know the feedback.

JavaScript seem just to react after MouseMove

probably the strangst thing I've ever seen: I want to load a grid after the document is loaded. Since the grid (infragistics) seems to delay, I set a interval, in the interval I try to get the needed element, if I cant find it, I wait another 500 ms:
function trySetEditMode(obj) {
var testObj = $('#' + obj.btnId).parents("tr[type='row']").get(0);
if (testObj && testObj._object){
clearInterval(_intervalId);
The funny thing is: Even if I see the with the IE debugging tool the row is there, it justdoenst find it. It works just when I move arround with the mouse. This effect seems totally random.
Has anyone an idea how this is possible? I tried to tinker arorund with .focus, .blur etc, but nothing seems to work.
btw: obj is a custom object from me, the button id is the clientid of the button and is there. For example:
$('#' + obj.btnId).parents('tr').length
returns a length.
Can this be a bug from the infragistics control? If yes, how could I simulate this mouseMove?
Best regards
Matthias
Creating the row objects is costly on the client and as such they are created on demand to avoid a large performance hit if all row objects were created initially. The actual creation of these objects is on mouse over or when you use the get_row() method that is provided as part of the client side object model. As such the recommended approach is to use the client side object model to get a reference to the row, for example the following will get the first row:
var grid = $find("webDataGrid1");
var row = grid.get_rows().get_row(0);
probably someoneelse will have this problem as well with infragistics webdatagrid:
Sidenote: I cant believe the ig support couldnt tell me that:
The Grid is kinda lazyLoaded, the dom gets loaded but the ig relevant attributes AND the object behind just get loaded when you go with the mouse over. So it didnt matter how long I waited, the object wasnt just there.
Since I had no time to get a proper solution, I basically fired manually the mouse over event on a cell. It doesnt matter on what you do this, but I tested it with the first one and it worked proper.
//The grid doesnt load data (except the first row) until the mouse did hover over it
//Get a cell, and hover over it
var parentTd = btn.parents('td').first();
var cell = parentTd.siblings()[0];
var rows = $find('dgrRoles').get_rows();
if (cell && rows) {
cell.target = cell;
rows._onMouseOver(cell);
}

Categories

Resources