Is it possible to hide the additional icon when dragging an element in Microsoft Edge? - draggable

Microsoft Edge shows a confusing icon when dragging and dropping elements using the html "draggable" attribute. I think it might be considered a "cursor", but I am unsure. Regardless, is it possible to hide this copy/stop icon?
Microsoft Edge on Windows Example
As far as Windows is concerned, it looks like this icon only shows up on Edge. Chrome has a default behavior of a cursor change (much less obtrusive).
Google Chrome on Windows Example
Any browser on MacOS has neither the icon or the cursor change.
Here's a codepen example where you can see the behavior reproduced
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
ev.dataTransfer.setDragImage(document.getElementById("drag-image"), 0, 0);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
}
.droppable {
float: left;
min-width: 100px;
min-height: 80px;
border: 1px solid black;
margin: 0 32px;
padding: 8px;
}
#drag-image {
background: #eee;
padding: 4px;
position: absolute;
bottom: 0;
left: 0;
}
<h2>Drag and Drop</h2>
<p>Drag the image back and forth between the two div elements.</p>
<div class="droppable" ondrop="drop(event)" ondragover="allowDrop(event)">
<h1 draggable="true" ondragstart="drag(event)" id="drag1">Drag Me</h1>
</div>
<div class="droppable" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="drag-image">Drag Me</div>
Background/why it matters: This could be considered a minor inconvenience, but for an application that is centered around drag and drop behavior this sort of UX mishap can be really confusing for the end user. Not only does the icon compete for attention with the drag image, but the icon is also potentially misinforming the user on the action they are taking. The "copy" icon is used when a droppable area is available, but the user could be moving (cutting) or creating a net new object from something that does not exist yet (think dragging a new component onto the screen in squarespace or a similar app).

I suggest you to use DataTransfer.dropEffect property in your code may help to solve the issue for MS Edge.
The DataTransfer.dropEffect property controls the feedback (typically visual) the user is given during a drag and drop operation. It will affect which cursor is displayed while dragging. For example, when the user hovers over a target drop element, the browser's cursor may indicate which type of operation will occur.
Example:
function dragstart_handler(ev) {
console.log("dragStart: dropEffect = " + ev.dataTransfer.dropEffect + " ; effectAllowed = " + ev.dataTransfer.effectAllowed);
// Add this element's id to the drag payload so the drop handler will
// know which element to add to its tree
ev.dataTransfer.setData("text", ev.target.id);
ev.dataTransfer.effectAllowed = "move";
}
function drop_handler(ev) {
console.log("drop: dropEffect = " + ev.dataTransfer.dropEffect + " ; effectAllowed = " + ev.dataTransfer.effectAllowed);
ev.preventDefault();
// Get the id of the target and add the moved element to the target's DOM
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
}
function dragover_handler(ev) {
console.log("dragOver: dropEffect = " + ev.dataTransfer.dropEffect + " ; effectAllowed = " + ev.dataTransfer.effectAllowed);
ev.preventDefault();
// Set the dropEffect to move
ev.dataTransfer.dropEffect = "move"
}
div {
margin: 0em;
padding: 2em;
}
#source {
color: blue;
border: 1px solid black;
}
#target {
border: 1px solid black;
}
<div>
<p id="source" ondragstart="dragstart_handler(event);" draggable="true">
Select this element, drag it to the Drop Zone and then release the selection to move the element.
</p>
</div>
<div id="target" ondrop="drop_handler(event);" ondragover="dragover_handler(event);">Drop Zone</div>
JsFiddle Example link
Output in MS Edge:
Reference:
DataTransfer.dropEffect

Related

How can I make parallax working in Firefox?

I have a working parallax example on Chrome on Codepen. The most important code is here :
body {
height : $body-height;
perspective : #{$perspective}px;
perspective-origin : 0;
-webkit-overflow-scrolling : touch; // Safari fix
}
#at-root body,
.parallax-container {
overflow-x : hidden;
overflow-y : auto;
position : relative;
}
#at-root body {
#at-root .parallax-container {
// position
transform-style : preserve-3d; // to avoid that the intermediary container flattens the effect
// size
height : 100%;
width : 100%;
#at-root {
.background-content,
.foreground-content {
position : relative;
}
.background-content {
transform-origin : 0 0;
transform : translateZ(0) scale(1);
}
div.other-class {
$value : 126;
height : #{$value}px;
bottom : #{-($value + 35)}px;
}
}
}
}
I read a lot of things on parallax and still does not understand what is going wrong here.
I believe I made it work one time, maybe it is a regression, but I cannot find the problem.
Do not hesitate to suggest things for Safari if it does not work on Safari too because I cannot test it on this browser yet.
I am on Firefox 82.0.3 and Chromium 86.0.4240.198 on Ubuntu 20.04.

