Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to realize HTML5 and CSS3 Bubble components

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

How to achieve HTML5 and CSS3 bubble components, many novices are not very clear about this, in order to help you solve this problem, the following editor will explain in detail for you, people with this need can come to learn, I hope you can get something.

Bubble components are very common in practice, whether in web pages or in app, such as:

Our so-called bubble component here refers to the column phenotypic bubble component. Here we discuss its dom implementation, css implementation and js implementation. * give some instructions on some details. I hope it will be useful to you.

Xiaochai recently learned CSS, here to do a special topic, to facilitate their own CSS improvement, the article has a lot of problems and optimization points, please guide

Component classification

In terms of bubble components alone, they still belong to the "pop-up layer" category, which means that they have these characteristics:

① layout is detached from the document stream

② can have a mask mask and can configure whether the click mask is closed or not.

The optional features of ③ include clicking on the browser fallback close component and animation display and hidden animation features.

The differences are as follows:

① is not centered.

② has an arrow logo and can be set up or down

Because ③ has an arrow, and the arrow is relative to an element, generally speaking, our task is relative to a button, so we have a triggerEL.

So from here alone, our component is called BubbleLayer, which should inherit from a generic Layer.

However, in the case of Layer, it will at least have the following common features:

① creation-- create

② display-- show

③ Hidden-hide

④ destroys-destroy

The above features are not unique to Layer components, but to all components, so there should be an abstract component of AbstractView on top of Layer.

At this point, the inheritance relationship comes out, putting aside the extra interfaces, it simply goes like this:

Component dom level implementation

The simplest implementation

In terms of dom implementation alone, a simple ul can accomplish the task.

Price: ¥35 score: 80 level: 5

Of course, there should be relevant css here.