FancyBox 3: top positioning of images

I have to position the image container at the top of the page, but there is no parameter.
I have found a small snippet in the docs of fancybox3, That works for me, but not for the navigation buttons. They are still in the middle of the page:
afterShow : function( instance, current, e ) {
$('.fancybox-content').css('transform','translate3d(0px, 30px, 0px)');
}
Spacing around content is controlled by CSS padding property of wrapping element. This is the default value for element containing an image:
.fancybox-slide--image {
padding: 44px 0;
}
#media all and (max-height: 576px) {
.fancybox-slide--image {
padding: 6px 0;
}
}
You can adjust that for your likening. As you can see, this gives greater flexibility that just some js option.

How to scrollTop a div whose content is managed by AngularDart?

I have a div holding some chat history. I would like for the div content to scroll when it becomes full. I have this working using jQuery in another project, but what would be the proper AngularDart way to achieve this?
Simplifying a bit, in my HTML I have
<div class="chatHistory">{{ctrl.text}}</div>
(using style white-space:pre) and in my controller I have the method
void addToChatHistory(String msg) {
text += msg;
var elt = querySelector(".chatHistory");
elt.scrollTop = elt.scrollHeight;
}
Issues:
This code scrolls the div content but not quite enough because it sets the scrollTop too quickly; i.e., even before the .chatHistory can be updated by Angular.
Besides this (partial) solution doesn't feel very Angular in style given the use of querySelector.
I tried setting up a watch on the text field but that also fires too early. Suggestions?
For the first issue you can use Timer.run to defer the scroll execution :
Timer.run(() => elt.scrollTop = elt.scrollHeight);
For the second issue you can inject the Element managed by your controller and use querySelector on it :
MyController(Element e) : elt = e.querySelector('.chatHistory');
EDIT
I published a package containing this directive: http://pub.dartlang.org/packages/bwu_angular
-------
I would create a Directive/Decorator like NgEventDirective but for the resize event and add it to your div. In the event handler you set your scrollTop property.
I found contradictory info about the resize event.
DART - Resize div element event says it is available everywhere
Onresize for div elements? is a workaround for browsers that don't support this event.
another page covering this topic: http://marcj.github.io/css-element-queries/
I tried to create an Angular implementation for the 'workaround' (2nd link) but run into this issue https://code.google.com/p/dart/issues/detail?id=18062 which contains info about a workaround but I didn't yet find time to implement it.
EDIT
I checked my attempt and it worked in Dartium with the version I downloaded today (Dart VM version: 1.4.0-dev.4.0 (Thu May 1 04:06:09 2014) on "linux_x64").
I haven't tried in other version since I created the issue.
(The code should be improved to make the directive more generic - the event method should be assignable by an attribute not hardcoded)
index.html
<!DOCTYPE html>
<html ng-app>
<head>
<script src="packages/web_components/platform.js"></script>
<style>
.resize-triggers {
visibility: hidden;
}
.resize-triggers, .resize-triggers > div, .contract-trigger:before {
content: " ";
display: block;
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
overflow: hidden;
}
.resize-triggers > div {
background: #eee;
overflow: auto;
}
.contract-trigger:before {
width: 200%;
height: 200%;
}
</style>
<style>
#my_element {
height: 200px;
overflow: scroll;
}
</style>
</head>
<body ng-cloak>
<div>
<div id="my_element" style="border: 1px solid blue;">
<div id='my_sizable' ng-observe-size></div>
</div>
</div>
<script type="application/dart" src="index.dart"></script>
<script type="text/javascript" src="packages/browser/dart.js"></script>
</body>
</html>
index.dart
library angular_observe_resize.main;
import 'dart:async' as async;
import 'dart:html' as dom;
import 'package:angular/angular.dart' as ng;
import 'package:angular/application_factory.dart' as ngaf;
// see https://stackoverflow.com/questions/19329530
// and this bug https://code.google.com/p/dart/issues/detail?id=18062
// source from http://www.backalleycoder.com/2013/03/18/cross-browser-event-based-element-resize-detection/
#ng.Decorator(selector: '[ng-observe-size]')
class NgObserveSizeDirective implements ng.AttachAware, ng.DetachAware {
dom.Element _element;
bool _hasAttacheEvent;
NgObserveSizeDirective(this._element);
void onSizeChange(dom.Event e) {
_element.parent.scrollTop = _element.scrollHeight;
}
dom.HtmlElement _triggers;
void resetTriggers() {
var expand = _triggers.children[0];
var contract = _triggers.children[_triggers.children.length - 1];
var expandChild = expand.children[0];
contract.scrollLeft = contract.scrollWidth;
contract.scrollTop = contract.scrollHeight;
expandChild.style.width = '${expand.offsetWidth + 1}px';
expandChild.style.height = '${expand.offsetHeight + 1}px';
expand.scrollLeft = expand.scrollWidth;
expand.scrollTop = expand.scrollHeight;
}
int _resizeLastWidth;
int _resizeLastHeight;
bool checkTriggers() {
return _element.offsetWidth != _resizeLastWidth ||
_element.offsetHeight != _resizeLastHeight;
}
int _resizeRaf;
void scrollListener(dom.Event e) {
resetTriggers();
if(_resizeRaf != null) {
dom.window.cancelAnimationFrame(_resizeRaf);
}
_resizeRaf = dom.window.requestAnimationFrame((num highResTime){
if(checkTriggers()) {
_resizeLastWidth = _element.offsetWidth;
_resizeLastHeight = _element.offsetHeight;
onSizeChange(e);
}
});
}
#override
void attach() {
if(_element.getComputedStyle().position == 'static') {
_element.style.position = 'relative';
}
_triggers = new dom.DivElement()
..classes.add('resize-triggers')
..append(new dom.DivElement()..classes.add('expand-trigger')..append(new dom.DivElement()))
..append(new dom.DivElement()..classes.add('contract-trigger'));
_element.append(_triggers);
new async.Future.delayed(new Duration(seconds: 1), () {
//_triggers = _element.children[_element.children.length - 1];
resetTriggers();
dom.Element.scrollEvent.forTarget(_element, useCapture: true).listen(scrollListener);
});
}
#override
void detach() {
_triggers.remove();
}
}
class MyAppModule extends ng.Module {
MyAppModule() {
type(NgObserveSizeDirective);
}
}
main() {
print('main');
ngaf.applicationFactory().addModule(new MyAppModule()).run();
new async.Timer.periodic(new Duration(seconds: 1), (t) {
var elt = (dom.querySelector('#my_sizable') as dom.HtmlElement);
elt.append(new dom.Element.html('<div>${new DateTime.now()}</div>'));
});
}
If you're using an AngularDart component you can inject the shadowdom then select an element inside it to focus on. Didnt find a way of getting the container of the shadowdom.
new Future.delayed(new Duration(milliseconds: 300), () {
var rowElement = _shadowRoot.querySelector('.step-container');
if (rowElement != null ) {
rowElement.scrollIntoView(ScrollAlignment.TOP);
}
});
ShadowDom.host might work, though its currently marked as experimental.