.cui-bubble-layer {background: # f2f2f2; border: # bcbcbc 1px solid; border-radius: 3px}

The effect so far is that the sauce is purple:

Blade Demo body, button, input, select, textarea {font: 40014px/1.5 Arial, "Lucida Grande", Verdana, "Microsoft YaHei", hei;} body, div, dl, dt, dd, ul, ol, li, H2, H2, h4, h5, h6, h7, pre, code, form, fieldset, legend, input, textarea, p, blockquote, th, td, hr, button, article, aside, details, figcaption, figure, figure, footer, footer, header, header: 0 Padding: 0;} body {background: # f5f5f5;} ul, ol {list-style: none;} .cui-bubble-layer {background: # f2f2f2; border: # bcbcbc 1px solid; border-radius: 3px;} Price: ¥35 score: 80: 5

At this time, it is basically realized by adding a pseudo-class and making some style adjustments. The knowledge points of the pseudo-class are used here:

Cui-bubble-layer:before {position: absolute; content: "; width: 10px; height: 10px;-webkit-transform: rotate (45deg); background: # f2f2f2; border-top: # bcbcbc 1px solid; border-left: # bcbcbc 1px solid; top:-6px; left: 50%; margin-left:-5px; z-index: 1;}

Here we set an absolute positioning rectangle, set values for its two borders, and then deform a 45-degree deflection to form a small triangle, and then we all know.

Blade Demo body, button, input, select, textarea {font: 40014px/1.5 Arial, "Lucida Grande", Verdana, "Microsoft YaHei", hei;} body, div, dl, dt, dd, ul, ol, li, H2, H2, h4, h5, h6, h7, pre, code, form, fieldset, legend, input, textarea, p, blockquote, th, td, hr, button, article, aside, details, figcaption, figure, figure, footer, footer, header, header: 0 Padding: 0;} body {background: # f5f5f5;} ul, ol {list-style: none;} .cui-bubble-layer {background: # f2f2f2; border: # bcbcbc 1px solid; border-radius: 3px;} .cui-bubble-layer > li {padding: 5px 10px;} .cui-bubble-layer:before {position: absolute; content: "; width: 10px; height: 10px;-webkit-transform: rotate (45deg); background: # f2f2f2 Border-top: # bcbcbc 1px solid; border-left: # bcbcbc 1px solid; top:-6px; left: 50%; margin-left:-5px; z-index: 1; Price: ¥35 score: 80 level: 5

Http://sandbox.runjs.cn/show/9ywitfn8

Deficiency and expansion

There is no problem with the above as a basic implementation, but the actual application scenario will have the following shortcomings:

The basic ul level of ① requires a wrapper, which has a up or down class, and then decides which arrow is up or down

② we can not use pseudo-classes here, the reason is that our small triangle tag is not necessarily in the middle, it has a certain sliding characteristics, that is to say, this small triangle needs to be controlled by js to its left and right position, it needs to be a tag

Based on the above, our structure seems to look like this:

Price: ¥35 score: 80 level: 5

On the ① root element, we can set the current style of up or down

The ② I tag chooses whether to go up or down according to the up or down of the root element, and the tag can be manipulated by js

At this point, it seems that the whole component is more complete, but the real situation is not the case, how to say, the above structure is too limited

The component needs a container, and the container label should be on top of ul, so that the dom structure loaded inside the container can be not ul but some other structure.

Secondly, on mobile phones, there are no more than five visual projects on 4S phones, often four, so we should set scrollable properties such as overflow on its containers.

Component regression final structure

From the above, based on the fact that it is inherited from Layer, we can form the following structure:

Price: ¥35 score: 80 level: 5

This can also be the basic structure of our entire pop-up class, and we can do a lot of extensions on it, but here we don't talk too much about bubble components.

As for the bubble assembly, its structure is:

Price: ¥35 score: 80 level: 5

Implementation of js level

Here is still the set of inheritance mechanism in blade. If there are students who do not understand and are interested, please step forward: [blade's UI Design] understand the front-end MVC and layering ideas.

About templat

Since the theme of our part is refactoring related, our focus here is CSS, and we first generate our template:

Here are several key customization points:

① wrapperClass is used to add a customized class by the business team to change the class of the root element, with the benefit of making it easier for the business team to customize the style of the bubble components

② gives a customizable className for the project list Ul. GM only facilitates business teams to make style changes.

③ returns the name field of the incoming project by default, but the user can pass in a callback of itemFn, which is customized.

The above template can basically meet the conditions. If not, the whole template can be passed in as a parameter.

About js implementation

Due to the implementation of inheritance, most of our work has been done, and we only need to write code in a few key places

Define (['UILayer', getAppUITemplatePath (' ui.bubble.layer')], function (UILayer, template) {return _ .inherit (UILayer, {propertys: function ($super) {$super (); / / html template this.template = template; this.needMask = false This.datamodel = {data: [], wrapperClass: 'cui-bubble-layer', upClass:' cui-pop--triangle-up', downClass: 'cui-pop--triangle-down', curClass:' active', itemStyleClass:', needBorder: true, index:-1 Dir: 'up' / / Arrow Direction default} This.events = {'click .cui-pop-list > li':' clickAction'}; this.onClick = function (data, index, el, e) {console.log (arguments); / / this.setIndex (index);}; this.width = null; / / triangular icon offset this.triangleLeft = null; this.triangleRight = null This.triggerEl = null;}, initialize: function ($super, opts) {$super (opts);}, createRoot: function (html) {this.$el = $(html). Hide (). Attr ('id', this.id);}, clickAction: function (e) {var el = $(e.currentTarget); var I = el.attr (' data-index') Var data = this.datamodel.data [I]; this.onClick.call (this, data, I, el, e);}, initElement: function () {this.el = this.$el; this.triangleEl = this.$ ('.cui-pop-triangle'); this.windowWidth = $(window). Width ();}, setIndex: function (I) {var curClass = this.datamodel.curClass I = parseInt (I) if (I)

< 0 || i >

This.datamodel.data.length | | I = = this.datamodel.index) return; this.datamodel.index = I; / / there is no change in the entire dom caused by the datamodel change, not cost-effective this.$ ('.cui-pop-list li') .removeClass (curClass); this.$ (' li [data-index= "'+ I +']') .addClass (curClass) }, / / position reposition: function () {if (! this.triggerEl) return; var offset = this.triggerEl.offset (); var step = 6, w = offset.width-step; var top = 0, left = 0, right; if (this.datamodel.dir = = 'up') {top = (offset.top + offset.height + 8) +' px' } else {top = (offset.top-this.el.offset () .height-8) + 'px';} left = (offset.left + 2) +' px' If (offset.left + (parseInt (this.width) | | w) > this.windowWidth) {this.el.css ({width: this.width | | w, top: top, right: '2px'}) } else {this.el.css ({width: this.width | | w, top: top, left: left});} if (this.triangleLeft) {this.triangleEl.css ({'left': this.triangleLeft,' right': 'auto'}) } if (this.triangleRight) {this.triangleEl.css ({'right': this.triangleRight,' left': 'auto'});}}, addEvent: function ($super) {$super (); this.on (' onCreate', function () {this.$el.removeClass ('cui-layer'); this.$el.css ({position:' absolute'})) }); this.on ('onShow', function () {this.setzIndexTop (this.el);})

What you call here, you can do a simple implementation:

'click. Demo1': function (e) {if (! this.demo1) {var data = [{name: 'ordinary member'}, {name: 'vip'}, {name:' advanced vip'}, {name: 'diamond vip'}] This.list = new UIBubbleLayer ({datamodel: {data: data}, triggerEl: $(e.currentTarget), width: '150pxrabbit, triangleLeft:' 20px'});} this.list.show ();}

With a little modification, you can form another appearance:

It's just that we have to consider the occurrence of this scenario, and we still need to deal with it when there are too many projects:

There are many ways to deal with this. * are passed directly into maxHeight, if the height is exceeded, a scroll bar appears. The second is to dynamically calculate within the component to see the relationship between the component and the visual area.

Let's use the visual area calculation here, so make some changes to the original component and add an interface:

This.checkHeightOverflow ()

This simple interface can actually be divided into several paragraphs.

* the interface is to detect the visual area, which can be overridden by the user.

IsSizeOverflow

The second interface is the processing logic if the visual area exceeds, that is, if the * interfaces return true.

HandleSizeOverflow

Considering that the excess is not necessarily the height, so here height is changed to Size

Of course, there will be resource destruction, so a new hide interface will be added.

IsSizeOverflow: function () {if (! this.el) return false; if (this.el.height () > this.windowHeight * 0.8) return true; return false;}, handleSizeOverflow: function () {if (! this.isSizeOverflow ()) return; this.listWrapper.css ({height: (parseInt (this.windowHeight * 0.8) + 'px'), overflow:' hidden', position: 'relative'}) This.listEl.css ({position: 'absolute', width:' 100%'}); / / need to reset the location this.reposition () before calling; this.scroll = new UIScroll ({wrapper: this.listWrapper, scroller: this.listEl});}, checkSizeOverflow: function () {this.handleSizeOverflow ();}, addEvent: function ($super) {$super () This.on ('onCreate', function () {this.$el.removeClass (' cui-layer'); this.$el.css ({position: 'absolute'});}); this.on (' onShow', function () {/ / check whether the visual area is beyond; this.checkSizeOverflow (); this.setzIndexTop (this.el);}) This.on ('onHide', function () {if (this.scroll) this.scroll.destroy ();});}

At this point, our function is almost over. * implement a customized function to turn our bubble component black:

Is it helpful for you to read the above content? If you want to know more about the relevant knowledge or read more related articles, please follow the industry information channel, thank you for your support.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report