Sass loop: start from second instance of this element

I have a series of divs in a step type layout. I am learning to use Scss at the moment and I thought maybe a mixin could work through the 12 divs and arrange them for me. So far I've got:
#mixin steps(){
$stepBlocks: 12;
#for $i from 1 through $stepBlocks {
.steps-#{$i} {
position: absolute;
top: (($i * 296) + px);
display: block;
}
}
}
This is what my div structure looks like:
I've made a HTML mockup as well:
http://jsfiddle.net/vdecree/CGGyL/
As you can see, the fiddle works fine, however how can I negate the effect of the first one? I need the first element to be top: 0; is there an if statement I can use? If you think you've a better way in which I can do this, I'd appreciate any help.
What you're likely wanting to is start with an offset of 0, rather than 296px.
#mixin steps(){
$stepBlocks: 12;
#for $i from 1 through $stepBlocks {
.steps-#{$i} {
position: absolute;
top: ($i - 1) * 296px;
display: block;
}
}
}

Limit Joomla 1.5 Database Query to Current Year

Below is one page of a Joomla 1.5 extension another developer created quickly that ultimately works like the core Joomla Related Articles but a bit more custom. The code is not very pretty but it works. It shows the title and date for the latest 5 articles that are tagged with the same tag on the current page being viewed. The only problem is it shows articles from 2013 and 2012, since there are only a couple 2013 articles. So ultimately it should show 5 related items only from the current year. So if its 2013 (which it is), and there are only 4 articles from 2013 it should only show those 4.
On the line: for($y=2001; $y <= $intYear; $y++) I tried changing 2001 to 2013 but didn't change anything on the front end. Tried changing to 2014 and didn't change anything either.
The other option I was thinking was on the line: $objDb->setQuery("SELECT sectionid, catid, title if there was a way to say WHERE created='$currentYear' kind of thing.
Once again the code is not pretty and imagine the performance not so great, but looking for a quick fix to this issue, until the whole module can be replaced with a better solution later on. Any help would be most appreaciated!
<?php
// Include the syndicate functions only once
//require_once (dirname(__FILE__).DS.'helper.php');
//
//$list = modRelatedItemsHelper::getList($params);
//
//if (!count($list)) {
// return;
//}
//
//$showDate = $params->get('showDate', 0);
//
//require(JModuleHelper::getLayoutPath('mod_related_items'));
// no direct access
defined('_JEXEC') or die('Restricted access');
// Include the syndicate functions only once
include_once( dirname(__FILE__).DS.'helper.php' );
if( !defined('NL') )
{ define('NL', "\n"); }
$prmRptShowFilter=$params->get('rpt_show_filter');
$prmRptSection=$params->get('rpt_section');
$prmRptCategory=$params->get('rpt_category');
$prmRptDateFormat=$params->get('rpt_date_format');
$arrMonths=array();
$arrMonths[1]='January';
$arrMonths[2]='February';
$arrMonths[3]='March';
$arrMonths[4]='April';
$arrMonths[5]='May';
$arrMonths[6]='June';
$arrMonths[7]='July';
$arrMonths[8]='August';
$arrMonths[9]='September';
$arrMonths[10]='October';
$arrMonths[11]='November';
$arrMonths[12]='December';
$arrYears=array();
$intYear=date(Y);
for($y=2001; $y <= $intYear; $y++)
{ $arrYears[]=$y; }
$varArticleId=JRequest::getVar('id');
$objDb=&JFactory::getDBO();
//--- Database Script ---//
$objDb->setQuery("SELECT sectionid, catid, title FROM #__content WHERE id='$varArticleId' LIMIT 1");
$rows=$objDb->loadObjectList();
$section_id=$rows[0]->sectionid;
$cat_id=$rows[0]->catid;
//--- Database Script ---//
$arrList=modGtSidebarCustomHelper::getList($params);
?>
<style type="text/css">
#idForm1 {
float: right;
}
#idForm1 ul {
margin: 0;
padding: 0;
list-style: none;
clear: both;
}
#idForm1 li {
float: left;
margin: 0 1px 0 0;
padding: 0;
}
#idGtReportDisplayB {
text-align:left;
margin:3px 5px;
}
#idGtReportDisplayB a:hover {
text-decoration: underline;
font-weight: normal;
}
#idGtReportDisplayB span.zoom-link {
display: none;
}
#idGtReportDisplayB dl,
#idGtReportDisplayB dl dt,
#idGtReportDisplayB dl dd {
padding: 0px 5px 0px 5px;
margin: 0;
}
#idGtReportDisplayB dd {
color: #680e0e;
}
#idGtReportDisplayB dl {
width: 284px;
padding-bottom: 15px;
}
#idNoRelatedLatestNews {
display: none;
}
</style>
<div id="idGtReportDisplayB">
<?php
$strDisplay='';
$prmRptDateFormat='n/j/Y';
if( !empty($arrList) )
{
$strDisplay.='<h2>Recent News</h2>'. NL;
$numSize=sizeof($arrList);
for($x=0; ($x < $numSize) && ($x <= 5); $x++)
{
$tmpDtm=strtotime($arrList[$x]->created);
$strDisplay.='<dl>'. NL;
$strDisplay.=' <dt>'. $arrList[$x]->title .'</dt>'. NL;
$strDisplay.=' <dd>'. date($prmRptDateFormat, $tmpDtm) .'</dd>'. NL;
$strDisplay.='</dl>'. NL;
}
echo($strDisplay);
}
else
{
# include( dirname(__FILE__).DS.'..'.DS.'mod_latestnews'.DS.'mod_latestnews.php' );
?>
<style type="text/css">
#idNoRelatedLatestNews {
display: block;
}
</style>
<?
}
?>
</ul>
</div>
Try something like,
$current_year = date('Y');
$objDb->setQuery("SELECT sectionid, catid, title FROM #__content WHERE id='$varArticleId' AND YEAR(created_on) = $current_year ");
It will load only current year data ..
Since there wasn't much of any response from the community on this one, I ultimately created a hack that resolved the issue for now. In which I added the article year as the class name to each dl and then through css just hid the old year I didn't want. While not ideal it works and hopefully will be replacing all the code soon enough anyway.

Resources